本文是《Docker必知必會系列》第二篇,原文發佈於個人博客:悟塵紀。
構建並運行鏡像
要構建一個容器,需要做很多的工作,設置很多的配置,如果我們可以把每一層修改、安裝、構建、操作的命令都寫入一個腳本,用這個腳本來構建、定製鏡像,那麼經常被提及的無法重複、鏡像構建透明性、體積等問題就都會解決。 這個腳本就是 Dockerfile。
準備 Dockerfile 文件
下載示例項目,請在終端中運行以下命令:
curl -LO https://github.com/dockersamples/node-bulletin-board/archive/master.zip
unzip master.zip
cd node-bulletin-board-master/bulletin-board-app
該
node-bulletin-board
項目是一個簡單的公告板應用程序,使用 Node.js 編寫。在此示例中,假設您編寫了此應用程序,現在正嘗試對其進行容器化。
Dockerfile
描述如何爲容器組裝專用文件系統,並且還可以包含一些元數據,這些元數據描述瞭如何基於該鏡像運行容器。公告板應用程序 Dockerfile
內容如下:
# Use the official image as a parent image.
FROM node:current-slim
# Set the working directory.
WORKDIR /usr/src/app
# Copy the file from your host to your current location.
COPY package.json .
# Run the command inside your image filesystem.
RUN npm install
# Inform Docker that the container is listening on the specified port at runtime.
EXPOSE 8080
# Run the specified command within the container.
CMD [ "npm", "start" ]
# Copy the rest of your app's source code from your host to your image filesystem.
COPY . .
編寫 Dockerfile 是容器化應用程序的第一步,這些 Dockerfile 命令是構建鏡像的步驟。 這個步驟如下:
- 使用
FORM
指定基於已經存在的node:current-slim
基礎鏡像構建。這是一個由 nodejs 官方構建的鏡像。 - 使用
WORKDIR
指定所有後續操作均從鏡像文件系統中的/usr/src/app
目錄中執行(而不是主機的文件系統中)。 - 將文件
package.json
從主機複製到鏡像中的當前位置(.)(複製到 ``/usr/src/app/package.json`) - 在鏡像文件系統中運行命令
npm install
(讀取package.json
以確定並安裝應用程序依賴) - 將應用的其餘源代碼從主機複製到鏡像文件系統。
這些步驟與在主機上設置和安裝應用程序所採取的步驟幾乎相同。但是,將它們保存爲
Dockerfile
可以使您在可移植的隔離 Docker 鏡像中執行相同的操作。
上面的步驟構建了我們鏡像的文件系統,但是 Dockerfile 中還有其他幾行。
-
CMD
指令在鏡像中指定一些元數據,該元數據描述瞭如何基於該鏡像運行容器。在本示例中該圖像的容器化過程是npm start
。 -
EXPOSE 8080
通知 Docker 該容器在運行時監聽 8080 端口。
上面是組織一個簡單的 Dockerfile 的方法。始終以 FROM
命令開頭,然後按照步驟構建您的私有文件系統,並以任何元數據規範作爲結束。 Dockerfile 指令比上面看到的要多。有關完整列表,請參閱 Dockerfile 參考。
構建並測試鏡像
現在您已經有了一些源代碼和一個 Dockerfile,現在該構建您的第一個鏡像,並確保從其啓動的容器能夠按預期工作。讓我們構建您的公告板圖像:
docker build --tag bulletinboard:1.0 .
您將看到 Docker 逐步完成 Dockerfile 中的每條指令,並逐步構建鏡像:
Sending build context to Docker daemon 45.57kB
Step 1/7 : FROM node:current-slim
current-slim: Pulling from library/node
48839397421a: Pull complete
cbb6511d79bf: Pull complete
04ec6202052a: Pull complete
29c5eab4674c: Pull complete
8df5bb5f8d2e: Pull complete
Digest: sha256:c92fad90875a6ce7251c72701f9c88e1e3f3efc2eb1d7d1ffb2184204e4f7d98
Status: Downloaded newer image for node:current-slim
---> 6d9a17519d40
Step 2/7 : WORKDIR /usr/src/app
---> Running in 9dfd5c099558
Removing intermediate container 9dfd5c099558
---> 6062c6d2e488
Step 3/7 : COPY package.json .
---> 2ddc37525da9
Step 4/7 : RUN npm install
---> Running in 6ce3fed8ecd7
> [email protected] postinstall /usr/src/app/node_modules/ejs
> node ./postinstall.js
Thank you for installing EJS: built with the Jake JavaScript build tool (https://jakejs.com/)
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN [email protected] No repository field.
npm WARN The package morgan is included as both a dev and production dependency.
added 91 packages from 168 contributors and audited 221 packages in 16.854s
found 0 vulnerabilities
Removing intermediate container 6ce3fed8ecd7
---> 38a27fea6567
Step 5/7 : EXPOSE 8080
---> Running in c7528a178327
Removing intermediate container c7528a178327
---> 97f454f32f95
Step 6/7 : CMD [ "npm", "start" ]
---> Running in 72a6340e3d58
Removing intermediate container 72a6340e3d58
---> 0a90efca7ea9
Step 7/7 : COPY . .
---> 84c4f69e2893
Successfully built 84c4f69e2893
Successfully tagged bulletinboard:1.0
將鏡像作爲容器運行
-
根據您的新鏡像啓動一個容器:
docker run --publish 8000:8080 --detach --name board bulletinboard:1.0
這裏有幾個常見的標誌:
--publish
要求 Docker 將主機端口 8000 上傳入的流量轉發到容器的端口 8080。容器具有自己的專用端口集,因此,如果要從網絡訪問某個端口,則必須以這種方式將流量轉發到該端口。否則,作爲默認的安全狀態,防火牆規則將阻止所有網絡流量到達您的容器。--detach
要求 Docker 在後臺運行此容器。--name
指定一個名稱,您可以使用該名稱在後續命令中引用您的容器,在這種情況下爲board
。
還要注意,您沒有指定容器要運行的程序。您不必這樣做,因爲在構建 Dockerfile 時使用了
CMD
指令。Docker 知道在容器啓動時會自動運行npm start
程序。 -
在的瀏覽器中訪問您的應用程序
localhost:8000
,您應該看到公告板應用程序已啓動並正在運行。 -
對公告板容器正常工作感到滿意後,可以將其刪除:
docker rm --force board
該
--force
選項將刪除正在運行的容器。如果停止容器運行,docker stop board
則無需使用--force
。