1 概述html
基於容器製做鏡像的問題是,每次都要啓動一個容器,在容器內部執行相關命令,才進行製做容器,這個比較麻煩。還有一種狀況,多是製做後的容器,容器變得很龐大,用戶拷貝也可能成問題,若是經過dockerfile,至關因而一個文檔,客戶能夠基於dockerfile生成新的容器nginx
dockerfile僅僅是用來製做鏡像的源碼文件,是構建容器過程當中的指令,docker可以讀取dockerfile的指定進行自動構建容器,基於dockerfile製做鏡像,每個指令都會建立一個鏡像層,即鏡像都是多層疊加而成,所以,層越多,效率越低,建立鏡像,層越少越好。所以能在一個指令完成的動做盡可能經過一個指令定義。docker
docker鏡像製做的工做邏輯shell
首先須要有一個製做鏡像的目錄,該目錄下有個文件,名稱必須爲Dockerfile,Dockerfile有指定的格式,#號開頭爲註釋,,指定默認用大寫字母來表示,以區分指令和參數,docker build讀取Dockerfile是按順序依次Dockerfile裏的配置,且第一條非註釋指令必須是FROM 開頭,表示基於哪一個基礎鏡像來構建新鏡像。能夠根據已存在的任意鏡像來製做新鏡像。apache
Dockerfile可使用環境變量,用ENV來定義環境變量,變量名支持bash的變量替換,如${variable:-word},表示若是變量值存在,就使用原來的變量,變量爲空時,就使用word的值做爲變量的值,通常使用這個表示法。ubuntu
${variable:+word},表示若是變量存在了,不是空值,那麼變量將會被賦予爲word對應的值,若是變量爲空,那麼依舊是空值vim
.dcokerignore:把文件路徑寫入到.dockerignore,對應的路徑將不會被打包到新鏡像centos
FROM 數組
FROM指令是最重的一個且必須爲 Dockerfile文件開篇的第一個非註釋行,用於爲映像文件構建過程指定基準鏡像,後續的指令運行於此基準鏡像所提供的運行環境 .緩存
實踐中,基準鏡像能夠是任何可用鏡像文件,默認狀況下, docker build會在 docker主機上查找指定的鏡像文件,在其不存在時,則會從 Docker Hub Registry上拉取所需的鏡像文件 .若是找不到指定的鏡像文件, docker build會返回一個錯誤信息
FROM 語法
FROM <repository>[:<tag>] 或者 FROM <repository>@<digest>
<repository>:指定做爲base image的名稱
<tag>:base image的標籤,爲可選項,省略時默認爲 latest;
<digest>爲校驗碼
MAINTANIER
用於讓鏡像製做者提供本人的詳細信息
Dockerfile並不限制 MAINTAINER指令可在出現的位置,但推薦將
其放置於 FROM指令以後 .
語法:
MAINTAINER <authtor's detail> l <author's detail>但是任何文本信息,但約定俗成地使用做者名稱及郵件地址,如
MAINTAINER "sunny <sunny@ghbsunny.cn>"
通常把MAINTAINER放在FROM後面
COPY
用於從 Docker主機複製文件至建立的新映像文件
語法
COPY <src> ... <dest>或 . COPY ["<src>",... "<dest>"]
<src>:要複製的源文件或目錄,支持使用通配符
<dest>:目標路徑,即正在建立的 image的文件系統路徑;建議爲 <dest>使用絕對路徑,<dest>絕對路徑爲鏡像中的路徑,而不是宿主機的路徑。不然, COPY指定則以 WORKDIR爲其起始路徑
注意:在路徑中有空白字符時,一般使用第二種格式 .
文件複製準則
<src>必須是build上下文中的路徑,即只能放在workshop這個工做目錄下,不能是其父目錄中的文件
若是<src>是目錄,其內部文件或者子目錄會被遞歸複製,但<src>目錄自身不會被複制
若是指定了多個<src>,或在<src>中使用了通配符,則<dest>必須是一個目錄,且dest目錄必須以/結尾
若是<dest>事先不存在,它將會被自動建立,這包括其父目錄路徑
copy是指在當前的workshop工做目錄中,準備好要添加到新鏡像的文件放到這個workshop下面,copy過程實際是基於dockerfile在後臺啓動一個容器,把工做目錄當作卷掛載到後臺啓動的容器,而後再把這些準備好的文件(workshop目錄下)拷貝到後臺容器,而後基於這個容器製做新鏡像,因此,鏡像的製做過程是基於指定的鏡像來製做
例子
建立一個目錄workshop,在該目錄下新建index.html文件用於鏡像製做的素材文件,在workshop下新建Dockerfile文件,把index.html拷貝到新鏡像裏
[root@docker ~]# mkdir workshop [root@docker ~]# cd workshop/ [root@docker workshop]# vim index.html [root@docker workshop]# vim Dockerfile FROM busybox:1.27.2 MAINTAINER "sunny <sunny@ghbsunny.cn>" COPY index.html /data/htdocs/ COPY yum.repos.d /etc/yum.repos.d/
Dockerfile製做完成後,用命令build製做基於dockerfile的新鏡像。命令以下
[root@docker workshop]# docker build -t sunnydocker01:v1 ./
查看
docker images
查看到生成了一個新鏡像sunnydocker01
啓動新生成的鏡像,在容器內部有目錄/data/htdocs,而且有文件index.html,且成功拷貝/etc/yum.repos.d這個目錄到新鏡像中
[root@docker workshop]# docker run -it --rm --name sunny01 sunnydocker01:v1
/ # ls
bin data dev etc home proc root sys tmp usr var
/ # ls data/htdocs/
index.html
/ # ls /etc/yum.repos.d/
CentOS-Base.repo docker-ce.repo epel.repo
bak/ epel-testing.repo sunny.repo
/ # ls /etc/yum.repos.d/
ADD
ADD指令相似於 COPY指令, ADD支持使用 TAR文件和 URL路徑
語法
. ADD <src> ... <dest>或
. ADD ["<src>",... "<dest>"]
.操做準則 .
同COPY指令的4點準則
若是<src>爲URL且<dest>不以/結尾,則<src>指定的文件將被下載並直接被建立爲<dest>;若是<dest>以/結尾,則文件名URL指定的文件將被直接下載,並保存爲<dest>/<filename>,注意,URL不能是ftp格式的url
若是<src>是一個本地系統上的壓縮格式的tar文件,它將被展開爲一個目錄,其行爲相似於「tar -x」命令,而後,經過URL獲取到的tar文件將不會自動展開
若是<src>有多個,或其間接或直接使用了通配符,則<dest>必須是一個以/結尾的目錄路徑;若是<dest>不以/結尾,則其被視做一個普通文件,<src>的內容將被直接寫入到<dest>;
例子
在workshop目錄下,準備了apache-tomcat-8.0.47.tar.gz 這個tar包,已經從網絡上下載一個包,Dockerfile路徑以下
[root@docker workshop]# vim Dockerfile
FROM busybox:1.27.2
MAINTAINER "sunny <sunny@ghbsunny.cn>"
COPY index.html /data/htdocs/
COPY yum.repos.d /etc/yum.repos.d/
ADD http://nginx.org/download/nginx-1.14.0.tar.gz /tmp
ADD apache-tomcat-8.0.47.tar.gz /app/tomcat/
製做鏡像
[root@docker workshop]# docker build -t test02:v1 ./
基於新鏡像啓動容器,並檢查
[root@docker workshop]# docker run -it --rm --name testadd test02:v1
/ # ls
app bin data dev etc home proc root sys tmp usr var
/ # ls /tmp/
nginx-1.14.0.tar.gz
/ # ls /app/tomcat/
apache-tomcat-8.0.47
/ #
注意,此時url對應的nginx已經被下載到/tmp下,且這個nginx的tar包不會被展開,同時目錄/app/tomcat/下有一個tomcat目錄,爲apache-tomcat-8.0.47.tar.gz 展開的目錄
WORKDIR
workdir爲工做目錄,指當前容器環境的工做目錄,用於爲 Dockerfile中全部的 RUN、CMD、ENTRYPOINT、COPY和 ADD指定設定工做目錄
語法
WORKDIR <dirpath>
在Dockerfile文件中, WORKDIR指令可出現屢次,其路徑也能夠爲相對路徑,不過,其是相對此前一個 WORKDIR指令指定的路徑
另外, WORKDIR也可調用由 ENV指定定義的變量 .例如
WORKDIR /var/log
WORKDIR $STATEPATH
例子
指定workdir爲/usr/local,至關因而容器啓動後,會把工做目錄切換到/usr/local這個workdir路徑下,而不是默認的根目錄,以下例子,則相對路徑 ./src/ 的絕對路徑爲容器的/usr/local/src,製做鏡像時,把nginx包拷貝到/usr/local/src,把tomcat包解壓到/usr/local/src下面
[root@docker workshop]# vim Dockerfile
FROM busybox:1.27.2
MAINTAINER "sunny <sunny@ghbsunny.cn>"
WORKDIR "/usr/local"
ADD http://nginx.org/download/nginx-1.14.0.tar.gz ./src/
ADD apache-tomcat-8.0.47.tar.gz ./
啓動容器並檢查
[root@docker workshop]# docker run -it --rm --name testworkdir testworkdir:v1
/usr/local # ls
apache-tomcat-8.0.47 src
/usr/local # ls src
nginx-1.14.0.tar.gz
/usr/local #
容器啓動後,工做路徑直接切換爲/usr/local
VOLUME
定義卷,只能是docker管理的卷,,VOLUME爲容器上的目錄,用於在 image中建立一個掛載點目錄,以掛載 Docker host上的卷或其它容器上的卷
語法
. VOLUME <mountpoint>或
. VOLUME ["<mountpoint>"]
若是掛載點目錄路徑下此前在文件存在, docker run命令會在卷掛載完成後將此前的全部文件複製到新掛載的卷中
例子
[root@docker workshop]# vim Dockerfile
FROM busybox:1.27.2
MAINTAINER "sunny <sunny@ghbsunny.cn>"
VOLUME "/test/htdocs"
COPY index.html /test/htdocs/
製做鏡像
[root@docker workshop]# docker build -t testvolume:v1
啓動鏡像
[root@docker workshop]# docker run -it --rm --name testvolume1 testvolume:v1
/ # ls
bin dev etc home proc root sys test tmp usr var
/ # ls /test/htdocs/
index.html
/ #
在另外的窗口檢查該容器掛載的卷
[root@docker workshop]# docker inspect -f {{.Mounts}} testvolume1
[{volume e87fdd9ab3b8037167e23edb5c4eae3cc7c5d5ffa63c7a4fa4c18173e0e06460 /var/lib/docker/volumes/e87fdd9ab3b8037167e23edb5c4eae3cc7c5d5ffa63c7a4fa4c18173e0e06460/_data /test/htdocs local true }]
[root@docker workshop]# cd /var/lib/docker/volumes/e87fdd9ab3b8037167e23edb5c4eae3cc7c5d5ffa63c7a4fa4c18173e0e06460/_data
[root@docker _data]# ls
index.html
[root@docker _data]# cat index.html
hello,this is first container made by sunny~
[root@docker _data]#
EXPOSE
暴露指定端口,用於爲容器打開指定要監聽的端口以實現與外部通訊
語法
EXPOSE <port>[/<protocol>] [<port>[/<protocol>] ...] l
其中<protocol>用於指定傳輸層協議,可爲 tcp或udp兩者之一,默認爲 TCP協議
EXPOSE指令可一次指定多個端口,可是不能指定暴露爲宿主機的指定端口,由於指定的宿主機端口可能已經被佔用,所以這裏使用隨機端口,例如
. EXPOSE 11211/udp 11211/tcp
例子
[root@docker workshop]# vim Dockerfile
FROM busybox:1.27.2
MAINTAINER "sunny <sunny@ghbsunny.cn>"
VOLUME "/data/htdocs"
COPY index.html /data/htdocs/
EXPOSE 80/tcp
製做鏡像
[root@docker workshop]# docker build -t testexpose:v1 ./
啓動並暴露端口,注意,啓動容器要跟大寫P選項-P來暴露
[root@docker workshop]# docker run -it -P --rm --name testexpose testexpose:v1
/ # ls
bin data dev etc home proc root sys tmp usr var
/ # ls data/htdocs/
index.html
/ #
在其餘端口檢查80口是否有暴露
[root@docker _data]# docker port testexpose
80/tcp -> 0.0.0.0:32768
[root@docker _data]#
ENV
ENV用於爲鏡像定義所需的環境變量,並可被 Dockerfile文件中位於其後的其它指令(如 ENV、ADD、COPY等)所調用 ,即先定義後調用
調用格式爲 $variable_name或${variable_name}
語法
ENV <key> <value>或 . ENV <key>=<value> ... .
第一種格式中, <key>以後的全部內容均會被視做其 <value>的組成部分,所以一次只能設置一個變量
第二種格式,可用一次設置多個變量,每一個變量爲一個「<key>=<value>」的鍵值對,若是<value>包含空格,能夠以反斜線(\)進行轉義,也可經過對<value>加引號進行標識;另外反斜線也能夠用於續行;
.定義多個變量時,建議使用第二種方式,以便在同一層中完成全部功能
例子
下載一個nginx包,其中nginx的版本和nginx包的路徑用變量替換
編輯Dockerfile
vim Dockerfile
FROM busybox:1.27.2
MAINTAINER "sunny <sunny@ghbsunny.cn>"
ENV nginx_ver=1.14.0
ENV nginx_url=http://nginx.org/download/nginx-${nginx_ver}.tar.gz
ADD ${nginx_url} /usr/local/
建立鏡像
[root@docker workshop]# docker build -t testenv:v1 ./
運行容器並驗證
[root@docker workshop]# docker run -it --rm --name testenv testenv:v1
/ # ls /usr/local/
nginx-1.14.0.tar.gz
/ #
有些變量在運行爲容器時依然有用,所以須要把那些變量在運行爲容器時從新定義爲一個新的值,若是變量不少,能夠放到一個文件中進行定義,使用參數 --env-list實現,經過文件來加載環境變量
RUN
RUN用於指定 docker build過程當中運行的程序,其能夠是任何命令,可是這裏有個限定,通常爲基礎鏡像能夠運行的命令,如基礎鏡像爲centos,安裝軟件命令爲yum而不是ubuntu裏的apt-get命令
RUN和CMD均可以改變容器運行的命令程序,可是運行的時間節點有區別,RUN表示在docker build運行的命令,而CMD是將鏡像啓動爲容器運行的命令。由於一個容器正常只用來運行一個程序,所以CMD通常只有一條命令,若是CMD配置多個,則只有最後一條命令生效。而RUN能夠有多個。
語法
RUN <command>或 . RUN ["<executable>", "<param1>", "<param2>"]
第一種格式中,<command>一般是一個shell命令,且以「/bin/sh -c」做爲父進程來運行它,這意味着此進程在容器中的PID不爲1,不能接收Unix信號,所以,當使用 docker stop <container>命令中止容器時,此進程接收不到SIGTERM信號;
第二種語法格式中的參數是一個JSON格式的數組,其中<executable>爲要運行的命令,後面的<paramN>爲傳遞給命令的選項或參數;然而,此種格式指定的命令不會以「/bin/sh -c」來發起,表示這種命令在容器中直接運行,不會做爲shell的子進程,所以常見的shell操做如變量替換以及通配符(?,*等)替換將不會進行,不過,若是要運行的沒能力依賴此shell特性的話,能夠將其替換爲相似下面的格式
RUN ["/bin/bash","-C","<executable>","<paraml>"]
例子
把下載的nginx打包文件,用RUN命令來展開
編輯dockerfile
vim Dockerfile
FROM busybox:1.27.2
MAINTAINER "sunny <sunny@ghbsunny.cn>"
ENV nginx_ver=1.14.0
ENV nginx_url=http://nginx.org/download/nginx-${nginx_ver}.tar.gz
WORKDIR "/usr/local/src"
ADD ${nginx_url} /usr/local/src/
RUN tar xf nginx-${nginx_ver}.tar.gz
建立鏡像
[root@docker workshop]# docker build -t testrun ./
運行容器並驗證
[root@docker workshop]# docker run -it --rm --name testrun testrun:latest
/usr/local/src # ls
nginx-1.14.0 nginx-1.14.0.tar.gz
/usr/local/src #
若是RUN的命令不少,就用&&符號鏈接多個命令,少構建鏡像層,提升容器的效率
例子以下
基礎鏡像爲centos,RUN多個命令
因爲安裝是到互聯網上的倉庫進行安裝,因此,建議把centos的yum源配置爲本地,即建立鏡像時,把yum的配置有本地倉庫源配置在CentOS-Base.repo文件放在workshop下面,配置文件配置ADD拷貝一份到新建鏡像的/etc/yum.repos.d目錄下,由於常常默認會優先加載CentOS-Base.repo下的包,可是不建議使用這個方法,除非本地倉庫有足夠的包解決依賴關係,不然建議僅使用默認的便可
編輯dockerfile
[root@docker workshop]# vim Dockerfile
FROM centos:7.3.1611
MAINTAINER "sunny <sunny@ghbsunny.cn>"
ENV nginx_ver=1.14.0
ENV nginx_url=http://nginx.org/download/nginx-${nginx_ver}.tar.gz
WORKDIR "/usr/local/src"
ADD CentOS-Base.repo /etc/yum.repos.d/
ADD ${nginx_url} /usr/local/src/
RUN tar xf nginx-${nginx_ver}.tar.gz && yum -y install gcc pcre-devel openssl-devel make \
&& cd nginx-${nginx_ver} && ./configure && make && make install
建立鏡像
[root@docker workshop]# docker build -t nginx:v1 ./
運行容器,啓動nginx進程
[root@docker workshop]# docker build -t testexpose:v1 ./cc^C
[root@docker workshop]# docker run -it --rm --name nginxv1 nginx:v1
[root@ccedfdf5e63f src]# /usr/local/nginx/sbin/nginx
此時,nginx進程運行於後臺,不建議這麼作,由於容器的進程要運行於前臺模式,不然容器會終止,nginx運行於前臺,須要在nginx的配置文件nginx.conf裏添加配置項
vi /usr/local/nginx/conf/nginx.conf
daemon off;
這樣使得nginx運行於前臺
再次運行nginx,則運行於前臺
或者經過-g選項,在運行nginx的全局配置模式以後再運行某些參數,注意off後面的冒號
[root@ccedfdf5e63f local]# /usr/local/nginx/sbin/nginx -g "daemon off;"
CMD
相似於 RUN指令, CMD指令也可用於運行任何命令或應用程序,不過,兩者的運行時間點不一樣 . RUN指令運行於映像文件構建過程當中,而 CMD指令運行於基於 Dockerfile構建出的新映像文件啓動一個容器時 . CMD指令的首要目的在於爲啓動的容器指定默認要運行的程序,且其運行結束後,容器也將終止;不過, CMD指定的命令其能夠被 docker run的命令行選項所覆蓋 .在Dockerfile中能夠存在多個 CMD指令,但僅最後一個會生效
語法
CMD <command>或
CMD ["<executable>","<param1>","<param2>"]或
CMD["<param1>","<param2>"]
.前兩種語法格式的意義同 RUN
.第三種則用於爲 ENTRYPOINT指令提供默認參數
例子
編譯安裝nginx,並將鏡像的默認命令修改成nginx啓動於前臺,暴露80口
編輯dockerfile
vim Dockerfile
FROM centos:7.3.1611
MAINTAINER "sunny <sunny@ghbsunny.cn>"
ENV nginx_ver=1.14.0
ENV nginx_url=http://nginx.org/download/nginx-${nginx_ver}.tar.gz
WORKDIR "/usr/local/src"
EXPOSE 80/tcp
ADD ${nginx_url} /usr/local/src/RUN tar xf nginx-${nginx_ver}.tar.gz && yum -y install gcc pcre-devel openssl-devel make \
&& cd nginx-${nginx_ver} && ./configure && make && make install
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
製做鏡像
[root@docker workshop]# docker build -t nginx:v3 ./
啓動容器並測試
[root@docker workshop]# docker run -it --rm --name nginxv3 nginx:v3
測試,容器的ip 爲 172.17.0.2,獲得nginx的測試頁
[root@docker yum.repos.d]# curl 172.17.0.2
查看容器80口被暴露爲哪一個口
[root@docker yum.repos.d]# docker port nginxv3
80/tcp -> 0.0.0.0:32772
[root@docker yum.repos.d]# curl 10.10.10.72:32772
注意,CMD在dockerfile裏寫的命令,若是啓動容器的命令行裏執行命令,則會把dockerfile裏的命令覆蓋掉,以下,容器啓動後,執行/bin/bash,而不是啓動nginx於前臺
[root@docker workshop]# docker run -it --rm -P --name nginxv3 nginx:v3 /bin/bash
[root@5f2f4b930df3 src]# ss -ntlp
若是dockerfile指定的CMD不容許覆蓋,則使用ENTRYPOINT
ENTRYPOINT
相似 CMD指令的功能,用於爲容器指定默認運行程序,從而使得容器像是一個單獨的可執行程序
與CMD不一樣的是,由 ENTRYPOINT啓動的程序不會被 docker run命令行指定的參數所覆蓋,並且,這些命令行參數會被看成參數傳遞給 ENTRYPOINT指定指定的程序 .不過, docker run命令的 --entrypoint選項的參數可覆蓋 ENTRYPOINT指令指定的程序
語法
ENTRYPOINT <command>
ENTRYPOINT ["<excutable>","<param1>","<param2>"]
docker run 命令傳入的命令參數會覆蓋CMD指令的內容而且附加到ENTRYPOINT命令最後作爲其參數使用 . Dockerfile文件中也能夠存在多個 ENTRYPOINT指令,但僅有最後一個會生效
例子
把上例中的CMD執行命令,改爲ENTRYPOINT
vim Dockerfile
FROM centos:7.3.1611
MAINTAINER "sunny <sunny@ghbsunny.cn>"
ENV nginx_ver=1.14.0
ENV nginx_url=http://nginx.org/download/nginx-${nginx_ver}.tar.gz
WORKDIR "/usr/local/src"
EXPOSE 80/tcp
ADD ${nginx_url} /usr/local/src/
RUN tar xf nginx-${nginx_ver}.tar.gz && yum -y install gcc pcre-devel openssl-devel make \
&& cd nginx-${nginx_ver} && ./configure && make && make install
ENTRYPOINT ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
製做鏡像
[root@docker workshop]# docker build -t nginx:v5 ./
因爲此次鏡像修改相比上次不多,只差了一層CMD,構建過程直接使用緩存,因此速度很快,dockerfile裏,建議CMD和ENTRYPOINT不用複用,兩者選其一,除非明確指定CMD裏的命令參數會被ENTRYPOINT當作參數執行
啓動容器
run命令不帶其餘命令
[root@docker workshop]# docker run -it --rm -P --name nginxv3 nginx:v5
直接啓動,能夠正常啓動nginx,並暴露端口
run命令修改默認命令如/bin/bash,與上例CMD不同,此時報選項錯誤,由於此時會把 /bin/bash當作參數傳遞給ENTRYPOINT指定的指令,此時ENTRYPOINT指定的指令爲啓動nginx,不能識別/bin/bash
[root@docker workshop]# docker run -it --rm -P --name nginxv3 nginx:v5 /bin/bash
nginx: invalid option: "/bin/bash"
[root@docker workshop]#
可是,若是必定要覆蓋dockerfile裏指定的ENTRYPOINT命令,那麼在run命令使用參數--entrypoint來覆蓋,以下
[root@docker workshop]# docker run -it --rm -P --name nginxv3 --entrypoint /bin/bash nginx:v5
[root@4c940d422f20 src]# pwd
/usr/local/src
[root@4c940d422f20 src]#
成功以進程/bin/bash啓動了容器,覆蓋了dockerfile裏設定的nginx啓動命令
USER
USER用於指定運行 image時的或運行 Dockerfile中任何 RUN、CMD或 ENTRYPOINT指令指定的程序時的用戶名或 UID ,即改變容器中運行程序的身份
.默認狀況下, container的運行身份爲 root用戶
語法
USER <UID>|<UserName>
須要注意的是, <UID>能夠爲任意數字,但實踐中其必須爲 /etc/passwd中某用戶的有效 UID,不然, docker run命令將運行失敗
ONBUILD
ONBUILD 用於在 Dockerfile中定義一個觸發器 . 用來指定運行docker指令
Dockerfile用於 build映像文件,此映像文件亦可做爲 base image被另外一個 Dockerfile用做 FROM指令的參數,並以之構建新的映像文件
.在後面的這個 Dockerfile中的 FROM指令在 build過程當中被執行時,將會 「觸發 」建立其 base image的Dockerfile文件中的 ONBUILD指令定義的觸發器
語法
ONBUILD <INSTRUCTION>
儘管任何指令均可註冊成爲觸發器指令,可是ONBUILD不能自我嵌套,且不會觸發FROM和MAINTAINER指令
使用包含ONBUILD指令的Dockerfile構建的鏡像應該使用特殊的標籤,例如 ruby:2.0-onbuild
在ONBUILD指令中使用ADD或COPY指令應該格外當心,由於新構建過程的上下文在缺乏指定的源文件時會失敗
ONBUILD 在構建鏡像時不會運行,是別人基於這個鏡像做爲基礎鏡像構建時,纔會運行
以下例子
增長一個ONBUILD命令,執行RUN
FROM centos:7.3.1611
MAINTAINER "sunny <sunny@ghbsunny.cn>"
ENV nginx_ver=1.14.0
ENV nginx_url=http://nginx.org/download/nginx-${nginx_ver}.tar.gz
WORKDIR "/usr/local/src"
EXPOSE 80/tcp
ADD ${nginx_url} /usr/local/src/
RUN tar xf nginx-${nginx_ver}.tar.gz && yum -y install gcc pcre-devel openssl-devel make \
&& cd nginx-${nginx_ver} && ./configure && make && make install
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
ONBUILD RUN echo -e "\nSunny do an onbuild~\n" >> /etc/issue
構建鏡像
[root@docker workshop]# docker build -t nginx:v6 ./
基於nginx:v6啓動容器,此時/etc/issue還沒寫入echo要插入的信息
[root@docker workshop]# docker run -it --rm -P --name nginxv3 nginx:v6 /bin/bash
[root@16e90f7a6460 src]# cat /etc/issue
\S
Kernel \r on an \m
[root@16e90f7a6460 src]#
而後基於這個nginx:v6鏡像,再次製做一個新鏡像,編輯一個新的Dockerfile
[root@docker ~]# mkdir nginxv7
[root@docker ~]# cd nginxv7/
[root@docker nginxv7]# vim Dockerfile
FROM nginx:v6
MAINTAINER "sunny <sunny@ghbsunny.cn>"
CMD "/bin/bash"
構建鏡像,注意,會提示執行一個build trigger,以下Executing 1 build trigger
[root@docker nginxv7]# docker build -t nginx:v7 ./
Sending build context to Docker daemon 2.048kB
Step 1/3 : FROM nginx:v6
# Executing 1 build trigger
---> Running in 6bb18c52af99
Removing intermediate container 6bb18c52af99
基於新鏡像nginx:v7啓動新容器nginxv7
[root@docker nginxv7]# docker run -it --rm --name nginxv7 nginx:v7
[root@becc66948713 src]# cat /etc/issue
\S
Kernel \r on an \m
Sunny do an onbuild~
[root@becc66948713 src]#
此時,在舊的鏡像中的dockerfile裏的ONBUILD已經觸發,把信息寫入到/etc/issue裏
LABEL
LABEL爲磁盤映像文件添加元數據,能夠基於這個LABEL調用這些元數據,一個LABEL就是一堆k/v值,一個鏡像文件能夠有多個LABEL