Dockerfile 文件學習(二) docker
(6)ADD(添加文件):ADD和COPY指令類似可是不一樣的是,ADD能夠從網上去添加文件或者是文件夾,就是從一個URL地址下載內容複製到容器文件系統中,還能夠將壓縮打包格式的文件解開後複製到指定的位置。 shell
ADD格式以下: ubuntu
ADD file /Images/path/file windows
ADD aaa.tar.gz /var/www/ 安全
在使用複製命令下,ADD構建鏡像的大小比COPY構建的鏡像要打,因此複製文件時儘可能推薦使用COPY。 網絡
(7)EXPOSE(指定端口暴露): app
EXPOSE指令以下: 工具
EXPOSE <端口>[<端口>…] 學習
EXPOSE指令用於標明這個鏡像中的應用將會偵聽某個端口,而且但願這個端口映射到主機的網絡界面上,可是爲了安全,docker run 命令若是沒有帶上響應的端口映射參數,docker並不會將端口映射出去。 ui
此外EXPOSE端口是能夠在多個容器之間通訊,經過--links 參數可讓多個容器經過端口鏈接在一塊兒。
(8)CMD(設置鏡像啓動命令):CMD提供了默認容器的執行命令。Dockerfile使用多個CMD會抵消以前全部的指令,只有最後一個指令生效。通常來講整個Dockerfile腳本的最後一條命令。當Dockerfile已經完成了全部的環境的安裝與配置,經過CMD指令來指示docker run 命令運行鏡像時要執行的命令。格式以下:
CMD ["executable","param1","param2"]
值得注意的是docker run 命令能夠覆蓋CMD命令,CMD與ENTRYPOINT的功能極爲類似。區別在於若是docker run後面出現了與CMD指定相同的命令,那麼CMD會被覆蓋;而ENTPYPOINT會把容器名後面的全部內容當作參數傳遞給其餘給其指定的命令(不會對命令覆蓋。另外,CMD指令還能夠當作是ENTPYPOINT指令的可選參數,共同組成一條完整的啓動命令。
讀這些若是有些模糊,不妨作作實驗:
Dockerfile以下:
FROM ubuntu
CMD ["echo","hello","world"]
而後開始構建,並運行容器:
[root@localhost ~]# docker build -t s8 . #-t s8 給鏡像打標籤S8
Sending build context to Docker daemon 1.127 MB
Step 1/2 : FROM ubuntu
---> cd6d8154f1e1
Step 2/2 : CMD echo hello world
---> Using cache
---> 8b4276f87c6c
Successfully built 8b4276f87c6c
[root@localhost ~]# docker run --rm s8 #運行鏡像
hello world
[root@localhost ~]# docker run s8 echo "hello docker" #再次運行
hello docker
[root@localhost ~]#
當使用docker run s6 echo 方式啓動容器時,echo "hello world"命令會覆蓋原有CMD指令。也就是說CMD指令能夠經過docker run命令覆蓋。這一點CMD和ENTRYPOINT最大的區別。
CMD和RUN 命令的區別在於,RUN是在build成鏡像時就運行,先於CMD和ENTRYPOINT,CMD會在每次啓動容器的時候運行,而RUN只在建立鏡像時執行一次。
固話在image中。
(9)ENTPYPOINT(設置接入點):
前面已經說到了這個命令與CMD類似。ENTPYPOINT至關於把鏡像變成了一個固定的命令工具,它通常是不能夠經過docker run
來改變的,而CMD不一樣,CMD是能夠經過啓動命令修改內容。兩者的主要區別經過實踐會體會得更清晰。
Dockerfile以下:
FROM ubuntu
ENTRYPOINT ["echo"]
[root@localhost ~]# docker build -t s9 . #建立鏡像。
Sending build context to Docker daemon 1.126 MB
Step 1/2 : FROM ubuntu
---> cd6d8154f1e1
Step 2/2 : ENTRYPOINT echo
---> Running in 44152f32f53c
---> 73ec7ef2bed4
Removing intermediate container 44152f32f53c
Successfully built 73ec7ef2bed4
[root@localhost ~]# docker run s9 'hello kubernetes' #啓動容器
hello kubernetes
[root@localhost ~]#
能夠看到 ,在ENTRYPOINT指令下,容器就行一個echo程序,docker run 後面的參數都成爲了echo的參數。
(10)VOLUME(設置數據卷):VOLUME指令用來向基於鏡像建立的容器添加數據卷(在一個容器內設置掛載點,能夠用來其餘容器掛載或讓宿主機訪問,以實現數據共享或對容器數據的備份,恢復或遷移).
數據卷能夠在容器間共享和重用。數據卷的修改是當即生效的。數據卷的修改不會對更新的鏡像產生影響。數據卷會一直存在,直到沒有任何容器使用它(沒有使用它,它也會在宿主機存在,但只不過是數據卷,和普通的文件沒有差別。)
VALUME指令使用:
VALUME ["/data","/data2"]
VALUME /data
VOLUME 能夠在docker run 中使用,若是run 命令中沒有使用,則不會在宿主機掛載這個數據卷。若是Dockerfile中沒有設置數據卷,在docker run 中也是能夠設置的,在Dockerfile中聲明數據卷有助於開發人員迅速定位須要保存的數據位置。
仍是來點實戰吧:
Dockerfile以下:
FROM ubuntu
RUN mkdir /app && echo "ello world"> /app/test.txt
VOLUME /home
CMD ["cat","/app/test.txt"]
[root@localhost ~]# docker build -t v99
Sending build context to Docker daemon 1.133 MB
Step 1/5 : FROM ubuntu
---> cd6d8154f1e1
Step 2/5 : RUN mkdir /app && echo 'hello world' > /app/test.txt
---> Running in dc47839b405e
---> 70ce3ce074eb
Removing intermediate container dc47839b405e
Step 3/5 : VOLUME /root
---> Running in deaad1ac5b3c
---> a4fed2b1608f
Removing intermediate container deaad1ac5b3c
Step 4/5 : CMD cat /app/test.txt
---> Running in aa7a3f2cf313
---> 476e20f1555a
Removing intermediate container aa7a3f2cf313
Step 5/5 : ENTRYPOINT echo
---> Running in 42f65c7980c4
---> cf5f06e79508
Removing intermediate container 42f65c7980c4
Successfully built cf5f06e79508
[root@localhost ~]#
[root@localhost ~]# docker run --rm v99
hello world
(11)USER(設置構建用戶):
USER指令以下:
USER user
USER user:group
USER uid:gid
USER指定能夠在docker run 命令中經過-u選項來覆蓋。這條指令應用場景在於,當服務不須要管理員權限時能夠經過命令指定運行用戶。指定的用戶須要在USER指令建立以前建立
EL:
RUN groupadd ——人newusereyuser&& useradd –r –g newuser newuser
(12)WORKDIR(設置工做目錄)
WORKDIR命令指定RUN CMD與ENTPOINT命令的工做目錄。
語法以下:
WORKDIR /path/to/workdir
一樣docker run –w 能夠運行時覆蓋指令指定的目錄
此外可使用多個WORKDIR指令,後續的命令參數若是是相對路徑。
(13)ONBUILD指令(設置二次構建指令)
ONBUILD指定在構建鏡像時並不執行,而是在它的子鏡像中執行。
說的很抽象。來個實戰試一試:
Dockerfile以下:
[root@localhost ~]# docker build -t c99 .
Sending build context to Docker daemon 1.132 MB
Step 1/2 : FROM busybox
Trying to pull repository docker.io/library/busybox ...
latest: Pulling from docker.io/library/busybox
Digest: sha256:cb63aa0641a885f54de20f61d152187419e8f6b159ed11a251a09d115fdff9bd
Status: Downloaded newer image for docker.io/busybox:latest
---> e1ddd7948a1c
Step 2/2 : ONBUILD run echo "you won't see me until later"
---> Running in 833de3bbf044
---> 09eadbfd18fa
Removing intermediate container 833de3bbf044
Successfully built 09eadbfd18fa
第二個Dockerfile以下:
FROM c99
[root@localhost ~]# docker build -t c88 .
Sending build context to Docker daemon 1.132 MB
Step 1/1 : FROM c99
# Executing 1 build trigger...
Step 1/1 : RUN echo "you won't see me until later"
---> Running in 5a982a7ab862
you won't see me until later
---> 436765d746f5
Removing intermediate container 5a982a7ab862
Successfully built 436765d746f5
能夠看到第一次建立中ONBUILD的指令沒有被執行,第二次被執行了。ONBUILD後面是不能跟FROM和MAINTAINER指令。
14.LABEL(設置元數據):LABEL指令添加元數據到鏡像,每一個標籤會生成一個layer。儘可能使用一個LABEL標籤。
LABEL multi.label1="value1" multi.label2="value2" multi.label3="value3"
或者LABEL multi.label1="value1" \
multi.label2="value2" \
multi.label3="value3"
15ARG.(構建環境變量)
ARG指令定義了一個變量,用戶能夠在構建時使用,效果和docker build –build-arg <varname>=<value>同樣,能夠在構建時設定參數,這個參數只會在構建時存在。與ENV類似,不一樣的是ENV會在鏡像構建結束以後依舊存在鏡像中,而AGR不會。
16.STOPSIGNAL:設置中止信號
STOPSIGNAL指令容許用戶定製化運行docker stop時的信號。
STOPSIGNAL SIGKILL
基於這種方式構建的鏡像,其啓動的容器在中止時會發出SIGKILL信號,這個指令適用於一些不能接受正常退出信號的容器。
17.HEALTHCHECK:檢查鏡像狀態
這個是一個健康檢查指令,用來檢查將容器啓動運行時是否正常。正常則會返回healthy,不然unhealthy。:
HEALTHCHECK [OPTIONS] CMD command
參數有3個:
--interval=DURATION(默認30秒)
2.設置超時時間,超過這個時間不返回信息,表示容器異常。
--timeout=DURATION(默認30秒)
3.設置重試次數
--retries=N
18.SHELL:(設置命令執行的環境)
Docker構建過程當中,默認會使用/bin/sh做爲shell環境。Windows下構建默認使用cmd做爲shell環境,可是有時須要在其餘shell環境中執行RUN的內容。這時就須要SHELL指令提醒Docker更換shell環境。
El:在windows環境下跟環powershell做爲默認shell
SHELL ["powershell","-command"]