docker構建的鏡像的三種方式

字節碼在跳舞 2024-04-11 17:56:10

通過容器創建

通過Dockerfile構建鏡像

使用BuildKit構建鏡像

1. 通過容器創建

容器提交是一種快速創建鏡像的方法,它將一個正在運行的容器的當前狀態保存爲一個新的鏡像。

提交容器:使用docker commit命令,指定要提交的容器ID、新鏡像的名稱和可選標簽。

docker commit container_id my_image:tag

➜  ~ docker commit -m "create image" nginx demo:testsha256:4f00c504f06115b9230c21afab2709b8cff1c5d4e8f2799f3472964c4b1c9d8c➜  ~ docker imagesREPOSITORY                                      TAGIMAGE ID       CREATED          SIZEdemo                                            test                      4f00c504f061   2 seconds ago    141MB

通過docker commit命令,可以將容器(如示例中的nginx,也可以使用容器ID)的當前狀態提交爲新鏡像,同時指定新鏡像的名稱(如my_image)和標簽(如tag)。這裏使用-m參數添加提交說明。

這種方式簡單快捷,適用于臨時或實驗性的鏡像創建。然而,不建議頻繁使用容器提交方式創建鏡像,因爲通過提交容器的方式,我們無法追溯詳細的變更操作,這會導致鏡像構建過程缺乏透明度和可重複性。

2. 通過Dockerfile構建鏡像

在Docker構建自定義鏡像時,Dockerfile是一個至關重要的工具。Dockerfile 是一個文本文件,它包含了一系列指令,用于自動化構建Docker鏡像。通過編寫Dockerfile,你可以精確地定義構建鏡像所需的步驟、依賴關系和配置項。整個過程通常稱爲“構建”(build)。Dockerfile確保了鏡像構建的可重複性和一致性。

下面是一個Dockerfile示例:

FROM python:3.11.9-alpine3.19LABEL authors="ff755"EXPOSE 8000WORKDIR /appCOPY . /appRUN pip install -i https://pypi.tuna.tsinghua.edu.cn/simple --no-cache-dir -r requirements.txtCMD [ "python", "./main.py" ]

示例代碼:https://gitee.com/ft/hello-py.git(一個FastAPI的Hello World項目)

指令詳解:

FROM:指定基于哪個鏡像來構建。示例中使用了python:3.11.9-alpine3.19鏡像。我們可以根據實際需求選擇合適的基鏡像來構建我們自己的鏡像。

LABEL:爲鏡像添加元數據,如作者、版本等,便于管理和搜索鏡像。

EXPOSE:聲明鏡像內服務對外提供的端口號。如果不指定,運行容器時使用-P將不會自動映射端口。

WORKDIR:設定鏡像的工作目錄,即容器內的當前目錄(等同于命令pwd)。

COPY:從宿主機指定目錄複制文件到容器內的指定目錄。如COPY . .表示將宿主機當前目錄下的所有文件複制到容器內的工作目錄。

RUN:在新構建的鏡像中執行命令並提交結果。每次RUN指令都會在當前鏡像層上執行命令,然後生成一個新的鏡像層。例如,上面通過pip根據requirements.txt安裝 Python 依賴,並指定使用清華大學的鏡像源。

CMD:設置容器啓動後默認執行的命令。只有最後一個CMD指令會被執行,如果用戶在運行容器時指定了命令,則會覆蓋CMD指定的命令。如CMD [ "python", "./main.py" ]表示容器啓動時運行python ./main.py。

此外,還有其他常用指令:

ENV:設置環境變量。

ARG:  設置構建變量。與ENV不通,ARG是定義構建過程中的變量。

ADD:類似于COPY,功能更豐富,可以支持URL下載並添加文件,自動解壓tar.gz等。一般情況下推薦使用COPY。

ENTRYPOINT:類似于CMD,常用于定義始終執行的可執行程序。

VOLUME:創建一個數據卷挂載點,用于持久化數據或與其他容器共享數據。數據卷獨立于容器生命周期,即使容器被刪除,數據也會被保留。

基于Dockerfile構建鏡像:

docker build -t hello:py .

使用docker build通過Dockerfile構建鏡像。當Docker不在當前目錄時,可以添加-f [你的目錄]/Dockerfile指定。

Docker Hub官方倉庫提供了大量的優秀鏡像和Dockerfile,可以通過閱讀,來學習如何編寫Dockerfile,高效編寫Dockerfile,構建我們自己的鏡像。

3. 使用BuildKit構建鏡像

Docker還提供了一個實驗性的構建工具,稱爲BuildKit,它可以提供更快的構建速度和更高效的鏡像緩存。使用BuildKit構建鏡像的方式與使用Dockerfile類似,只需設置一個環境變量即可啓用BuildKit。

# 設置環境變量啓用BuildKitexport DOCKER_BUILDKIT=1

使用常規的docker build命令構建鏡像,即可享受到 BuildKit 帶來的性能提升和新特性。BuildKit 作爲新一代的 Docker 構建工具,通過一系列創新設計和優化措施,極大地改善了 Docker 鏡像構建的效率、安全性和靈活性。

以下爲使用默認構建方式和BuildKit的效果:

默認構建:

➜  hello-py git:(master) docker build -t hello-py:0.0.1 .[+] Building 119.3s (9/9) FINISHED                   docker:default=> [internal] load build definition from Dockerfile           0.1s=> => transferring dockerfile: 254B                           0.0s=> [internal] load metadata for docker.io/library/python:3.  68.8s=> [internal] load .dockerignore                              0.1s=> => transferring context: 2B                                0.0s=> [1/4] FROM docker.io/library/python:3.11.9-alpine3.19@sh  35.2s=> => resolve docker.io/library/python:3.11.9-alpine3.19@sha  0.0s=> => sha256:3912f7fe31112ee0f747848328e1a2b 1.37kB / 1.37kB  0.0s=> => sha256:10333afc009e90c9e91c1f1d7deca49 6.26kB / 6.26kB  0.0s=> => sha256:c3cdf40b8bda8e4ca4be0f5fa7 619.60kB / 619.60kB  17.6s=> => sha256:ac499ccf2147611bc4388058b362 12.67MB / 12.67MB  22.2s=> => sha256:0b5ed25d3cc27cd35c7b0352bac8ef2 1.65kB / 1.65kB  0.0s=> => sha256:416bfceb623eb12bf1c373489e0dba32f0 240B / 240B  19.8s=> => extracting sha256:c3cdf40b8bda8e4ca4be0f5fa7f1d1289072  0.2s=> => sha256:76351c33299b900aa86b33176eac19 3.13MB / 3.13MB  34.3s=> => extracting sha256:ac499ccf2147611bc4388058b362c0bcc1ca  0.5s=> => extracting sha256:416bfceb623eb12bf1c373489e0dba32f00f  0.0s=> => extracting sha256:76351c33299b900aa86b33176eac198fc861  0.3s=> [internal] load build context                              0.2s=> => transferring context: 31.28kB                           0.0s=> [2/4] WORKDIR /app                                         2.1s=> [3/4] COPY . /app                                          0.6s=> [4/4] RUN pip install -i https://pypi.tuna.tsinghua.edu.  11.6s=> exporting to image                                         0.3s=> => exporting layers                                        0.3s=> => writing image sha256:a90573dc2e0981ef136518fc7c244af6c  0.0s=> => naming to docker.io/library/hello-py:0.0.1              0.0s

啓用BuildKit進行構建

➜  hello-py git:(master) docker build -t hello-py:buildkit .[+] Building 16.8s (9/9) FINISHED                    docker:default=> [internal] load build definition from Dockerfile           0.0s=> => transferring dockerfile: 254B                           0.0s=> [internal] load metadata for docker.io/library/python:3.  16.6s=> [internal] load .dockerignore                              0.0s=> => transferring context: 2B                                0.0s=> [1/4] FROM docker.io/library/python:3.11.9-alpine3.19@sha  0.0s=> [internal] load build context                              0.0s=> => transferring context: 2.84kB                            0.0s=> CACHED [2/4] WORKDIR /app                                  0.0s=> CACHED [3/4] COPY . /app                                   0.0s=> CACHED [4/4] RUN pip install -i https://pypi.tuna.tsinghu  0.0s=> exporting to image                                         0.0s=> => exporting layers                                        0.0s=> => writing image sha256:a90573dc2e0981ef136518fc7c244af6c  0.0s=> => naming to docker.io/library/hello-py:buildkit           0.0s

默認構建耗時119.3s,啓用BuildKit後16.8s,速度快了7倍,快來試試吧。

雖然,通過容器可以創建鏡像,但Dockerfile構建鏡像的應當成爲我們創建鏡像的首選。通過合理編寫Dockerfile,可以實現自動化、可重複和可維護的鏡像構建過程。開啓BuildKit可以更快速的構建我們的鏡像。

忍不住要加個關注!不是我吹,但你會後悔沒關注的!

0 阅读:0

字節碼在跳舞

簡介:分享學習筆記、知識。