純乾貨!Dockerfile 常用指令清單

Dockerfile 常用指令

一、Dockerfile

Docker 可以通過Dockerfile自動構建鏡像,Dockerfile是一個包含多個指令的文檔。如下

 # syntax=docker/dockerfile:1
 FROM ubuntu:18.04
 COPY . /app
 RUN make /app
 CMD python /app/app.py

二、FROM

FROM命令用於初始化一個新的構建階段,併爲後續指令設置基礎鏡像:

 FROM [--platform=<platform>] <image> [AS <name>]
 FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
 FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]
 ARG CODE_VERSION=latest
 FROM base:${CODE_VERSION}
 CMD /code/run-app
 FROM extras:${CODE_VERSION}
 CMD /code/run-extras

三、RUN

RUN指令將在當前鏡像之上的新層中執行命令,並且提交結果。在docker build時運行。

 RUN /bin/bash -c 'source $HOME/.bashrc; \
 echo $HOME'

RUN 有兩種形式:

說明:

有些命令會使用管道(|),如:

 RUN wget -O - https://some.site | wc -l > /number

Docker 使用/bin/sh -c解釋器,解釋器只計算所有一個命令的退出狀態碼以確定命令是否執行成功,如上例,只要wc -l執行成功,即使wget命令失敗,這個構建步驟也會生成一層新鏡像。如果希望命令由於管道中任意階段命令的錯誤而失敗,需要預先設置set-o pipefail&&,如下:

 RUN set -o pipefail && wget -O - https://some.site | wc -l > /number

注意,基於 debian 的鏡像要使用 exec 形式支持-o pipefail:

 RUN ["/bin/bash", "-c", "set -o pipefail && wget -O - https://some.site | wc -l > /number"]

四、CMD

Dockerfile 使用RUN指令完成docker build所有的環境安裝與配置,通過CMD指令來指示docker run命令運行鏡像時要執行的命令。Dockerfile 只允許使用一次CMD命令。使用多個CMD會抵消之前所有的命令,只有最後一個命令生效。一般來說,這是整個 Dockerfile 腳本的最後一個命令。

 FROM ubuntu
 CMD ["/usr/bin/wc","--help"]

CMD 有三種形式:

五、EXPOSE

EXPOSE指令通知容器在運行時監聽某個端口,可以指定 TCP 或 UDP,如果不指定協議,默認爲 TCP 端口。但是爲了安全,docker run命令如果沒有帶上相應的端口映射參數,Docker 並不會將端口映射出去。

 EXPOSE 80/tcp
 EXPOSE 80/udp

指定映射端口方式:

docker run -P:將所有端口發佈到主機接口,每個公開端口綁定到主機上的隨機端口,端口範圍在/proc/sys/net/ipv4/ip_local_port_range定義的臨時端口範圍內。

docker run -p :顯式映射單個端口或端口範圍。

六、LABEL

LABEL指令爲鏡像添加標籤,當前鏡像會繼承父鏡像的標籤,如果與父標籤重複,會覆蓋之前的標籤。

 LABEL multi.label1="value1" \
      multi.label2="value2" \
      other="value3"
 或
 LABEL multi.label1="value1" multi.label2="value2" other="value3"

可以使用如下方式查看鏡像標籤:

 docker image inspect --format='' myimage

查看結果實例:

 {
   "com.example.vendor": "ACME Incorporated",
   "com.example.label-with-value": "foo",
   "version": "1.0",
   "description": "This text illustrates that label-values can span multiple lines.",
   "multi.label1": "value1",
   "multi.label2": "value2",
   "other": "value3"
 }

七、ENV

ENV命令用來在執行docker run命令運行鏡像時指定自動設置的環境變量。這個環境變量可以在後續任何 RUN 命令中使用,並在容器運行時保持。一般用於軟件更便捷的運行,如:

 ENV PATH=/usr/local/nginx/bin:$PATH
 CMD ["nginx"]

設置的環境變量將持續存在,可以使用docker inspect來查看。這些環境變量可以通過docker run --env <key>=<value>命令的參數來修改。

八、ARG

ARG 命令定義用戶只在構建時使用的變量,效果和docker build --build-arg <varname>=<value>一樣,這個參數只會在構建時存在,不會保留在鏡像中。

 ARG <name>[=<default value>]

ARG 與 ENV 類似,不同的是 ENV 會在鏡像構建結束後一直保存在容器中,而 ARG 會在鏡像構建結束狗消失。一般運用在希望整個構建過程是無交互的,那麼可以使用 ARG 命令(僅限 Debian 發行版)。

 ARG DEBIAN_FRONTEND=noninteractive
 RUN apt-get update && apt-get install -y ...

Docker 有一組預定義的 ARG 變量,您可以在 Dockerfile 中沒有相應指令的情況下使用這些變量。

要使用這些,請使用 --build-arg 標誌在命令行上傳遞它們,例如:

 docker build --build-arg HTTPS_PROXY=https://my-proxy.example.com .

九、ADD

ADD指令用於複製新文件、目錄或遠程文件 URL 到容器 路徑中。可以指定多個資源,但如果它們是文件或目錄,則它們的路徑被解釋爲相對於構建上下文的源,也就是 WORKDIR。

ADD指令有兩種形式:

 ADD [--chown=<user>:<group>] <src>... <dest>
 ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]

每個都 可能包含通配符,匹配將使用 Go 的 filepath.Match 規則。 是一個絕對路徑,或相對 WORKDIR 的相對路徑。例如:

添加所有以 “hom” 開頭的文件:

 ADD hom* /mydir/

在下面的示例中,? 被替換爲任何單個字符,例如 “home.txt”。

 ADD hom?.txt /mydir/

所有新創建的文件和目錄的 UID 和 GID 都爲 0,除非使用--chown指定 UID/GID 以及權限。-chown特性僅在用於構建 Linux 容器。

 ADD --chown=55:mygroup files* /somedir/
 ADD --chown=bin files* /somedir/
 ADD --chown=1 files* /somedir/
 ADD --chown=10:11 files* /somedir/

如果 是一個可識別壓縮格式(identity、gzip、bzip2 或 xz)的本地 tar 存檔,那麼它將被解包爲一個目錄。遠程 URL 中的資源不會解壓縮。當一個目錄被複制或解包時,它的行爲與tar -x相同。

十、COPY

COPY 指令和 ADD 指令的唯一區別在於:是否支持從遠程 URL 獲取資源。COPY 指令只能從執行 docker build 所在的主機上讀取資源並複製到鏡像中。而 ADD 指令還支持通過 URL 從遠程服務器讀取資源並複製到鏡像中。

相同複製命令下,使用 ADD 構建的鏡像比 COPY 命令構建的體積大,所以如果只是複製文件使用 COPY 命令。ADD 指令更擅長讀取本地 tar 文件並解壓縮。

十一、ENTRYPOINT

ENTRYPOINTCMD一樣,都是在指定容器啓動程序以及參數,不會它不會被docker run的命令行指令所覆蓋。如果要覆蓋的話需要通過docker run --entrypoint來指定。

ENTRYPOINT 有兩種形式:

 ENTRYPOINT ["exec","param1","param1"]
 ENTRYPOINT command param1 param2

指定了 ENTRYPOINT 後,CMD 的內容作爲參數傳遞給 ENTRYPOINT 指令,實際執行時將變爲:

十二、VOLUME

創建一個具有指定名稱的掛載數據卷。

 VOLUME ["/var/log/"]
 VOLUME /var/log

VOLUME 的主要作用是:

十三、ONBUILD

ONBUILD指令作爲觸發指令添加到鏡像中,只有在該鏡像作爲基礎鏡像時執行。觸發器將在下游構建的 Dockerfile 中的FROM指令之後執行。如果任何觸發器失敗,FROM指令將中止,從而導致生成失敗。如果所有觸發器都成功,FROM指令將完成,構建將照常繼續。

 ONBUILD ADD . /app/src
 ONBUILD RUN /usr/local/bin/python-build --dir /app/src

注意,ONBUILD 指令不能觸發 FORM 和 MAINTAINER 指令。

十四、STOPSIGNAL

設置容器退出時喚起的系統調用信號。該信號可以是與內核系統調用表中的位置匹配的有效無符號數字,例如 9,或格式爲 SIGNAME 的信號名稱,如 SIGKILL。

 STOPSIGNAL signal

默認的 stop-signal 是 SIGTERM,在docker stop的時候會給容器內 PID 爲 1 的進程發送這個信號,通過--stop-signal可以設置需要的 signal,主要用於讓容器內的程序在接收到 signal 之後可以先處理些未完成的事務,實現優雅結束進程後退出容器。如果不做任何處理,容器將在一段時間後強制退出,可能會造成業務強制中斷,默認時間是 10s。

十五、HEALTHCHECK

HEALTHCHECK指令告訴容器如何檢查它是否保持運行。當容器具有指定的HEALTHCHECK時,除了其正常狀態外,還具有健康狀態。容器的狀態最初是starting,只要通過健康檢查,容器的狀態就變成healthy(無論之前處於什麼狀態)。如果經過一定數量的失敗檢查,容器的狀態會變成unhealthy

HEALTHCHECK指令有兩種形式:

HEALTHCHECK選項(應處於CMD之前):

舉例:

 HEALTHCHECK --interval=5m --timeout=3s \
   CMD curl -f http://localhost/ || exit 1

十六、SHELL

SHELL指令用於設置默認 shell。Linux 上默認 shell 是["/bin/sh","-c"],Windows 上是["cmd","/S","/C"]

 SHELL ["exec","param1"]

SHELL指令在 Windows 上特別有用,因爲 Windows 有兩種截然不同的本機 SHELL:CMD 和 powershell,以及備用的 sh。該 SHELL 指令可以出現多次。每條 SHELL 指令都會覆蓋所有先前的 SHELL 指令,並影響後續指令。

FROM
Learn more about the "FROM" Dockerfile command.
 microsoft/windowsservercore

# Executed as cmd /S /C echo default
RUN echo default

# Executed as cmd /S /C powershell -command Write-Host default
RUN powershell -command Write-Host default

# Executed as powershell -command Write-Host hello
SHELL ["powershell", "-command"]
RUN Write-Host hello

# Executed as cmd /S /C echo hello
SHELL ["cmd", "/S", "/C"]
RUN echo hello

十七、WORKDIR

WORKDIR指令爲 Dockerfile 中接下來的RUNCMDENTRYPOINTADDCOPY指令設置工作目錄。如果WORKDIR不存在,及時它沒有在後續 Dockerfile 指令中使用,它也會被創建。

Dockerfile 中可以多次使用WORKDIR,如果提供了相對路徑,它將相對於前一條WORKDIR指令的路徑。

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd

最終 pwd 命令的輸出是 /a/b/c。

該 WORKDIR 指令可以解析先前使用 ENV,例如:

ENV DIRPATH=/path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd

最終 pwd 命令的輸出是 /path/$DIRNAME。

官方推薦 WORKDIR 始終使用絕對路徑。此外,儘量避免使用RUN cd ..&& dosomething,大量的類似指令會降低可讀性,令 Dockerfile 難以維護。

十八、USER

RUN指令設置用戶名或(UID)和可選用戶組(或 GID),用於運行Dockerfile中接下來的RUNCMDENTRYPOINT指令。

USER <user>[:<group>]
USER <UID>[:<GID>]

注意,在 Linux 上,當用戶沒有主組時,鏡像(或指令)將與根組一起運行。在 Windows 上,如果用戶不是內置帳戶,則必須首先創建該用戶。也可以先通通過net user創建用戶,再指定用戶。

FROM microsoft/windowsservercore
# Create Windows user in the container
RUN net user /add patrick
# Set it for subsequent commands
USER patrick

十九、MAINTAINER

MAINTAINER 指令設置生成鏡像的作者。如:

MAINTAINER <name>

官方文檔:

https://docs.docker.com/engine/reference/builder/#label

如果對文章內容存在疑問

歡迎各位移步到公衆號後臺留言。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/swiryyb9Azzr7fva5ISE9w