Dockerfile 是用來構建自定義 Docker 鏡像的文本文檔。咱們經過docker build
命令用於從Dockerfile 文件構建鏡像。 若是你要構建自定義鏡像,Dockerfile 是你必須學會的技能之一。java
Dockerfile 通常分爲:基礎鏡像、鏡像元信息、鏡像操做指令和容器啓動時執行指令,#
爲 Dockerfile 中的註釋。python
Docker 從上到下的順序運行Dockerfile 的指令,每個指令都以 step
爲步驟。並且文件的命名也必須爲 Dockerfile
。mysql
接下來對經常使用的 Dockerfile 指令進行總結。spring
FROM
是指定基礎鏡像,必須爲第一個命令,格式:sql
FROM <image>:<tag>
docker
其中 tag
或 digest
是可選的,若是不使用這兩個值時,會使用 latest
版本的基礎鏡像。 shell
示例: FROM mysql:5.6
apache
MAINTAINER
用來聲明維護者信息,該命令已通過期,推薦使用 LABEL
,格式:ubuntu
MAINTAINER <name>
緩存
LABEL:用於爲鏡像添加元數據,多用於聲明構建信息,做者、機構、組織等。格式:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
示例: LABEL version="1.0" description="felord.cn" by="Felordcn"
使用LABEL
指定元數據時,一條LABEL指定能夠指定一或多條元數據,指定多條元數據時不一樣元數據之間經過空格分隔。推薦將全部的元數據經過一條LABEL指令指定,以避免生成過多的中間鏡像。
ENV
用來設置環境變量,格式:
ENV <key> <value> ENV <key>=<value>
示例: ENV version 1.0.0
或者 ENV version=1.0.0
能夠經過 ${key}
在其它指令中來引用變量,如 ${version}
。咱們也能夠經過 docker run
中的 -e <ENV>
來動態賦值
ARG
用於指定傳遞給構建運行時的變量,格式:
ARG <name>[=<default value>]
經過 docker run
中的 --build-arg <key>=<value>
來動態賦值,不指定將使用其默認值。
WORKDIR
用來指定工做目錄,相似於咱們一般使用的cd
命令,格式:
WORKDIR <PATH>
經過 WORKDIR
設置工做目錄,Dockerfile 中的其它指令 RUN
、CMD
、ENTRYPOINT
、ADD
、COPY
等命令都會在該目錄下執行。在使用 docker run
運行容器時,能夠經過 -w
參數覆蓋構建時所設置的工做目錄。
ADD
用於將本地文件添加到鏡像中,tar
類型文件會自動解壓(網絡壓縮資源不會被解壓),能夠訪問網絡資源,相似 wget
,格式:
ADD <src>... <dest> # 用於支持包含空格的路徑 ADD ["<src>",... "<dest>"]
示例:
ADD home /path/ # 支持通配符 添加全部以"home"開頭的文件 到/path/ 下
COPY
的功能相似於 ADD
,可是不會自動解壓文件,也不能訪問網絡資源
RUN
用來執行構建鏡像時執行的命令,有如下兩種命令執行方式:
shell
執行格式:RUN <command>
示例: RUN apk update
exec
執行格式:RUN ["executable", "param1", "param2"]
示例: RUN ["/dev/file", "p1", "p2"]
須要注意的是: RUN
指令建立的中間鏡像會被緩存,並會在下次構建中使用。若是不想使用緩存鏡像,可在構建時指定 --no-cache
參數,示例:docker build --no-cache
CMD
構建容器後執行的命令,也就是在容器啓動時才執行的命令。格式:
# 執行可執行文件,優先執行 CMD ["executable","param1","param2"] # 設置了 ENTRYPOINT,則直接調用ENTRYPOINT添加參數 參見 CMD 講解 CMD ["param1","param2"] # 執行shell命令 CMD command param1 param2
示例: CMD ["/usr/bin/bash","--help"]
CMD
不一樣於 RUN
,CMD
用於指定在容器啓動時所要執行的命令,而RUN用於指定鏡像構建時所要執行的命令。
ENTRYPOINT
用來配置容器,使其可執行化。配合 CMD
可省去 application
,只使用參數。格式:
#可執行文件, 優先 ENTRYPOINT ["executable", "param1", "param2"] # shell內部命令 ENTRYPOINT command param1 param2
示例:
FROM ubuntu ENTRYPOINT ["top", "-b"] CMD ["-c"]
ENTRYPOINT
與 CMD
很是相似,不一樣的是經過 docker run
執行的命令不會覆蓋 ENTRYPOINT
,而 docker run
命令中指定的任何參數都會被當作參數再次傳遞給 ENTRYPOINT
指令。Dockerfile 中只有最後一個 ENTRYPOINT
命令起做用,也就是說若是你指定多個ENTRYPOINT
,只執行最後的 ENTRYPOINT
指令。
EXPOSE
指定與外界交互的端口,格式:
EXPOSE [<port>...]
示例: EXPOSE 8080 443
、 EXPOSE 80
、EXPOSE 11431/tcp 12551/udp
EXPOSE
並不會直接讓容器的端口映射主機。宿主機訪問容器端口時,須要在 docker run
運行容器時經過 -p
來發布這些端口,或經過 -P
參數來發布EXPOSE
導出的全部端口
VOLUME
用於指定持久化目錄, 格式:
VOLUME ["<src>",...]
示例:VOLUME ["/data"]
,VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"]
一個卷能夠存在於一個或多個容器的指定目錄,該目錄能夠繞過聯合文件系統,並具備如下功能:
和 EXPOSE
指令相似, VOLUME
並不會掛載的宿主機,須要經過 docker run
運行容器時經過 -v
來映射到宿主機的目錄中。參見另外一個命令 docker volume create
USER
指定運行容器時的用戶名或 UID
,後續的 RUN
也會使用指定用戶。使用 USER
指定用戶時,可使用用戶名、UID
或GID
,或是二者的組合。當服務不須要管理員權限時,能夠經過該命令指定運行用戶。而且能夠在以前建立所須要的用戶,格式:
USER user USER user:group USER uid:group USER uid USER user:gid USER uid:gid
使用 USER
指定用戶後,Dockerfile 中其後的命令 RUN
、CMD
、ENTRYPOINT
都將使用該用戶。你能夠經過 docker run
運行容器時,能夠經過 -u
參數來覆蓋指定用戶。
ONBUILD
做用是其當所構建的鏡像被用作其它鏡像的基礎鏡像,該鏡像中的 ONBUILD
中的命令就會觸發,格式:
ONBUILD [INSTRUCTION]
示例:
ONBUILD ADD . /application/src ONBUILD RUN /usr/local/bin/python-build --dir /app/src
今天對構建 Docker 鏡像腳本 Dockerfile 基本命令進行的詳細的總結,並加以舉例說明,相信能解決你在構建鏡像中的一些困惑。敬請多多關注微信公衆號:Felordcn ,後續將會有更多幹貨奉上。
# 使用 aws 的java jdk 8 FROM amazoncorretto:8 # 做者等相關的元信息 LABEL AUTHOR=Felordcn OG=felord.cn # 掛載卷 VOLUME ["/tmp","/logs"] # 時區 ENV TZ=Asia/Shanghai # 啓用配置文件 默認爲 application.yml ENV ACTIVE=defualt # 設置鏡像時區 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"]
關注公衆號:Felordcn 獲取更多資訊