Docker 構(gòu)建腳本 Dockerfile 指令全解析

Dockerfile

1. 前言

Dockerfile 是用來構(gòu)建自定義 Docker 鏡像的文本文檔。我們通過docker build 命令用于從Dockerfile 文件構(gòu)建鏡像。 如果你要構(gòu)建自定義鏡像,Dockerfile 是你必須學(xué)會的技能之一。

2. Dockerfile 的基本結(jié)構(gòu)

Dockerfile 一般分為:基礎(chǔ)鏡像、鏡像元信息、鏡像操作指令和容器啟動時執(zhí)行指令,#Dockerfile 中的注釋。

3. Dockerfile 文件說明

Docker 從上到下的順序運行Dockerfile 的指令,每一個指令都以 step 為步驟。而且文件的命名也必須為 Dockerfile

4. Dockerfile 常用的指令。

接下來對常用的 Dockerfile 指令進(jìn)行總結(jié)。

4.1 FROM 指令

FROM是指定基礎(chǔ)鏡像,必須為第一個命令,格式:

FROM <image>:<tag>

其中 tagdigest 是可選的,如果不使用這兩個值時,會使用 latest 版本的基礎(chǔ)鏡像。

示例: FROM mysql:5.6

4.2 MAINTAINER 指令

MAINTAINER 用來聲明維護(hù)者信息,該命令已經(jīng)過期,推薦使用 LABEL ,格式:

MAINTAINER <name>

4.3 LABEL 指令

LABEL:用于為鏡像添加元數(shù)據(jù),多用于聲明構(gòu)建信息,作者、機(jī)構(gòu)、組織等。格式:

LABEL <key>=<value> <key>=<value> <key>=<value> ...

示例: LABEL version="1.0" description="felord.cn" by="Felordcn"

使用LABEL 指定元數(shù)據(jù)時,一條LABEL指定可以指定一或多條元數(shù)據(jù),指定多條元數(shù)據(jù)時不同元數(shù)據(jù)之間通過空格分隔。推薦將所有的元數(shù)據(jù)通過一條LABEL指令指定,以免生成過多的中間鏡像。

4.4 ENV 指令

ENV 用來設(shè)置環(huán)境變量,格式:

ENV <key> <value>  

ENV <key>=<value>  

示例: ENV version 1.0.0 或者 ENV version=1.0.0

可以通過 ${key} 在其它指令中來引用變量,如 ${version} 。我們也可以通過 docker run 中的 -e <ENV> 來動態(tài)賦值

4.5 ARG 指令

ARG 用于指定傳遞給構(gòu)建運行時的變量,格式:

ARG <name>[=<default value>]

通過 docker run 中的 --build-arg <key>=<value> 來動態(tài)賦值,不指定將使用其默認(rèn)值。

4.6 WORKDIR 指令

WORKDIR 用來指定工作目錄,類似于我們通常使用的cd 命令,格式:

WORKDIR <PATH>

通過 WORKDIR 設(shè)置工作目錄,Dockerfile 中的其它指令 RUN、CMDENTRYPOINT、ADDCOPY等命令都會在該目錄下執(zhí)行。在使用 docker run 運行容器時,可以通過 -w 參數(shù)覆蓋構(gòu)建時所設(shè)置的工作目錄。

4.7 ADD 指令

ADD 用于將本地文件添加到鏡像中,tar 類型文件會自動解壓(網(wǎng)絡(luò)壓縮資源不會被解壓),可以訪問網(wǎng)絡(luò)資源,類似 wget,格式:

 ADD <src>... <dest>
 # 用于支持包含空格的路徑
 ADD ["<src>",... "<dest>"] 

示例:

ADD home* /path/ # 支持通配符 * 添加所有以"home"開頭的文件 到/path/ 下

4.8 COPY 指令

COPY 的功能類似于 ADD,但是不會自動解壓文件,也不能訪問網(wǎng)絡(luò)資源

4.9 RUN 指令

RUN 用來執(zhí)行構(gòu)建鏡像時執(zhí)行的命令,有以下兩種命令執(zhí)行方式:

  • shell 執(zhí)行格式:

RUN <command>

示例:RUN apk update

  • exec 執(zhí)行格式:

RUN ["executable", "param1", "param2"]

示例: RUN ["/dev/file", "p1", "p2"]

需要注意的是: RUN 指令創(chuàng)建的中間鏡像會被緩存,并會在下次構(gòu)建中使用。如果不想使用緩存鏡像,可在構(gòu)建時指定 --no-cache 參數(shù),示例:docker build --no-cache

4.10 CMD 指令

CMD 構(gòu)建容器后執(zhí)行的命令,也就是在容器啟動時才執(zhí)行的命令。格式:

 # 執(zhí)行可執(zhí)行文件,優(yōu)先執(zhí)行
 CMD ["executable","param1","param2"]  
 # 設(shè)置了 ENTRYPOINT,則直接調(diào)用ENTRYPOINT添加參數(shù)  參見 CMD 講解 
 CMD ["param1","param2"] 
 # 執(zhí)行shell命令
 CMD command param1 param2  

示例: CMD ["/usr/bin/bash","--help"]

CMD 不同于 RUN,CMD 用于指定在容器啟動時所要執(zhí)行的命令,而RUN用于指定鏡像構(gòu)建時所要執(zhí)行的命令。

4.11 ENTRYPOINT 指令

ENTRYPOINT 用來配置容器,使其可執(zhí)行化。配合 CMD可省去 application,只使用參數(shù)。格式:

 #可執(zhí)行文件, 優(yōu)先
 ENTRYPOINT ["executable", "param1", "param2"]  
 # shell內(nèi)部命令
 ENTRYPOINT command param1 param2  

示例:

    FROM ubuntu

    ENTRYPOINT ["top", "-b"]

    CMD ["-c"] 

ENTRYPOINTCMD 非常類似,不同的是通過 docker run 執(zhí)行的命令不會覆蓋 ENTRYPOINT ,而 docker run 命令中指定的任何參數(shù)都會被當(dāng)做參數(shù)再次傳遞給 ENTRYPOINT 指令。Dockerfile 中只有最后一個 ENTRYPOINT 命令起作用,也就是說如果你指定多個ENTRYPOINT,只執(zhí)行最后的 ENTRYPOINT 指令。

4.12 EXPOSE 指令

EXPOSE 指定與外界交互的端口,格式:

EXPOSE [<port>...]

示例: EXPOSE 8080 443 、EXPOSE 80 、EXPOSE 11431/tcp 12551/udp

EXPOSE 并不會直接讓容器的端口映射主機(jī)。宿主機(jī)訪問容器端口時,需要在 docker run 運行容器時通過 -p 來發(fā)布這些端口,或通過 -P 參數(shù)來發(fā)布EXPOSE 導(dǎo)出的所有端口

4.13 VOLUME 指令

VOLUME 用于指定持久化目錄, 格式:

VOLUME ["<src>",...]

示例:VOLUME ["/data"],VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"]

一個卷可以存在于一個或多個容器的指定目錄,該目錄可以繞過聯(lián)合文件系統(tǒng),并具有以下功能:

  1. 卷可以容器間共享和重用
  2. 容器并不需要要和其它容器共享卷
  3. 修改卷后會立即生效
  4. 對卷的修改不會對鏡像產(chǎn)生影響
  5. 卷會一直存在,直到?jīng)]有任何容器在使用它

EXPOSE 指令類似, VOLUME 并不會掛載的宿主機(jī),需要通過 docker run 運行容器時通過 -v 來映射到宿主機(jī)的目錄中。參見另一個命令 docker volume create

4.14 USER 指令

USER 指定運行容器時的用戶名或 UID,后續(xù)的 RUN 也會使用指定用戶。使用 USER 指定用戶時,可以使用用戶名、UIDGID,或是兩者的組合。當(dāng)服務(wù)不需要管理員權(quán)限時,可以通過該命令指定運行用戶。并且可以在之前創(chuàng)建所需要的用戶,格式:

USER user
USER user:group
USER uid:group
USER uid
USER user:gid
USER uid:gid

使用 USER 指定用戶后,Dockerfile 中其后的命令 RUN、CMD、ENTRYPOINT 都將使用該用戶。你可以通過 docker run 運行容器時,可以通過 -u 參數(shù)來覆蓋指定用戶。

4.15 ONBUILD 指令

ONBUILD 作用是其當(dāng)所構(gòu)建的鏡像被用做其它鏡像的基礎(chǔ)鏡像,該鏡像中的 ONBUILD 中的命令就會觸發(fā),格式:

ONBUILD [INSTRUCTION]

示例:

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

5. 總結(jié)

今天對構(gòu)建 Docker 鏡像腳本 Dockerfile 基本命令進(jìn)行的詳細(xì)的總結(jié),并加以舉例說明,相信能解決你在構(gòu)建鏡像中的一些困惑。敬請多多關(guān)注微信公眾號:Felordcn ,后續(xù)將會有更多干貨奉上。

附: Spring Boot Dockerfile

   # 使用 aws 的java jdk 8
   FROM amazoncorretto:8
   # 作者等相關(guān)的元信息
   LABEL AUTHOR=Felordcn OG=felord.cn
   # 掛載卷 
   VOLUME ["/tmp","/logs"]
   # 時區(qū)
   ENV TZ=Asia/Shanghai
   # 啟用配置文件 默認(rèn)為 application.yml  
   ENV ACTIVE=defualt
   # 設(shè)置鏡像時區(qū)
   RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
   # 修改為打包后的jar文件名稱
   ADD /target/flyway-spring-boot-1.0.0.jar app.jar
   ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-Dspring.profiles.active=${ACTIVE}","-jar","app.jar"]

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容