本篇文章給大家帶來了關于dockerfile命令的相關知識,該命令包含一條條指令,每條指令構建一層的鏡像制作文件,希望對大家有幫助。
推薦學習:《dockerfile》
dockerFile 命令詳解
Dockerfile 是包含一條條指令,每條指令構建一層的鏡像制作文件。
構建鏡像
docker build [選項] <上下文路徑/URL/-> docker build -t nginx:v3 . # . 表示Dockerfile在當前目錄
FROM 指定基礎鏡像
通過FROM指定基礎鏡像,因此一個 Dockerfile 中 FROM 是必備的指令,并且必須是第一條指令。
FROM scratch,這個鏡像是虛擬的概念,并不實際存在,它表示一個空白的鏡像,接下來的指令將作為鏡像第一層開始存在。
RUN 執行命令
RUN 用來執行命令行命令,其格式有兩種:
shell 格式:
RUN <命令> RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
exec 格式:
RUN ["可執行文件", "參數1", "參數2"]
Union FS 是有最大層數限制的,比如 AUFS,曾經是最大不得超過 42 層,現在是不得超過 127 層,相同功能應該使用 && 將各個所需命令串聯起來簡化鏡像的層數
COPY 復制文件
COPY [--chown=<user>:<group>] <宿主機源路徑> <鏡像內的目標路徑> COPY [--chown=<user>:<group>] ["<宿主機源路徑1>",... "<鏡像內的目標路徑>"]
# 把當前目錄的a.txt文件復制到鏡像的根目錄 COPY a.txt /a.txt
ADD 復制文件(下載文件或解壓文件)
ADD [--chown=<user>:<group>] http://xxx <目標路徑> # 下載文件到鏡像的目標路徑 ADD [--chown=<user>:<group>] ./a.tar.gz <目標路徑> # 復制壓縮包,并自動解壓到目標路徑
CMD 指定默認的容器主進程的啟動命令
CMD ["可執行文件", "參數1", "參數2"...]
# 指定進入容器馬上指定 cat /a.txt CMD ["sh","-c", "cat /a.txt"]
執行 docker run -it 鏡像的時候,如果不指定命令類似 /bin/bash ,會自動執行 sh -c cat /a.txt,否則會按用戶指定的CMD
ENTRYPOINT 指定容器主進程的啟動命令,類似CMD
格式與CMD一致,差異點
1、使用ENTRYPOINT可以傳參
在Dockerfile中指定ENTRYPOINT [ “curl”, “-s”, “http://myip.ipip.net” ],命令行通過 docker run myip -i 時,會把 -i 參數傳給 ENTRYPOINT 的命令,最后進入
容器時,容器會執行 curl -s http://myip.ipip.net -i
2、執行一些與 CMD 無關的初始化工作,與容器 CMD 無關的,無論 CMD 為什么,都需要事先進行一個預處理的工作。
類似 ENTRYPOINT [“docker-entrypoint.sh”] ?這個腳本里檢查用戶的身份是否合法等
ENV 設置環境變量
ENV <key> <value> ENV <key1>=<value1> <key2>=<value2>...
ARG 構建參數
ARG <參數名>[=<默認值>]
ARG 指令有生效范圍,如果在 FROM 指令之前指定,那么只能用于 FROM 指令中。
ARG DOCKER_USERNAME=library FROM ${DOCKER_USERNAME}/alpine
如果在FROM之后指定,對于在各個階段中使用的變量都必須在每個階段分別指定
FROM ${DOCKER_USERNAME}/alpine # 在FROM 之后使用變量,必須在每個階段分別指定 ARG DOCKER_USERNAME=library RUN set -x ; echo ${DOCKER_USERNAME}
VOLUME 匿名卷
VOLUME ["<路徑1>", "<路徑2>"...] VOLUME <路徑>
為了防止運行時用戶忘記將動態文件所保存目錄掛載為卷,在 Dockerfile 中,可以事先指定某些目錄掛載為匿名卷,這樣在運行時如果用戶不指定掛載,其應用也可以正常運行,不會向容器存儲層寫入大量數據
這里的 /data 目錄就會在容器運行時自動掛載為匿名卷,任何向 /data 中寫入的信息都不會記錄進容器存儲層,從而保證了容器存儲層的無狀態化。
EXPOSE 暴露端口
EXPOSE <端口1> [<端口2>...]
EXPOSE 指令是聲明容器運行時提供服務的端口,EXPOSE 僅僅是聲明容器打算使用什么端口而已,并不會自動在宿主進行端口映射。
在 Dockerfile 中寫入這樣的聲明有兩個好處,一個是幫助鏡像使用者理解這個鏡像服務的守護端口,以方便配置映射;
另一個用處則是在運行時使用隨機端口映射時,也就是 docker run -P 時,會自動隨機映射 EXPOSE 的端口。
要將 EXPOSE 和在運行時使用 -p : 區分開來。
-p,是映射宿主端口和容器端口,換句話說,就是將容器的對應端口服務公開給外界訪問。
WORKDIR?指定工作目錄,如該目錄不存在,WORKDIR 會建立目錄
WORKDIR <工作目錄路徑>
例子1:
WORKDIR /app RUN echo "hello" > world.txt
例子2:
WORKDIR /a WORKDIR b WORKDIR c RUN pwd ## RUN pwd 的工作目錄為 /a/b/c
USER?指定當前用戶
USER <用戶名>[:<用戶組>]
如果以 root 執行的腳本,在執行期間希望改變身份,比如希望以某個已經建立好的用戶來運行某個服務進程,不要使用 su 或者 sudo,這些都需要比較麻煩的配置,而且在 TTY 缺失的環境下經常出錯。建議使用 gosu。
# 建立 redis 用戶,并使用 gosu 換另一個用戶執行命令 RUN groupadd -r redis && useradd -r -g redis redis # 下載 gosu RUN wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/1.12/gosu-amd64" && chmod +x /usr/local/bin/gosu && gosu nobody true # 設置 CMD,并切換到redis用戶執行 CMD [ "exec", "gosu", "redis", "redis-server" ]
HEALTHCHECK 告訴 Docker 如何進行判斷容器的狀態是否正常
HEALTHCHECK [選項] CMD <命令>:設置檢查容器健康狀況的命令 HEALTHCHECK NONE:如果基礎鏡像有健康檢查指令,使用這行可以屏蔽掉其健康檢查指令
選項:
--interval=<間隔>:兩次健康檢查的間隔,默認為 30 秒; --timeout=<時長>:健康檢查命令運行超時時間,如果超過這個時間,本次健康檢查就被視為失敗,默認 30 秒; --retries=<次數>:當連續失敗指定次數后,則將容器狀態視為 unhealthy,默認 3 次
當在一個鏡像指定了 HEALTHCHECK 指令后,用其啟動容器,初始狀態會為 starting,在 HEALTHCHECK 指令檢查成功后變為 healthy,如果連續一定次數失敗,則會變為 unhealthy。
HEALTHCHECK 只可以出現一次,如果寫了多個,只有最后一個生效
CMD 命令的返回值決定了該次健康檢查的成功與否:0:成功;1:失敗
ONBUILD 指定某些命令只有當以當前鏡像為基礎鏡像,去構建下一級鏡像的時候才會被執行
ONBUILD <其它指令>
# 舉例如下Dockerfile,初次構建為鏡像my-node時,ONBUILD的三行命令不會執行 FROM node:slim RUN mkdir /app WORKDIR /app ONBUILD COPY ./package.json /app ONBUILD RUN [ "npm", "install" ] ONBUILD COPY . /app/ CMD [ "npm", "start" ] # 只要當其他鏡像 FROM my-node 從上面鏡像作為基礎鏡像進行構建時,ONBUILD 的命令開始執行
LABEL 為鏡像添加元數據
LABEL <key>=<value> <key>=<value> <key>=<value> ...
# 標注鏡像的作者 LABEL org.opencontainers.image.authors="yeasy"
SHELL 指定執行shell命令的參數
SHELL ["可執行程序", "參數"]
SHELL ["/bin/sh", "-c"] RUN lll ; ls # 這里的shell命令將通過 /bin/sh -c 的方式執行
推薦學習:《dockerfile》