一、什麼是Dockerfile?
Dockerfile是一個包含用於組合映像的命令的文本文檔。可以使用在命令行中調用任何命令。 Docker通過讀取Dockerfile中的指令自動生成映像。
docker build命令用於從Dockerfile構建映像。可以在docker build命令中使用-f標誌指向文件系統中任何位置的Dockerfile。
例:
docker build -f /home/fendo/Dockerfile
二、Dockerfile的基本結構
Dockerfile 一般分爲四部分:基礎鏡像信息、維護者信息、鏡像操作指令和容器啓動時執行指令,’#’ 爲 Dockerfile 中的註釋。
三、Dockerfile格式
1. FROM
指定基於哪個基礎鏡像,必須爲第一個命令
格式:
FROM <image>
FROM <image>:<tag>
FROM <image>@<digest>
示例:
FROM mysql:5.6
注:
tag或digest是可選的,如果不使用這兩個值時,會使用latest版本的基礎鏡像
2. MAINTAINER
維護者信息
格式:
MAINTAINER <name>
示例:
MAINTAINER fendo fendo
MAINTAINER fendo.com
MAINTAINER fendo fendo <[email protected]>
3.RUN
構建鏡像時執行的命令
RUN用於在鏡像容器中執行命令,其有以下兩種命令執行方式:
3.1、shell執行
格式:
RUN <command>
3.2、exec執行
格式:
RUN ["executable", "param1", "param2"]
示例:
RUN ["executable", "param1", "param2"]
RUN yum update
RUN ["/etc/execfile", "arg1", "arg1"]
注:RUN指令創建的中間鏡像會被緩存,並會在下次構建中使用。如果不想使用這些緩存鏡像,可以在構建時指定–no-cache參數,如:docker build --no-cache
4.CMD
構建容器後調用,也就是在容器啓動時才進行調用。
格式:
CMD ["executable","param1","param2"] (執行可執行文件,優先)
CMD ["param1","param2"] (設置了ENTRYPOINT,則直接調用ENTRYPOINT添加參數)
CMD command param1 param2 (執行shell內部命令)
示例:
CMD ["/bin/bash", "/usr/local/nginx/sbin/nginx", "-c", "/usr/local/nginx/conf/nginx.conf"]
注:CMD不同於RUN,CMD用於指定在容器啓動時所要執行的命令,而RUN用於指定鏡像構建時所要執行的命令,只能有一條。
5.ADD
將本地文件添加到容器中,tar類型文件會自動解壓,可以訪問網絡資源,類似wget
格式:
ADD <src>... <dest>
ADD ["<src>",... "<dest>"] 用於支持包含空格的路徑
示例:
ADD hom* /fendo/ # 添加所有以"hom"開頭的文件到/fendo目錄
ADD hom?.txt /fendo/ # ? 替代一個單字符,例如:"home.txt"
ADD test relativeDir/ # 添加 "test" 到 `WORKDIR`/relativeDir/
ADD test /absoluteDir/ # 添加 "test" 到 /absoluteDir/
6.COPY
功能類似ADD,但是是不會自動解壓文件,也不能訪問網絡資源URL
7.ENTRYPOINT
配置容器,容器啓動時要執行的命令,它和CMD很像,也是隻有一條生效,如果寫多個只有最後一條有效。和CMD不同是:CMD 是可以被 docker run 指令覆蓋的,而ENTRYPOINT不能覆蓋
格式:
ENTRYPOINT ["executable", "param1", "param2"] (可執行文件, 優先)
ENTRYPOINT command param1 param2 (shell內部命令)
示例:
FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ["-c"]
注:ENTRYPOINT與CMD非常類似,不同的是通過docker run執行的命令不會覆蓋ENTRYPOINT,而docker run命令中指定的任何參數,都會被當做參數再次傳遞給ENTRYPOINT。Dockerfile中只允許有一個ENTRYPOINT命令,多指定時會覆蓋前面的設置,而只執行最後的ENTRYPOINT指令。
8.LABEL
用於爲鏡像添加元數據
格式:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
示例:
LABEL version="1.0" description="這是描述" by="fendo"
注:使用LABEL指定元數據時,一條LABEL指定可以指定一或多條元數據,指定多條元數據時不同元數據之間通過空格分隔。推薦將所有的元數據通過一條LABEL指令指定,以免生成過多的中間鏡像。
9.ENV
設置環境變量,它主要是爲後續的RUN指令提供一個環境變量
格式:
ENV <key> <value>
ENV <key>=<value> ...
示例:
ENV myName fendo
ENV myDog fendo Dog
ENV myCat fendo
10.EXPOSE
指定於外界交互的端口
格式:
EXPOSE <port> [<port>...]
示例:
EXPOSE 80 443
EXPOSE 8080
說明:
用來指定要映射出去的端口,比如容器內部我們啓動了sshd和nginx,所以我們需要把22和80端口暴漏出去。這個需要配合-P(大寫)來工作,
也就是說在啓動容器時,需要加上-P,讓它自動分配。如果想指定具體的端口,也可以使用-p(小寫)來指定。
注:
EXPOSE並不會讓容器的端口訪問到主機。要使其可訪問,需要在docker run運行容器時通過-p來發布這些端口,或通過-P參數來發布EXPOSE導出的所有端口
11.VOLUME
用於指定持久化目錄
格式:
VOLUME ["/path/to/dir"]
示例:
VOLUME ["/data"]
VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"
說明:
創建一個可以從本地主機或其他容器掛載的掛載點。
注:一個卷可以存在於一個或多個容器的指定目錄,該目錄可以繞過聯合文件系統,並具有以下功能:
- 卷可以容器間共享和重用
- 容器並不一定要和其它容器共享卷
- 修改卷後會立即生效 對卷的修改不會對鏡像產生影響
- 卷會一直存在,直到沒有任何容器在使用它
12.WORKDIR
工作目錄,類似於cd命令
格式:
WORKDIR /fendo/nginx
示例:
WORKDIR /a (這時工作目錄爲/a)
WORKDIR b (這時工作目錄爲/a/b)
WORKDIR c (這時工作目錄爲/a/b/c)
說明:爲後續的RUN、CMD或者ENTRYPOINT指定工作目錄
注:通過WORKDIR設置工作目錄後,Dockerfile中其後的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都會在該目錄下執行。在使用docker run運行容器時,可以通過-w參數覆蓋構建時所設置的工作目錄。