Dockerfile簡單一點就是描述你這個鏡像安裝了哪些軟件包,有哪些操作,創建了什么東西。有些人喜歡用 docker commit 命令去打包鏡像,這樣是不好的,首先commit出來的鏡像比你使用Dockerfile構建出來的體積大,而且commit出來的鏡像屬於黑盒鏡像,除了制作者,誰都不知道你在里面干了什么,屬於不安全的鏡像,很少會有人使用,最后就是不便於你最終的管理和更新。所以推薦使用Dockerfile去管理你的鏡像,下面將簡單介紹Dockerfile常見的指令和注意事項:
注意:一行注釋一行命令,不要亂注釋,否則可能出現命令無效的情況,詳情看dockerfile官方文檔
文中加粗的是常用命令,一個命令可能有多種格式,注意!!
# escape=\
指定轉譯符,默認為\,可以使用任意符號
FROM
FROM <image>
FROM <image>:<tag>
FROM <image>:<digest>
FROM命令定義構建鏡像的基礎鏡像,該條必須是dockerfile的首個命令。
對於官方沒給出Dockerfile的軟件想Docker化,那么引用的鏡像一般是debian:jessie、alpine、ubuntu,如果官方已經有了,比如nginx、php、mysql這寫,那么基本直接引用即可。
MAINTAINER
MAINTAINER <messages>
聲明作者信息,可以放在文件任何位置,建議放在FROM后面
LABEL <key>=<value> <key>=<value> <key>=<value> ...
標簽,將后面的元數據添加到鏡像中,可以用docker inspect查看
RUN
RUN <commands>
RUN ["executable", "param1", "param2"] (exec form)
在基礎鏡像上創建新的鏡像執行命令,並提交結果,生成的新的鏡像將作為dockerfile中接下來的命令基礎(建議一個dockerfile中只要一個RUN命令,如果要執行多條命令請用連接符)(因為docker鏡像使用的是分層結構,一個指令就是一層,三個RUN就會有三層)
EXPOSE
EXPOSE <port>[<port>/<protocol>...]
容器暴露的端口(會直接綁定容器和docker宿主機的該端口,可以指定連接協議,默認為tcp協議)
CMD
CMD <commands>
容器啟動時執行操作,如果一個Dockerfile中有多個CMD命令,那么只有最后一個CMD命令生效。CMD的指令可以在docker run的時候覆蓋。
ENTRYPOINT
ENTRYPOINT
Dockerfile是用來構建鏡像,而ENTRYPOINT則是用來啟動鏡像,它會將CMD作為參數傳遞進去運行。
啟動時的默認命令,此命令設置不可被修改。如果一個Dockerfile中有多個ENTRYPOINT,那么只有最后一個生效。
詳情請看docker問答錄和官方文檔
eg:
ENTRYPOINT ["nginx"]
CMD ["-g","daemon off;"]
如上,如果執行 docker run -d --name nginx -P nginx 則最終容器內執行的命令是nginx -g daemon off; ,如果你執行的命令是 docker run -d --name nginx -P nginx bash 則最終容器內執行的命令是nginx bash 注意區別。
USER
USER <user>[:<group>]
USER <UID>[:<GID>]
指定docker構建,運行使用的用戶,如果不設置,將使用root的用戶和組來構建。前提是用戶要存在。
WORKDIR /path/to/workdir
docker構建、復制、運行等的工作目錄,一個dockerfile中可以指定多次,如果沒有指定將會自動創建,默認/,如果使用相對路徑,將在之前的路徑下。
ENV
ENV <key> <value>
ENV <key>=<value> ...
設置docker鏡像的環境變量,可以在構建鏡像時使用,也可以在運行的容器中使用,使用鍵值對的形式,可以一次指定多個。
ADD
ADD <src>... <dest>
ADD ["<src>",... "<dest>"]
The ADD instruction copies new files, directories or remote file URLs from <src> and adds them to the filesystem of the image at the path <dest>.
這個命令將會把src(源)目錄、文件、遠程文件URL復制到鏡像的文件系統中,存放目錄為dest(目標)目錄。如果src是壓縮文件會幫你解壓出來。
COPY
COPY <src>... <dest>
COPY ["<src>",... "<dest>"]
The COPY instruction copies new files or directories from <src> and adds them to the filesystem of the container at the path <dest>.
src只能是本地文件或目錄,壓縮文件不會解壓。。。
VOLUME
VOLUME ["/data"]
卷,由於docker容器不能持久化存儲數據,因此將會發生變化的數據使用卷來管理,卷分為宿主目錄、數據卷、容器卷。
VOLUME命令會設置你的卷,在啟動容器的時候Docker會在/var/lib/docker/的下一級目錄下創建一個卷,以保存你在容器中產生的數據。若沒有申明則不會創建。
eg:
VOLUME ["/data"]
VOLUME ["/data","/opt"]
WORKDIR
指定容器中的工作目錄,可以在構建時使用,也可以在啟動容器時使用,構建使用就是通過 WORKDIR 將當前目錄切換到指定的目錄中,容器中使用的意思則是在你使用 docker run 命令啟動容器時,默認進入的目錄是 WORKDIR 指定的,下面的example中我使用環境變量。
eg:
WORKDIR /app
ARG
ARG <name>[=<default value>]
變量,可以有值,也可以沒有。可以在構建時使用--build-arg定義。詳情請看官方文檔
ONBUILD
ONBUILD [INSTRUCTION]
ONBUILD命令在容器中添加一個觸發器,在將該鏡像作為基礎鏡像構建其他鏡像是觸發。會在下個容器FROM一調用就執行。
STOPSIGNAL signal
停止信號
HEALTHCHECK [OPTIONS] CMD command
用於檢測容器是否有效
SHELL ["executable", "parameters"]
使用命令的shell窗口來覆蓋默認的shell窗口,應該就是用容器的shell窗口覆蓋宿主機的shell窗口吧,沒用過。
參考
官方文檔:https://docs.docker.com/engine/reference/builder/
docker問答錄:https://blog.lab99.org/post/docker-2016-07-14-faq.html
感謝小沫大佬的指導