Docker for 開發:容器化你的應用

2021-02-21 分布式實驗室

作為開發者,我們總是尋找一個捷徑或更容易的方法來快速起步,對吧?如果你是團隊領導,付出最少的代價讓團隊站在同一個起點是很重要的。 Docker可以提供幫助。

在軟體開發領域,一直越來越強調模塊化,從單一責任的一般原則到更具體的實現,例如將JavaScript功能模塊化為無狀態組件。在這裡,我將告訴你我們如何使用Docker來模塊化我們的開發環境,以獲得許多類似的好處,包括幫助我們快速起步。

如你所知,為了加快項目進度,你有一個待辦事項清單:

想像一下,如果在將應用程式的代碼基線拉出存儲庫之後,您只需運行幾個命令行(可能只有一個),可以使整個應用程式的環境準備就緒。聽起來很酷,對吧?

這正是我們要完成的。不同於使用一個百科全書式的方法來使用Docker的所有功能和命令,我將介紹容器化開發人員的環境的主要的Docker功能。

這篇文章是關於利用Docker的容器化能力的一系列文章中的第一篇,它很容易構建一個可以在任何時間共享和運行的應用程式開發環境。

Docker Toolbox 對 Docker for X

Docker Toolbox是可用於處理多個Docker資源的原始工具集合,並且會根據您選擇的作業系統而有所不同。但在那之後,他們發布了新的Windows和Mac原生應用程式。因此,除了Linux、OS X和Windows Docker Toolbox變體之外,您還將看到「Docker for Mac」和「Docker for Windows」。

要理解和決定應該使用哪種工具,我想概述使用新的原生應用程式的前提。原來的Docker Toolbox將會設置一些工具以及使用VirtualBox。它還將提供在Linux Hypervisor上運行的虛擬機,用於Windows或Mac。

VirtualBox、Hyper-V和Hyperkit,我的上帝啊!

原生應用程式,例如在Docker for Mac中,實際安裝的是OS X原生應用程式。它也不再使用VirtualBox,而是使用OS X的hypervisor hyperkit。此外,共享接口和網絡的管理更簡單。還有一些用戶體驗更新以便於Docker更好的工作。在Docker for Windows原生應用程式中也會包含這些相同的更改,但是會使用Hyper-V作為hypervisor,以及其他類似的網絡和工具更新的主機。

最後,原生應用的體驗應該是一個更積極,更有效率的,而且更少的出錯。但是,您會發現絕大多數與Toolbox相關的外部文檔 - 因此了解Toolbox將是你的優勢。

這個初始教程將簡單地使用一個開箱即用的express.js應用程式。當我們開始編輯原始碼並在容器之間進行通信時,我將介紹一個運行Webpack的開發伺服器的進階的通用React.js應用程式,其中包含熱模塊重新加載,MongoDB資料庫等。

為了努力獲得使用Docker並將開發人員環境與各種作業系統版本一起集中化的好處,我將讓您選擇需要下載的Docker版本(Toolbox或原生)和作業系統:

Toolbox:https://www.docker.com/products/docker-toolbox (OS X and Windows)

Docker for Windows:https://www.docker.com/products/docker#/windows

Docker for Mac:https://www.docker.com/products/docker#/mac

TOOLBOX用戶:Docker Toolbox配有「Docker快速入門終端」,並在運行時與Docker環境相關聯。但是,通常在您選擇的IDE中運行終端或獨立運行終端。為了讓Docker與另一個終端/提示進行交互,您需要通過運行「docker-machine env」來初始化Docker env。文本顯示的末尾是一個命令,您需要從該同一終端中複製該命令以初始化Docker環境。

下一步是獲取要容器化的開發應用程式的原始碼。

現在,您可以從GitHub抓取這個項目(https://github.com/hyndsite/docker-4-devs.git),這個項目保存了本教程的一些步驟。

請記住,主要目標是在隔離和模塊化的環境中運行我們的應用程式。為了讓Docker創建這個環境,我們必須告訴它如何創建它。我們使用包含一組指令的Docker鏡像文件(https://docs.docker.com/engine/reference/builder/)。

使用你的IDE,增加一個文件到工程根目錄並命名為「Dockerfile」

拷貝下面的文件內容到這個文件

重要信息:該Docker鏡像文件將允許我們創建一個鏡像,該鏡像將代表我們一直在討論的容器化環境,並最終創建稱為容器的該鏡像的運行實例。但是,我們向前跳了一步,這些內容應該在第5步中。

Dockerfile

FROM mhart/alpine-node:6.9.2WORKDIR /var/appCOPY . /var/appRUN npm install --productionEXPOSE 3000ENV NODE_ENV=productionCMD ["node", "bin/www」]

Dockerfile是Docker在鏡像文件中尋找的默認名稱,但它可以是任何名稱,我們將在稍後的步驟中看到。這些指令告訴Docker我們要創建一個鏡像:

從一個基礎的mhart/alpine-node鏡像的6.9.2標籤開始創建

設置應用程式初始運行的工作目錄WORKDIR

拷貝當前本地目錄「."中的內容到工作目錄

然後從工作目錄運行RUN命令npm install —production」

我們將對外暴露 EXPOSE3000埠從容器中,當它從鏡像中被創建的時候

另外我們想要對容器設置本地環境變量ENV NODE_ENV的值為「production」

最後,我們啟動express.js服務,它駐留在bin目錄中的「www」文件中,執行命令「node bin/www」

提示:Docker總是需要一個基本的鏡像,鏡像保持儘可能小空間佔用是關鍵。alpine-node鏡像是非常小的(49.65mb),包括Node.js和NPM。

現在我們有一個Docker鏡像文件,它指定了有關如何創建鏡像的詳細信息,讓我們停下來談談鏡像是什麼:

鏡像是只讀分層文件系統。它構成了我們不斷追求的環境的基本文件系統。我們在上一步中創建的鏡像文件將指示Docker如何去創建鏡像的每層。

但如果它是一個只讀的文件系統,我們如何去寫它,(例如,執行代碼的變化對我們的應用程式的代碼在開發過程中)?好問題,我會在即將到來的步驟中回答。

步驟 4a:構建生產鏡像

docker build -t express-prod-i .

提示:對於Docker Toolbox,從Docker Quickstart Terminal開始運行Docker命令會導致錯誤(根據作業系統而異)。為了從任何隨機終端/提示符運行命令,您需要將終端/提示連結到docker環境。運行docker-machine env,並運行它提示的命令,例如「@FOR / f」tokens = *「%i IN('docker-machine env')DO @%i」

我們做了什麼?

我們運行build命令從我們在步驟3中創建的Docker鏡像文件創建一個文件

使用標籤開關-t,我們給鏡像一個名稱,我們可以使用它來引用它,而不必引用Docker生成的ID(例如50e8dde7e180)

我們指定了使用「.」指定的當前本地目錄的鏡像路徑

步驟 4b:驗證鏡像

如果所有都按計劃進行,我們應該看到(如.gif中的)一個「successful build ...」消息。我們現在可以運行一個命令來記住你的鏡像:

在這種情況下,我們的組合鏡像大小為61.26 MB,這是基本的alpine-node鏡像和我們的express應用層的組合。

步驟 4c:觀察鏡像文件層

如果我們想要看到為我們的鏡像創建的文件層,我們可以運行命令:

docker history express-prod-i

既然我們已經創建了一個鏡像,我們已經準備好創建一個隔離的,模塊化的應用環境。正如我已經提到了很多次那樣,那個環境是一個Docker容器。Docker容器實際上是鏡像的運行實例。

在概念上,一個鏡像和容器非常類似於我們如何想到一個JavaScript Prototype或一個OOP類。所以,我們來運行一個我們創建的鏡像的實例。

步驟 5a:生成並運行一個鏡像實例

docker run -d --name express-prod-app -p 7000:3000 express-prod-i

2. 登錄瀏覽器訪問http://localhost:7000。

我們做了什麼?

我們創建並運行了一個express-prod-i鏡像的實例而作為一個容器:

使用RUN命令

指定分離模式-d標誌(所以我們不綁定當前終端/提示符)

並使用-name標誌給我們的容器設置名字「express-prod-app」

將主機7000上的本地埠映射到使用-p標誌顯示的3000的內部容器埠

最後,指定我們要生成並運行我們的實例的「express-prod-i」鏡像

注意:我使用不同的本地埠7000來向您展示您可以將主機上的任何未使用的埠映射到容器中暴露的內部埠。

提示:沒有-d,我們將以貼合模式啟動運行容器。這意味著它將從容器中直接輸出到我們運行命令的終端/提示符。通過在分離模式下啟動容器,我們可以繼續從終端/提示符運行容器工作。

頓悟#1

你明白了嗎?我們不必在本地安裝Node.js或NPM。我們沒有必要運行npm安裝本地使用的應用程式,我們沒有從主機運行應用程式。所有這些都在主機內部發生,這是一個簡單的express.js演示網站。

步驟 5b:驗證運行容器

1. 我們可以使用這個命令觀察運行時容器

這將顯示我們運行容器。我們還可以指定-a標誌來查看所有容器。當事情出錯時,可能會有用,我們想看看一個號稱已經運行容器是否意外退出:

停止一個運行時容器是非常簡單的……或許你已經猜到了:

docker stop express-prod-app

docker start express-prod-app

當我們瀏覽這些教程時,可以刪除鏡像或容器並重新開始。以下是步驟。另外,在「獎勵」部分,還有一些有用的捷徑:

步驟 7a:刪除容器

docker rm express-prod-app

docker run -d --name express-prod-app -p 7000:3000 express-prod-i

步驟 7b:刪除鏡像

刪除一個鏡像,我們可以使用「rmi」命令:

docker rmi express-prod-i

docker build -t express-prod-i .

提示:刪除鏡像和容器命令可以使用鏡像或容器ID,甚至可以使用ID的前幾個字符。所以你可以任意選擇。 (您還會看到我們在獎勵部分中這樣做。)

獎勵

補充一些刪除鏡像和容器的其他手段,你可以使用一些我已經在用的有效的快捷方法。

刪除所有容器

要刪除所有容器,運行下面的「rm」命令,這條命令內部會返回所有的容器:

docker rm $(docker ps -a -q)

Windows用戶:你需要是一個bash環境去運行這些命令。主要是因為只有GNU才能使用$()變量引用。你可以安裝諸如「Bash on Ubuntu on Windows」甚至於 GIT bash。只要記得你需要運行docker-machine env來連結你的終端,並且運行顯示在最後的eval命令。

我們做了什麼?

我們想container提交了刪除命令「rm」

但是我們提交的是一個容器ID的列表,而不是提供容器標籤或是container ID

提供所有(-a)參數並組合靜默(-q)將會返回數字類型的容器ID

刪除所有鏡像

刪除所有的鏡像我們可以類似於上面的做法,使用刪除鏡像命令「rmi」

docker rmi $(docker images -q)

我們做了什麼?

這裡我們使用了刪除鏡像命令但是入參是一個docker鏡像ID列表……

……使用列出docker鏡像的命令

並且設置靜默(-q)參數,這樣返回了數字型的Docker ID

這可以應用到生產嗎?還是只是應用開發環境?

很明顯能主要到我們剛剛創建的鏡像通知Express.js和Node.js在生產環境中運行。那這是什麼鬼?

記住我們是要為任何鏡像製作基本鏡像,並且誰會在開發環境中為每次修改而「重建」鏡像呢?所以我們需要使用生產鏡像來作為基本鏡像構建我們的開發環境並且隔離開發修改到分層鏡像中的開發層中。

所以,我已經屏蔽了一大堆關於Docker的知識。創建鏡像文件,構建鏡像並生成該鏡像的正在運行的容器。但是我們還有很多事情要去做。

因此,在本系列的下一篇文章中,我將針對我們的開發版本或應用程式創建一個鏡像,但是基於我們的生產鏡像。我們還將介紹如何利用容器中的腳本來幫助設置本地環境來更改原始碼。

原文連結:https://dzone.com/articles/docker-for-devs-containerizing-your-application本次培訓以容器存儲和網絡為主題,包括:Docker Plugin、Docker storage driver、Docker Volume Pulgin、Kubernetes Storage機制、容器網絡實現原理和模型、Docker網絡實現、網絡插件、Calico、Contiv Netplugin、開源企業級鏡像倉庫Harbor原理及實現等。點擊識別下方二維碼加微信好友了解具體培訓內容

相關焦點

  • 使用 Docker 容器化 Django Web 應用
    我從 GitHub 中挑選了一個隨機項目,該項目有一個公開的 issue[1],稱 Docker 化(後文使用 Dockerize)可以在這裡作為示例進行貢獻和使用。為什麼要在現實世界中 Dockerize 現有的 Django Web 應用程式呢?有很多原因,但如果你沒有,那麼就當玩玩,哈哈。我決定使用 Docker,因為我的一個應用程式很難部署。
  • Spring Boot 應用容器化之 Docker、Gradle
    本文演示了如何用 Docker、Gradle 來構建、運行、發布來一個 Spring Boot 應用。Docker 簡介Docker 是一個 Linux 容器管理工具包,具備「社交」方面,允許用戶發布容器的 image (鏡像),並使用別人發布的 image。
  • 一分鐘玩轉Docker容器化部署
    所以微服務時代的運維方式一定是Devops模式,通過構建自動化運維發布平臺來打通產品、開發、測試及運維流程,從而整體上提升研發效能,而這也是目前大部分公司正在做的事情。隨著以Docker為代表的容器化技術的普及,目前Devops實踐大多會採用容器(如Docker、K8s)這樣的方式來作為微服務應用部署運行的載體,並通過容器的彈性擴展來實現快速擴容和縮容,從而更快地響應業務、更好地利用資源。
  • docker化你的java應用(上)
    現在在很多企業(騰訊/京東/阿里/小紅書等等)都大規模使用docker。作為開發工程師,咱們或多或少需要接觸docker,因為咱們的程序運行在docker容器當中,了解docker,有益無害。下面我們就進入docker的世界吧~
  • Docker 容器化部署技術
    Docker容器技術概述Docker重新定義了程序開發測試、交付和部署的過程。隨著雲計算技術的深入發展,使用虛擬伺服器代替傳統的物理伺服器越來越常見。伺服器虛擬化的思想是在性能強勁的伺服器上運行多個虛擬機,每個虛擬機運行獨立的作業系統與相應的軟體。通過虛擬機管理器可以隱藏真實機器的物理配置。
  • 容器化 | .NET 4.x on Docker 體驗(1)
    我們都知道.NET Core應用可以跑在Docker上,那.NET Framework 4.x應用呢?
  • Docker 工作原理及容器化簡易指南
    它使軟體開發者無需擔心配置和依賴性,在任何地方打包,發送和運行他們的應用程式。而在與 Kubernetes 相結合後,它使應用集群部署和管理變得更方便。這使得 Docker 深受軟體開發者的喜愛,越來越多的開發者開始使用 Docker。它是構建、測試、部署和發布容器化應用的平臺。稱其為平臺是因為 Docker 其實是一套用於管理與容器相關的所有事物的工具。
  • Docker 容器化部署運維 OpenStack 和 Ceph
    Kolla 是具有廣闊應用前景和市場的一個自動化部署工具。相比於其他部署工具,Kolla 完全革新地使用了 Docker 容器技術,將每一個 OpenStack 服務運行在不同的 Docker 容器中。以前,我們要想在 OpenStack 版本發布後或者在版本開發過程中,立即安裝體驗等只能使用 DevStack 源碼方式安裝。但現在更多了一種新的選擇——即使用 Kolla。
  • 使用Visual Studio調試容器化.Net Core應用
    由於公司一直致力於為客戶實現軟體研發的DevOps,因此老闆說我這個應用的開發要DevOps。好吧!基於這些要求,應用的技術選型與開發、部署工具確定了:開發語言C#(我就會這個),.Net Core框架,使用Visual Studio(夠強大), 採用Docker的容器化部署。
  • 從零開始Docker化你的Node.js應用
    開發的Web應用源碼包(zip),要求你在新機器上使用Docker的方式把應用部署起來。此時的你,並沒有搞清楚什麼是容器/鏡像,也沒記住幾個相關的Linux命令,該怎麼辦?本文將幫助你擺脫困境。所有環境配置已準備完畢,可以根據Node.js應用編寫Dockerfile了。假設Node.js應用的啟動命令為npm start,監聽埠為${app_port}。
  • Docker容器入門指北
    Docker 是一種基於 Linux 的容器化技術,類似於輕量的虛擬機。它採用 C/S 架構,使用Go語言開發。Docker 分為 2 個版本:社區版(Community Edition, CE)和企業版(Enterprise Edition, EE),社區版免費,企業版是收費的。
  • 怎樣在Python中操作Docker容器?
    Docker容器在分離不同應用方面做的非常出色,但是如果你想讓這些應用之間實現交互呢?例如,你正在開發一款Python應用,而這個應用需要與一個用其他語言開發的應用進行交互。Python官方百科中提供了一些讓Python與其他流行的程式語言進行底層交互的技巧。但是如果你碰到一個很奇怪的情況,或者某個複雜的遺留軟體,交互就變得非常困難,甚至是不可能完成。
  • PHP項目Docker化指南
    文章亮點將PHP應用及其依賴的服務容器化步驟如何將應用容器鏡像的構建自動化應用容器如何快速部署到測試環境和生產環境中快速上手PHP官方在 hub.docker.com 上維護了官方的PHP Docker鏡像,包含了從PHP 5.5到7.0的多種不同版本的鏡像。
  • ​Docker容器化Jenkins+碼雲+Docker+華為鏡像容器實現CI/CD
    轉載Docker容器化Jenkins+碼雲+Docker+華為鏡像容器實現CI/CD本篇主要為個人在jenkins不知道是不是自己下的鏡像版本的問題,jenkins容器起起來以後沒有jdk運行環境。使用docker 掛載數據卷的方式蹭宿主機的jdk來用,見下面的一長串啟動命令配置。個人不是很熟悉 docker-compose,所以本篇基本都是docker 原生命令。
  • 用一首歌時間將 React 應用 Docker 化,成為前端 Star!
    來源 | 前端勸退師(ID:quantuishi)以前一直有疑問困擾著我:人人都在吹的Docker容器化,與前端有何關係?然而在近兩年的編程生涯,在每一次產品迭代中,漸漸體會到了容器化其魅力所在。應用部署從刀耕火種,到DevOps崛起,原來不止前端在迅捷發展。接下來,我將用一首歌的時間,帶大家真實的體驗一番Docker容器化。
  • 輕鬆容器化golang應用程式
    有一些方法容器化 Golang 工程,尤其是當您使用 Docker 運行 Go 項目的可執行文件時。我們可以從我們的項目中創建我們的鏡像,簡單地在您的本地計算機上運行它,甚至可以通過從 harbour 中提取您的鏡像運行它。
  • 玩轉docker容器編排調度 docker-compose、docker-swarm
    Docker Compose可以運行在生產環境、測試環境和開發環境中。使用Docker Compose需要有這三個基礎的步驟:編寫docker-compose.yml 定義你的服務,目的是為了讓Dockerfile定義的容器可以一起運行。
  • 一首歌時間將React / Vue 應用Docker 化
    前言 以前一直有疑問困擾著我:人人都在吹的Docker容器化,與前端有何關係?然而在近兩年的編程生涯,在每一次產品迭代中,漸漸體會到了容器化其魅力所在。應用部署從刀耕火種,到DevOps崛起,原來不止前端在迅捷發展。
  • Docker最全教程之MySQL容器化 (二十五)
    前言                MySQL是目前最流行的開源的關係型資料庫,MySQL的容器化之前有朋友投稿並且寫過此塊
  • 什麼是 Docker 和 Docker 容器?深入了解 Docker!
    什麼是 Docker 和 Docker 容器?Docker 是一個容器化平臺,它以 docker 容器的形式將您的應用程式及其所有依賴項打包在一起,以確保您的應用程式在任何環境中都能無縫運行。Docker 容器是一個標準化單元,可以動態創建以部署特定應用程式或環境,從作業系統的角度來看,它可以是 Ubuntu 容器、CentOs 容器等,以完全滿足要求,此外,它可以是面向應用程式的容器,如 CakePHP 容器或 Tomcat-Ubuntu 容器等。