Dockerfile 概述
Dockerfile
一切都始於 Dockerfile。
Docker 透過讀取 Dockerfile 中的指令來構建映象。Dockerfile 是一個文字檔案,其中包含構建原始碼的指令。Dockerfile 指令語法由 Dockerfile 參考中的規範參考定義。
以下是最常見的指令型別
指令 | 描述 |
---|---|
FROM <image> | 定義映象的基礎。 |
RUN <command> | 在當前映象之上執行新層中的任何命令並提交結果。RUN 也有一個用於執行命令的 shell 形式。 |
WORKDIR <directory> | 設定 Dockerfile 中其後任何 RUN 、CMD 、ENTRYPOINT 、COPY 和 ADD 指令的工作目錄。 |
COPY <src> <dest> | 從 <src> 複製新檔案或目錄,並將其新增到容器檔案系統中的 <dest> 路徑。 |
CMD <command> | 允許您定義基於此映象啟動容器後執行的預設程式。每個 Dockerfile 只有一個 CMD ,並且當存在多個時,只有最後一個 CMD 例項被遵守。 |
Dockerfile 是映象構建的關鍵輸入,可以促進基於您獨特配置的自動化多層映象構建。Dockerfile 可以從簡單開始,並隨著您的需求增長以支援更復雜的場景。
檔名
Dockerfile 的預設檔名是 Dockerfile
,不帶副檔名。使用預設名稱允許您執行 docker build
命令而無需指定額外的命令標誌。
有些專案可能需要用於特定目的的不同 Dockerfile。一個常見的約定是將其命名為 <something>.Dockerfile
。您可以使用 docker build
命令的 --file
標誌來指定 Dockerfile 檔名。請參閱 docker build
CLI 參考以瞭解 --file
標誌。
注意我們建議為您的專案主要 Dockerfile 使用預設名稱(
Dockerfile
)。
Docker 映象
Docker 映象由層組成。每個層都是 Dockerfile 中構建指令的結果。層按順序堆疊,每個層都是表示應用於前一層更改的增量。
示例
以下是使用 Docker 構建應用程式的典型工作流程。
以下示例程式碼顯示了一個使用 Flask 框架編寫的小型“Hello World”Python 應用程式。
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
為了在不使用 Docker Build 的情況下發布和部署此應用程式,您需要確保
- 所需的執行時依賴項已安裝在伺服器上
- Python 程式碼已上傳到伺服器的檔案系統
- 伺服器使用必要的引數啟動您的應用程式
以下 Dockerfile 建立了一個容器映象,該映象已安裝所有依賴項並自動啟動您的應用程式。
# syntax=docker/dockerfile:1
FROM ubuntu:22.04
# install app dependencies
RUN apt-get update && apt-get install -y python3 python3-pip
RUN pip install flask==3.0.*
# install app
COPY hello.py /
# final configuration
ENV FLASK_APP=hello
EXPOSE 8000
CMD ["flask", "run", "--host", "0.0.0.0", "--port", "8000"]
以下是此 Dockerfile 的作用
Dockerfile 語法
要新增到 Dockerfile 的第一行是 # syntax
解析器指令。雖然是可選的,但此指令指示 Docker 構建器在解析 Dockerfile 時使用何種語法,並允許啟用 BuildKit 的舊版 Docker 在開始構建之前使用特定的 Dockerfile 前端。解析器指令 必須出現在 Dockerfile 中任何其他註釋、空格或 Dockerfile 指令之前,並且應該是 Dockerfile 中的第一行。
# syntax=docker/dockerfile:1
提示我們建議使用
docker/dockerfile:1
,它始終指向版本 1 語法的最新版本。BuildKit 會在構建前自動檢查語法的更新,確保您使用的是最新版本。
基礎映象
語法指令後面的行定義了要使用的基礎映象
FROM ubuntu:22.04
FROM
指令將您的基礎映象設定為 Ubuntu 的 22.04 版本。所有後續指令都在此基礎映象(Ubuntu 環境)中執行。ubuntu:22.04
記法遵循 Docker 映象命名的 name:tag
標準。當您構建映象時,您使用此記法來命名您的映象。您可以在您的專案中利用許多公共映象,透過使用 Dockerfile FROM
指令將其匯入到您的構建步驟中。
Docker Hub 包含大量官方映象,您可以用於此目的。
環境設定
以下行在基礎映象中執行構建命令。
# install app dependencies
RUN apt-get update && apt-get install -y python3 python3-pip
此 RUN
指令在 Ubuntu 中執行 shell,該 shell 更新 APT 包索引並在容器中安裝 Python 工具。
註釋
請注意 # install app dependencies
行。這是一個註釋。Dockerfile 中的註釋以 #
符號開頭。隨著 Dockerfile 的演變,註釋對於為檔案未來的讀者和編輯者(包括您自己)記錄 Dockerfile 的工作方式至關重要。
注意您可能已經注意到,註釋使用與檔案第一行上的 語法指令 相同的符號表示。只有當模式與指令匹配並出現在 Dockerfile 的開頭時,該符號才會被解釋為指令。否則,它被視為註釋。
安裝依賴項
第二個 RUN
指令安裝 Python 應用程式所需的 flask
依賴項。
RUN pip install flask==3.0.*
此指令的前提是 pip
已安裝到構建容器中。第一個 RUN
命令安裝 pip
,這確保我們可以使用該命令安裝 flask Web 框架。
複製檔案
下一個指令使用 COPY
指令將 hello.py
檔案從本地構建上下文複製到映象的根目錄。
COPY hello.py /
構建上下文是您可以在 Dockerfile 指令(如 COPY
和 ADD
)中訪問的一組檔案。
在 COPY
指令之後,hello.py
檔案被新增到構建容器的檔案系統。
設定環境變數
如果您的應用程式使用環境變數,您可以使用 ENV
指令在 Docker 構建中設定環境變數。
ENV FLASK_APP=hello
這設定了一個我們稍後需要的 Linux 環境變數。Flask(此示例中使用的框架)使用此變數啟動應用程式。沒有它,flask 將不知道在哪裡找到我們的應用程式才能執行它。
暴露埠
EXPOSE
指令標記我們的最終映象有一個服務在埠 8000
上監聽。
EXPOSE 8000
此指令不是必需的,但它是一個好習慣,有助於工具和團隊成員瞭解此應用程式正在做什麼。
啟動應用程式
最後,CMD
指令設定當用戶啟動基於此映象的容器時執行的命令。
CMD ["flask", "run", "--host", "0.0.0.0", "--port", "8000"]
此命令啟動 flask 開發伺服器,監聽埠 8000
上的所有地址。這裡的示例使用 CMD
的“exec 形式”版本。也可以使用“shell 形式”
CMD flask run --host 0.0.0.0 --port 8000
這兩個版本之間存在細微差異,例如它們如何捕獲 SIGTERM
和 SIGKILL
等訊號。有關這些差異的更多資訊,請參閱 Shell 和 exec 形式
構建
要使用 上一節中的 Dockerfile 示例構建容器映象,您可以使用 docker build
命令
$ docker build -t test:latest .
-t test:latest
選項指定了映象的名稱和標籤。
命令末尾的單個點(.
)將構建上下文設定為當前目錄。這意味著構建期望在呼叫命令的目錄中找到 Dockerfile 和 hello.py
檔案。如果這些檔案不存在,構建將失敗。
映象構建完成後,您可以使用 docker run
命令以容器方式執行應用程式,並指定映象名稱
$ docker run -p 127.0.0.1:8000:8000 test:latest
這會將容器的埠 8000 釋出到 Docker 主機上的 https://:8000
。
提示為了改進 Visual Studio Code 中 Dockerfile 的 linting、程式碼導航和漏洞掃描,請參閱 Docker VS Code 擴充套件。