Dockerfile命令详解
使用docker就會(huì)避免不了的要做各種鏡像,就會(huì)用到dockerfile,記錄一下dockerfile的主要命令
1、主要組成部分
? ? dockerfile執(zhí)行build命令時(shí),是從上倒下依次執(zhí)行的,dockerfile的基本組成部分如下。
? ? ? ? ? ? 主要部分? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 代表性命令
? ? ? ? 基礎(chǔ)鏡像信息? ? ? ? ? ? ? ? ? ? ? FROM
? ? ? ? 維護(hù)者信息? ? ? ? ? ? ? ? ? ? ? ? ? MAINTAINER
? ? ? ? 鏡像操作指令? ? ? ? ? ? ? ? ? ? ? RUN、COPY、ADD、EXPOSE、WORKDIR、ONBUILD、USER、VOLUME、ENV等
? ? ? ? 容器啟動(dòng)時(shí)執(zhí)行指令? ? ? ? ? ?CMD、ENTRYPOINT
2、各命令詳解
?
FROM:指定基礎(chǔ)鏡像,必須為dockerfile中的第一個(gè)命令
格式:FROM <image>FROM <image>:<tag>FROM <image>@<digest> 示例:FROM mysql:5.6 注:tag或digest是可選的,如果不使用這兩個(gè)值時(shí),會(huì)使用latest版本的基礎(chǔ)鏡像?
MAINTAINER:?維護(hù)者信息
格式:MAINTAINER <name> 示例:MAINTAINER Jasper XuMAINTAINER sorex@163.comMAINTAINER Jasper Xu <sorex@163.com>?
?RUN:構(gòu)建鏡像時(shí)執(zhí)行的命令,一個(gè)文件中可以包含多個(gè)RUN命令
RUN用于在鏡像容器中執(zhí)行命令,有以下兩種命令執(zhí)行方式: shell執(zhí)行,即/bin/sh 格式:RUN <command> exec執(zhí)行 格式:RUN ["executable", "param1", "param2"]要注意的是,executable是命令,后面的param是參數(shù) 示例: RUN yum install -y nginx RUN ["yum", "install", "-y", "nginx"] 注:RUN指令創(chuàng)建的中間鏡像會(huì)被緩存,并會(huì)在下次構(gòu)建中使用。如果不想使用這些緩存鏡像,可以在構(gòu)建時(shí)指定--no-cache參數(shù),如:docker build --no-cache? ? ? ? 由于RUN命令會(huì)生成一個(gè)鏡像層,所以RUN并不是越多越好,需要合理使用,如果一個(gè)RUN中執(zhí)行多個(gè)命令,可以使用 && 連接,如果命令過長,可以使用 \ 換行,例如
RUN apt-get update && apt-get install -y \ bzr \cvs \git \mercurial \subversion并且這樣寫還有個(gè)優(yōu)點(diǎn),apt-get update 和 apt-get install 被放在一個(gè) RUN 指令中執(zhí)行,這樣能夠保證每次安裝的是最新的包。如果 apt-get install 在單獨(dú)的 RUN 中執(zhí)行,則會(huì)使用 apt-get update 創(chuàng)建的鏡像層,而這一層可能是很久以前緩存的?
ADD:將本地文件添加到容器中,tar類型文件會(huì)自動(dòng)解壓(網(wǎng)絡(luò)壓縮資源不會(huì)被解壓),可以訪問網(wǎng)絡(luò)資源,類似wget
如果目的位置不存在,Docker會(huì)自動(dòng)創(chuàng)建所需要的目錄結(jié)
格式:ADD <src>... <dest>ADD ["<src>",... "<dest>"] 用于支持包含空格的路徑 示例:ADD hom* /mydir/ # 添加所有以"hom"開頭的文件ADD hom?.txt /mydir/ # ? 替代一個(gè)單字符,例如:"home.txt"ADD test relativeDir/ # 添加 "test" 到 `WORKDIR`/relativeDir/ADD test /absoluteDir/ # 添加 "test" 到 /absoluteDir/注意:需要復(fù)制的本地文件一定要放在Dockerfile文件的同級目錄下原因:因?yàn)闃?gòu)建環(huán)境將會(huì)先上傳到Docker守護(hù)進(jìn)程,而復(fù)制是在Docker守護(hù)進(jìn)程中進(jìn)行的。任何位于構(gòu)建環(huán)境之外的東西都是不可用的。ADD指令的目的的位置則必須是容器內(nèi)部的一個(gè)絕對路徑。?
COPY:功能類似ADD,但是是不會(huì)自動(dòng)解壓文件,也不能訪問網(wǎng)絡(luò)資源
? ? ? ? 就是不能解壓,其他限制條件跟ADD一樣
?
WORKDIR:指定工作目錄,類似于cd命令,之后的命令都是基于此工作目錄
格式:WORKDIR /path/to/workdir 示例:WORKDIR /a (這時(shí)工作目錄為/a)WORKDIR b (這時(shí)工作目錄為/a/b)WORKDIR c (這時(shí)工作目錄為/a/b/c) 注:通過WORKDIR設(shè)置工作目錄后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都會(huì)在該目錄下執(zhí)行。在使用docker run運(yùn)行容器時(shí),可以通過-w參數(shù)覆蓋構(gòu)建時(shí)所設(shè)置的工作目錄。?
LABEL:用于為鏡像添加元數(shù)據(jù)
格式:LABEL <key>=<value> <key>=<value> <key>=<value> ... 示例:LABEL version="1.0" description="這是一個(gè)Web服務(wù)器" by="IT筆錄" 注:使用LABEL指定元數(shù)據(jù)時(shí),一條LABEL指定可以指定一或多條元數(shù)據(jù),指定多條元數(shù)據(jù)時(shí)不同元數(shù)據(jù)之間通過空格分隔。推薦將所有的元數(shù)據(jù)通過一條LABEL指令指定,以免生成過多的中間鏡像。?
ENV:設(shè)置環(huán)境變量
格式:ENV <key> <value> #<key>之后的所有內(nèi)容均會(huì)被視為其<value>的組成部分,因此,一次只能設(shè)置一個(gè)變量ENV <key>=<value> ... #可以設(shè)置多個(gè)變量,每個(gè)變量為一個(gè)"<key>=<value>"的鍵值對,如果<key>中包含空格,可以使用\來進(jìn)行轉(zhuǎn)義,也可以通過""來進(jìn)行標(biāo)示;另外,反斜線也可以用于續(xù)行 示例:ENV myName John DoeENV myDog Rex The DogENV myCat=fluffy?
EXPOSE:指定暴露鏡像的端口供主機(jī)做映射
格式:EXPOSE <port> [<port>...] 示例:EXPOSE 80 443EXPOSE 8080EXPOSE 11211/tcp 11211/udp 注:EXPOSE并不會(huì)讓容器的端口訪問到主機(jī)。要使其可訪問,需要在docker run運(yùn)行容器時(shí)通過-p來發(fā)布這些端口,或通過-P參數(shù)來發(fā)布EXPOSE導(dǎo)出的所有端口?
VOLUME:添加卷,用于指定持久化目錄
格式:VOLUME ["/path/to/dir"] 示例:VOLUME ["/data"]VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2" 注:一個(gè)卷可以存在于一個(gè)或多個(gè)容器的指定目錄,該目錄可以繞過聯(lián)合文件系統(tǒng),并具有以下功能: 1 卷可以容器間共享和重用 2 容器并不一定要和其它容器共享卷 3 修改卷后會(huì)立即生效 4 對卷的修改不會(huì)對鏡像產(chǎn)生影響 5 卷會(huì)一直存在,直到?jīng)]有任何容器在使用它?
USER:指定運(yùn)行容器時(shí)的用戶名或 UID,后續(xù)的操作都會(huì)使用指定用戶。使用USER指定用戶時(shí),可以使用用戶名、UID或GID,或是兩者的組合。當(dāng)服務(wù)不需要管理員權(quán)限時(shí),可以通過該命令指定運(yùn)行用戶。并且可以在之前創(chuàng)建所需要的用戶
格式:USER userUSER user:groupUSER uidUSER uid:gidUSER user:gidUSER uid:group示例:USER www注:使用USER指定用戶后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT都將使用該用戶。鏡像構(gòu)建完成后,通過docker run運(yùn)行容器時(shí),可以通過-u參數(shù)來覆蓋所指定的用戶。?
ARG:用于指定傳遞給構(gòu)建運(yùn)行時(shí)的變量
格式:ARG <name>[=<default value>] 示例:ARG siteARG build_user=www?
ONBUILD:用于設(shè)置鏡像觸發(fā)器
格式:ONBUILD [INSTRUCTION] 示例:ONBUILD ADD . /app/srcONBUILD RUN /usr/local/bin/python-build --dir /app/src 注:當(dāng)所構(gòu)建的鏡像被用做其它鏡像的基礎(chǔ)鏡像時(shí)(比如用戶的鏡像需要從某為準(zhǔn)備好的位置添加源代碼,或者用戶需要執(zhí)行特定于構(gòu)建鏡像的環(huán)境的構(gòu)建腳本),該鏡像中的觸發(fā)器將會(huì)被鑰觸發(fā)?
例如創(chuàng)建鏡像image-A
? FROM ubuntu
? ...
? ONBUILD ADD . /var/www
? ...
然后創(chuàng)建鏡像image-B,指定image-A為基礎(chǔ)鏡像,如
? FROM image-A
? ...
?
然后在構(gòu)建image-B的時(shí)候,日志上顯示如下:
? Step 0 : FROM image-A
? # Execting 1 build triggers
? Step onbuild-0 : ADD . /var/www
? ...
?
CMD:構(gòu)建容器后調(diào)用,也就是在容器啟動(dòng)時(shí)才進(jìn)行調(diào)用,存在多個(gè)CMD時(shí)只有最后一個(gè)生效,也支持exec語法。
格式:CMD ["executable","param1","param2"] (執(zhí)行可執(zhí)行文件,優(yōu)先)CMD ["param1","param2"] (設(shè)置了ENTRYPOINT,則直接調(diào)用ENTRYPOINT添加參數(shù))CMD command param1 param2 (執(zhí)行shell內(nèi)部命令) 示例:CMD echo "This is a test." | wc -CMD ["/usr/bin/wc","--help"] 注:CMD不同于RUN,CMD用于指定在容器啟動(dòng)時(shí)所要執(zhí)行的命令,而RUN用于指定鏡像構(gòu)建時(shí)所要執(zhí)行的命令。?
ENTRYPOINT:配置容器,使其可執(zhí)行化。配合CMD可省去"application",只使用參數(shù)。
格式:ENTRYPOINT ["executable", "param1", "param2"] (可執(zhí)行文件, 優(yōu)先)ENTRYPOINT command param1 param2 (shell內(nèi)部命令) 示例:FROM ubuntuENTRYPOINT ["top", "-b"]CMD ["-c"] 注:ENTRYPOINT與CMD非常類似,不同的是通過docker run執(zhí)行的命令不會(huì)覆蓋ENTRYPOINT,而docker run命令中指定的任何參數(shù),都會(huì)被當(dāng)做參數(shù)再次傳遞給ENTRYPOINT。Dockerfile中只允許有一個(gè)ENTRYPOINT命令,多指定時(shí)會(huì)覆蓋前面的設(shè)置,而只執(zhí)行最后的ENTRYPOINT指令。注意!!!! CMD和ENTRYPOINT的區(qū)別
? ? CMD和ENTRYPOINT同樣作為容器啟動(dòng)時(shí)執(zhí)行的命令,區(qū)別有以下幾點(diǎn):
? ? ? ? ? CMD的命令會(huì)被 docker run 的命令覆蓋而ENTRYPOINT不會(huì)
? ? ? ? ? 如使用CMD ["/bin/bash"]或ENTRYPOINT ["/bin/bash"]后,再使用docker run -ti image啟動(dòng)容器,它會(huì)自動(dòng)進(jìn)入容器內(nèi)部的交互終端,如同使用docker run -ti image /bin/bash。
? ? ? ? ? 但是如果啟動(dòng)鏡像的命令為docker run -ti image /bin/ps,使用CMD后面的命令就會(huì)被覆蓋轉(zhuǎn)而執(zhí)行bin/ps命令,而ENTRYPOINT的則不會(huì),而是會(huì)把docker run 后面的命令當(dāng)做ENTRYPOINT執(zhí)行命令的參數(shù)。
? ? ?放個(gè)例子
Dockerfile中為 ENTRYPOINT ["/user/sbin/nginx"]然后通過啟動(dòng)build之后的容器 docker run -ti image -g "daemon off"此時(shí)-g "daemon off"會(huì)被當(dāng)成參數(shù)傳遞給ENTRYPOINT,最終的命令變成了 /user/sbin/nginx -g "daemon off"如果Dockerfile中定義的是CMD,則會(huì)被覆蓋
CMD和ENTRYPOINT都存在時(shí),CMD的指令就變成了ENTRYPOINT的參數(shù),并且此CMD提供的參數(shù)也會(huì)被 docker run 后面的命令覆蓋
Dockerfile中指令 .. ENTRYPOINT ["echo","hello","i am"] CMD ["docker"]之后啟動(dòng)構(gòu)建之后的容器使用docker run -ti image 輸出“hello i am docker”使用docker run -ti image world 輸出“hello i am world”?
最后說一下docker build命令,Dockerfile寫完后要生產(chǎn)鏡像,就需要docker build
docker build?命令用于使用 Dockerfile 創(chuàng)建鏡像,語法
docker build [OPTIONS] PATH | URL |-參數(shù)說明:
-
--build-arg=[] :設(shè)置鏡像創(chuàng)建時(shí)的變量;
-
--cpu-shares :設(shè)置 cpu 使用權(quán)重;
-
--cpu-period :限制 CPU CFS周期;
-
--cpu-quota :限制 CPU CFS配額;
-
--cpuset-cpus :指定使用的CPU id;
-
--cpuset-mems :指定使用的內(nèi)存 id;
-
--disable-content-trust :忽略校驗(yàn),默認(rèn)開啟;
-
-f :指定要使用的Dockerfile路徑;
-
--force-rm :設(shè)置鏡像過程中刪除中間容器;
-
--isolation :使用容器隔離技術(shù);
-
--label=[] :設(shè)置鏡像使用的元數(shù)據(jù);
-
-m :設(shè)置內(nèi)存最大值;
-
--memory-swap :設(shè)置Swap的最大值為內(nèi)存+swap,"-1"表示不限swap;
-
--no-cache :創(chuàng)建鏡像的過程不使用緩存;
-
--pull :嘗試去更新鏡像的新版本;
-
--quiet, -q :安靜模式,成功后只輸出鏡像 ID;
-
--rm :設(shè)置鏡像成功后刪除中間容器;
-
--shm-size :設(shè)置/dev/shm的大小,默認(rèn)值是64M;
-
--ulimit :Ulimit配置。
-
--tag, -t:?鏡像的名字及標(biāo)簽,通常 name:tag 或者 name 格式;可以在一次構(gòu)建中為一個(gè)鏡像設(shè)置多個(gè)標(biāo)簽。
-
--network:?默認(rèn) default。在構(gòu)建期間設(shè)置RUN指令的網(wǎng)絡(luò)模式
示例
使用當(dāng)前目錄的 Dockerfile 創(chuàng)建鏡像,標(biāo)簽為 runoob/ubuntu:v1。 docker build -t runoob/ubuntu:v1 . 使用URL github.com/creack/docker-firefox 的 Dockerfile 創(chuàng)建鏡像。 docker build github.com/creack/docker-firefox也可以通過 -f Dockerfile 文件的位置: $ docker build -f /path/to/a/Dockerfile .在 Docker 守護(hù)進(jìn)程執(zhí)行 Dockerfile 中的指令前,首先會(huì)對 Dockerfile 進(jìn)行語法檢查,有語法錯(cuò)誤時(shí)會(huì)返回: $ docker build -t test/myapp . Sending build context to Docker daemon 2.048 kB Error response from daemon: Unknown instruction: RUNCMD?
轉(zhuǎn)載于:https://www.cnblogs.com/yanh0606/p/11360936.html
總結(jié)
以上是生活随笔為你收集整理的Dockerfile命令详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Proxy + Reflect 实
- 下一篇: 学习笔记94—所有用过SCI-hub的科