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

CinUIS 7年前發布 | 24K 次閱讀 Docker

這篇文章以極簡的模式快速搭建一套使用與開發的Docker環境,特別面向了開發中常用的Mac和Windows環境。雖然本文模糊了大量的實現細節,但可作為在開發平臺搭建Docker環境有力范本。

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

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

Docker 4 開發者

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

  • 拉取代碼基線
  • 安裝外部工具,如數據庫、緩存和一些額外的工具和服務
  • 給外部工具打補丁和升級
  • 配置數據庫和服務以使他們可以通信
  • 開始祈禱(可能需要好幾次)
  • 調試問題(至少要30幾次)

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

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

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

Docker Toolbox 對 Docker for X

Docker Toolbox是可用于處理多個Docker資源的原始工具集合,并且會根據您選擇的操作系統而有所不同。但在那之后,他們發布了新的Windows和Mac原生應用程序。因此,除了Linux、OS X和Windows Docker Toolbox變體之外,您還將看到“Doc??ker 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數據庫等。

步驟 1:安裝

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

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

步驟 2:源碼/環境

下一步是獲取要容器化的開發應用程序的源代碼。

現在,您可以從GitHub抓取這個 項目 ,這個項目保存了本教程的一些步驟。

步驟 3:創建Docker鏡像文件

請記住,主要目標是在隔離和模塊化的環境中運行我們的應用程序。為了讓Docker創建這個環境,我們必須告訴它如何創建它。我們使用包含一組指令的 Docker鏡像文件 。

  1. 使用你的IDE,增加一個文件到工程根目錄并命名為“Dockerfile”
  2. 拷貝下面的文件內容到這個文件

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

Dockerfile

FROM mhart/alpine-node:6.9.2

WORKDIR /var/app

COPY . /var/app

RUN npm install --production

EXPOSE 3000

ENV NODE_ENV=production

CMD ["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。

步驟 4:構建一個鏡像

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

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

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

步驟 4a:構建生產鏡像

  1. 從一個終端中導航到項目根目錄
  2. 運行命令(包含動圖最后的命令)
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”

我們做了什么?

  1. 我們運行build命令從我們在步驟3中創建的Docker鏡像文件創建一個文件
  2. 使用標簽開關-t,我們給鏡像一個名稱,我們可以使用它來引用它,而不必引用Docker生成的ID(例如50e8dde7e180)
  3. 我們指定了使用“.”指定的當前本地目錄的鏡像路徑

步驟 4b:驗證鏡像

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

docker images

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

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

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

docker history express-prod-i

步驟 5:運行鏡像實例

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

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

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

  1. 運行命令:
docker run -d --name express-prod-app -p 7000:3000 express-prod-i
  1. 登錄瀏覽器訪問 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. 我們可以使用這個命令觀察運行時容器
docker ps

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

步驟 6:停止并啟動容器

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

docker stop express-prod-app

然后啟動它

docker start express-prod-app

步驟 7:刪除鏡像和容器

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

步驟 7a:刪除容器

刪除一個容器,我們可以使用“rm”命令:

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命令。

我們做了什么?

  1. 我們想container提交了刪除命令“rm”
  2. 但是我們提交的是一個容器ID的列表,而不是提供容器標簽或是container ID
  3. 提供所有(-a)參數并組合靜默(-q)將會返回數字類型的容器ID

刪除所有鏡像

刪除所有的鏡像我們可以類似于上面的做法,使用刪除鏡像命令“rmi”

docker rmi $(docker images -q)

我們做了什么?

  1. 這里我們使用了刪除鏡像命令但是入參是一個docker鏡像ID列表……
  2. ……使用列出docker鏡像的命令
  3. 并且設置靜默(-q)參數,這樣返回了數字型的Docker ID

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

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

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

總結

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

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

 

 

來自:http://dockone.io/article/2239

 

 本文由用戶 CinUIS 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!