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 執行個體時,只會遵循最後一個 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 架構以 Python 撰寫的小型「Hello World」應用程式。
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
若要傳送和部署此應用程式而不使用 Docker 建置,您需要確保
- 必要的執行階段依賴項已安裝在伺服器上
- 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 映像檔命名標準。當您建置映像檔時,您會使用此符號來命名您的映像檔。您可以利用許多公開映像檔,透過使用 Dockerfile 的 FROM
指令將它們導入您的建置步驟中。
Docker Hub 包含大量的官方映像檔,您可以將其用於此目的。
環境設定
下一行會在基礎映像檔內執行建置指令。
# install app dependencies
RUN apt-get update && apt-get install -y python3 python3-pip
這個 RUN
指令 會在 Ubuntu 中執行 shell,以更新 APT 套件索引並在容器中安裝 Python 工具。
註解
請注意 # install app dependencies
這一行。這是一個註解。 Dockerfile 中的註解以 #
符號開頭。隨著 Dockerfile 的發展,註解可以幫助記錄 Dockerfile 的工作原理,方便未來的讀者和編輯者(包括您自己!)理解。
注意
您可能已經注意到,註解使用的符號與檔案第一行上的語法指令相同。僅當模式符合指令且出現在 Dockerfile 的開頭時,該符號才會被解釋為指令。否則,它會被視為註解。
安裝依賴項
第二個 RUN
指令會安裝 Python 應用程式所需的 flask
依賴項。
RUN pip install flask==3.0.*
此指令的先決條件是將 pip
安裝到建置容器中。第一個 RUN
指令會安裝 pip
,確保我們可以使用該指令來安裝 flask 網頁框架。
複製檔案
下一個指令使用 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://127.0.0.1:8000
。