二、基於 Dockerfile 構建並運行鏡像

本文是《Docker必知必會系列》第二篇,原文發佈於個人博客:悟塵紀

上一篇:Docker必知必會系列(一):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

將鏡像作爲容器運行

  1. 根據您的新鏡像啓動一個容器:

    docker run --publish 8000:8080 --detach --name board bulletinboard:1.0
    

    這裏有幾個常見的標誌:

    • --publish要求 Docker 將主機端口 8000 上傳入的流量轉發到容器的端口 8080。容器具有自己的專用端口集,因此,如果要從網絡訪問某個端口,則必須以這種方式將流量轉發到該端口。否則,作爲默認的安全狀態,防火牆規則將阻止所有網絡流量到達您的容器。
    • --detach 要求 Docker 在後臺運行此容器。
    • --name指定一個名稱,您可以使用該名稱在後續命令中引用您的容器,在這種情況下爲board

    還要注意,您沒有指定容器要運行的程序。您不必這樣做,因爲在構建 Dockerfile 時使用了CMD指令。Docker 知道在容器啓動時會自動運行npm start 程序。

  2. 在的瀏覽器中訪問您的應用程序localhost:8000,您應該看到公告板應用程序已啓動並正在運行。

    公告板應用程序運行中

  3. 對公告板容器正常工作感到滿意後,可以將其刪除:

    docker rm --force board
    

    --force選項將刪除正在運行的容器。如果停止容器運行,docker stop board則無需使用--force

相關文章

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章