FROM 指定鏡像
功能為指定基礎鏡像,并且必須是第一條指令,
如果不以任何鏡像為基礎,那么寫法為: FROM scratch
同時意味著接下來所寫的指令作為鏡像的第一層開始
語法:
FROM <image>
FROM <image>:<tag>
FROM <image>:<digest>
三種寫法,其中<tag>和<digest>是可選項,如果沒有那么默認值為latest
例如:
FRPM centos:7.4 #當你在撰寫Dockerfile檔案時,第一行必須是FROM指令,也可以這么寫
#FROM scratch 這個代表從零開始構建 就是不在鏡像基礎上構建鏡像而且從0開始構建鏡像
MAINTAINER alex-wang wangwenchao_wwc@163.com
LABEL name="Centos Base Image" \ #LABEL 給鏡像指定標簽
vendor="Centos" \
license="GPLv2"
build-date="2021-8-9"
RUN 構建時間運行命令
功能為運行指定命令
RUN命令有兩種格式
- RUN <command>
- RUN ["executable","param1","param2"]
第一種后面直接跟shell命令
在linux作業系統上默認/bin/sh -c
在windows作業系統上默認 cmd /S /C
第二種是類似于函式呼叫,
可將executable理解成為可執行檔案,后面就是兩個引數,
兩種寫法對比:
RUN source $HOME/.bashrc ; echo $HOME
RUN ["/bin/bash","-c","ehco hello"]
注意: 多行命令不要寫多個RUN,原因是Docker中每一個指令都會建立一個層多少RUN就構建多少層鏡像,會造成鏡像的臃腫,多層, 不僅僅增加了構建部署的時間,還容易出錯,
RUN書寫時的換行符是\
RUN的三種書寫方式
FROM centos:7.4
MAINTAINER alex-wang wangwenchao_wwc@163.com
LABEL name="Centos Base Iamge" \
vendor="Centos" \
license="GPLv2"
build-date="2021-8-9"
RUN yum -y install net-tools
FROM centos:7.4
MAINTAINER alex-wang wangwenchao_wwc@163.com
LABEL name="Centos Base Iamge" \
vendor="Centos" \
license="GPLv2"
build-date="2021-8-9"
RUN ["/bin/bash","-c","yum -y install net-tools"]
FROM centos:7.4
MAINTAINER alex-wang wangwenchao_wwc@163.com
LABEL name="Centos Base Iamge" \
vendor="Centos" \
license="GPLv2"
build-date="2021-8-9"
RUN ["yum","-y","install","net-tolls"]
CMD 容器啟動時運行命令
功能為容器啟動時要運行的命令
語法有三種寫法:
- CMD ["executable","param1","param2"]
- CMD ["param1',"param2"]
- CMD command param1 param2
第三種比較好理解,就是shell這種執行方式和寫法
第一種和第二種其實都是可執行檔案加上引數的形式
舉例兩種寫法:
CMD [ "sh","-c""echo $HOME"]
CMD ["echo","$HOME"]
注意:這里邊包含引數一定要用雙引號,就是不能是單引號,千萬不能寫成單引號,原因是引數傳遞后,docker決議的是一個JSON array

RUN&CMD
不要RUN和CMD搞混了
RUN是構容器時就運行的命令以及提交運行結果
CMD是容器啟動時執行的命令,在構建時并不運行,構建時僅僅指定了這個命令到底是個什么樣子
[root@localhost wwc] # cat Dockerfile
FROM centos:7.4
MAINTAINER alex-wwc wangwenchao_wwc@163.com
LABEL name"Centos Base Image" \
vendor="Centos" \
license="GPLv2"
build-date="2021-8-9"
RUN ["yum","-y","install","httpd"]
CMD ["/usr/sbin/httpd","-D","FOREGROUND"] #容器啟動時運行命令代表開啟httpd服務/如果使用標準命令啟動服務會在啟動命令執行成功后關閉容器
[root@localhost wwc] # docker build -t httpd:v0.1 .

EXPOSE 監聽埠
用來指定容器運行時監聽的埠,但是并不會指定主機監聽的埠
如果想使得容器與主機的埠有映射關系,必須在容器啟動的時候加上-P引數
FROM centos:7.4
MAINTAINER alex-wwc wangwenchao_wwc@163.com
LABEL name"Centos Base Image" \
vendor="Centos" \
license="GPLv2"
build-date="2021-8-9"
RUN ["yum","-y","install","httpd"]
EXPOSE 80/tcp
CMD ["/usr/sbin/httpd","-D","FOREGROUND"]
#第二次構建特別快因為會用快取,在命令最后加上 -no-cache代表不使用快取構建
ENV 環境變數
功能為設定環境變數
語法有兩種
- ENV <key> <value>
- ENV <key> =<value> ..
兩者的區別就是第一種是一次設定一個,第二種是一層設定多個
FROM centos:7.4
MAINTAINER alex-wwc wangwenchao_wwc@163.com
LABEL name"Centos Base Image" \
vendor="Centos" \
license="GPLv2"
build-date="2021-8-9"
ENV name=wwc age=23 salary=100
docker build -t httpd:v0.3 .
docker run --name web1 --rm -it httpd:v0.3
ADD 復制自動解壓
一個復制命令,把檔案復制到鏡像中,如果是壓縮檔案,則會直接解壓
如果把虛擬機與容器想象成兩臺linux服務器的話,那么這個命令就類似于scp,只是scp需要加用戶名和密碼的權限驗證,而ADD不用,
- ADD <src>...<dest>
- ADD ["<src>",..."<dest>"]
<dest>路徑的填寫可以是容器內的絕對路徑,也可以是相對于作業目錄的相對路徑
<src>可以是一個本地檔案或者是一個本地壓縮檔案,還可以是一個url如果把<src>寫成一個URL,那么ADD就類似wget命令
如以下寫法都是可以的:
- ADD test relativerDir/
- ADD test /relativeDIr
- ADD http://example.com/foobar /
盡量不要把<scr>寫成一個檔案夾,如果<src>是一個檔案夾了,復制整理目錄的內容,包含檔案系統的元資料
FROM centos:7.4
MAINTAINER alex-wwc wangwenchao_wwc@163.com
LABEL name"Centos Base Image" \
vendor="Centos" \
license="GPLv2"
build-date="2021-8-9"
ADD ["test.tar","/root/"]
copy 復制不自動解壓
看這個名字就坐等,又是一個復制命令
語法如下:
- COPY <src>...<dest>
- COPY ["<src>",..."<dest>"]
與ADD的區別
COPY的<src>只能是本地檔案,并不能解壓,其他用法一致
ENTRYPOINT 容器啟動時命令
功能是啟動時的默認命令
語法如下:
- ENTRYPOINT ["executable","param1","param2"]
- ENTRYPOINT command param1 param2
如果從上到下看到這里的話,那么你應該對這兩種語法很熟悉啦,
第二種就是寫shlle
第一種就是可執行檔案加引數
與CMD比較說明(這兩命令太像了,而且還可以配合使用):
1. 相同點
只能寫一條,如果寫了多條,那么只有最后一條生效
容器啟動時才運行,運行時機相同
2. 不同點
ENTRYPOINT不會被運行的command覆寫,而CMD則會被覆寫
示例:
[root@wang ~]# cat wwc.sh
echo "wangwenchao"
[root@wang ~]# cat Dockerfile
FROM centos:7.4
MAINTAINER Ales-wang wangwenchao_wwc@163.com
LABEL name="Centos Base Image" \
vendor="Centos" \
build-data="2021-8-9"
COPY wwc.sh /opt
RUN chmod a+x /opt/wwc.sh
CMD ["/opt/wwc.sh"]
[root@wang ~]# docker build -t test:v0.1 .
[root@wang ~]# docker run --name web1 --rm -it test:v0.1 /bin/bash -c "echo Hello"
Hello
[root@wang ~]#
[root@wang ~]# cat wwc.sh
echo "wangwenchao"
[root@wang ~]# cat Dockerfile
FROM centos:7.4
MAINTAINER Ales-wang wangwenchao_wwc@163.com
LABEL name="Centos Base Image" \
vendor="Centos" \
build-data="2021-8-9"
COPY wwc.sh /opt
RUN chmod a+x /opt/wwc.sh
ENTRYPOINT ["/opt/wwc.sh"]
[root@wang ~]# docker build -t test:v0.2 .
[root@wang ~]# docker run --name web1 --rm -it test:v0.2 /bin/bash -c "echo Hello"
standard_init_linux.go:228: exec user process caused: exec format error
如果我們在dockerfile中同時寫了ENTRYPOINT和CMD,并且指令不是一個完整整的可執行命令,那么CMD指定的內容將會作為ENTRYPOINT的引數
如下:
[root@wang ~]# cat Dockerfile
FROM centos:7.4
MAINTAINER Ales-wang wangwenchao_wwc@163.com
LABEL name="Centos Base Image" \
vendor="Centos" \
build-data="2021-8-9"
RUN yum -y install httpd
EXPOSE 80
ENTRYPOINT ["/usr/sbin/httpd","-D"]
CMD ["FOREGROUND"]
[root@wang ~]# docker build -t test:v0.4 .
[root@wang ~]# docker run --name web1 --rm -d -P test:v0.4
5fa4c0e30929e5afe6201997a80c33a77011ed0b865af6daf58c329d03bad6ad
[root@wang ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5fa4c0e30929 test:v0.4 "/usr/sbin/httpd -D …" 3 seconds ago Up 2 seconds 0.0.0.0:49153->80/tcp, :::49153->80/tcp
如果我們在Dokcerfile中同時寫ENTRYPOINT和CMD,并且CMD是一個完整的指令,那么他們兩個會互相覆寫,誰在最后誰生效如下:
FROM ubuntu
ENIRYPOINT ["top","-b"]
CMD ls -al
那么將執行ls-al,top -b 不會執行,
VOLUME 容器掛載
可實作掛載功能,可以將本地檔案夾或者其他容器中的檔案夾掛載到這個容器中
語法為:
VOLUME ["/data"]
說明:
["/data"]可以是一個JsonArray,也可以是多個值,使用如下幾種寫法都是正確的
VOLUME ["/var/log"]
VOLUME /var/log
VOLUME /var/log /var/db
一般的使用場景為需要持久化存盤資料時
容器使用的是AUFS,這種檔案系統不能持久化資料,當容器關閉后,所有的更改都會丟失,
所以當資料需要持久化時用到這個命令,
[root@wang ~]# cat Dockerfile
FROM centos:7.4
MAINTAINER Ales-wang wangwenchao_wwc@163.com
LABEL name="Centos Base Image" \
vendor="Centos" \
build-data="2021-8-9"
RUN yum -y install httpd
EXPOSE 80
VOLUME /var/www/html
ENTRYPOINT ["/usr/sbin/httpd","-D"]
CMD ["FOREGROUND"] des/
[root@wang ~]# docker build -t test:v0.5 .
[root@wang ~]# docker run -d -P --name web1 --rm test:v0.5
c660362e1fbe37d9bdfe735a6b35a58e74472df59a111d9baaa7686e089f973e
[root@wang ~]# docker inspect web1
"Source": "/var/lib/docker/volumes/f4e901e2bdb35a019a29a2aa410d4cb5d6b9ea147bb3a9fb915ab6bd12670c99/_data",
"Destination": "/var/www/html",
[root@wang ~]# cd /var/lib/docker/volumes/f4e901e2bdb35a019a29a2aa410d4cb5d6b9ea147bb3a9fb915ab6bd12670c99/_data/
[root@wang _data]# ls
[root@wang _data]# echo "hello,world" > index.html
[root@wang _data]# ls
index.html
[root@wang _data]# docker exec -it web1 /bin/bash
[root@c660362e1fbe /]# cat /var/www/html/index.html
hello,world
USER 容器用戶
設定啟動容器的用戶,可以是用戶名和UID,所以,只有下面的兩種寫法是正確的
USER daemo
USER UID
注意:如果設定了容器以daemon用戶去運行,那么RUN,CMD和ENTRYPOINT都會以這個用戶去運行
WORKDIR 作業組
語法:
WORKDIR /path/to/workdir
設定作業目錄,對RUN,CMD,ENTRYPOINT,COPY,ADD生效,如果不存在則會創建,也可以設定多次,
如:
[root@wang test]# cat Dockerfile
FROM centos:7.4
ADD httpd-2.4.48.tar.gz /usr/src/
WORKDIR /usr/src/httpd/2.2.48
[root@wang test]# docker build -t test:v0.6 .
[root@wang test]# docker run -it -P --name web1 --rm test:v0.6
[root@f1370450187c 2.2.48]# pwd
/usr/src/httpd/2.2.48
[root@f1370450187c 2.2.48]#
WORKDIR也可以決議環境變數
如:
[root@wang test]# cat Dockerfile
FROM centos:7.4
ADD httpd-2.4.48.tar.gz /usr/src/
ENV DIRNAME=/usr/src/httpd-2.2.48
WORKDIR $DIRNAME
[root@wang test]# docker build -t test:v0.7 .
[root@wang test]# docker run -it -P --name web1 --rm test:v0.7
[root@7174998043ec httpd-2.2.48]# pwd
/usr/src/httpd-2.2.48
[root@7174998043ec httpd-2.2.48]#
ARG 互動式變數
語法:
ARG <name>[=default value]
設定變數命令,ARG命令定義了一個變數,在docker build創建鏡像的時候,使用 --build-arg <varname>=<value>來指定引數
如果用戶在build鏡像指定了一個引數沒有定義在Dockerfile中,那么將有一個Warning
提升如下:
[Warning] One or more build-args [foo] were not consumed .
我們可以定義一個或多個引數,如下:
FROM busybox
ARG user1
ARG buildon
也可以給引數一個默認值:
FROM busybox
ARG user1=someuser
ARG buildno=1
如果我們給ARG定義的引數默認值,那么當build鏡像時沒有指定引數值,將會使用這個默認值
[root@wang test]# cat Dockerfile
FROM centos:7.4
ARG nmae
ADD $name /usr/src/
ENV DIRNAME=/usr/src/httpd-2.2.48
WORKDIR $DIRNAME
[root@wang test]# docker build --build-arg name=httpd-2.2.48.tar.gz -t test:v0.8 .
[root@wang test]# docker run -it -P --name web1 --rm test:v0.8
[root@b4ac4cccd255 httpd-2.2.48]# pwd
/usr/src/httpd-2.2.48
[root@b4ac4cccd255 httpd-2.2.48]#
ONBULD 子鏡像構建時命令
語法:
ONBULD [INSTRUCTION]
這個指令只對當前鏡像的子鏡像生效,
比如當前鏡像為A,在Dockerfile中添加:
ONBULD RUN ls -al
這個ls -al命令不會在A鏡像構建或啟動的時候執行
此時有一個B是基于A鏡像構建的,那么這個ls -al命令會在B鏡像構建的時候被執行,
STOPSIGNAL 容器退出時執行命令
語法:
STOPSIGNAL signal
STOPSIGNAL命令的作用是當容器退出時給系統發送什么樣的指令
HEALTHCHECK 容器健康檢查
容器健康狀態檢查命令
語法有兩種:
- HEALTHCHECK [OPTIONS] CMD command
- HEALTHCHECK NONE
第一個的功能是在容器內部運行一個命令來檢查容器的檢查狀況
第二個的功能是在基礎鏡像中取消健康檢查命令
[OPTIONS]的選項支持以下三種選項:
--interval=DURATION #兩次檢查默認的時間間隔為30秒
--timeout=DURATION #健康檢查命令運行超時長,默認30秒
--retries=N #當連續失敗指定次數后,則容器被認為是不健康的,狀態為unhealthy,默認次數是3
注意:
HEALTHCHECK命令只能出現一次,如果出現多次,只有最后一個生效,
CMD后邊的命令的回傳值決定了本次健康檢查是否成功,具體的回傳值如下:
0:success-表示容器是健康的
1:unhealthy-表示容器已經不能作業了
2:reserved-保留值
例子:
HEALTHCHECK --interval=5s --timeout=3s CMD curl -f http://localhost/ || exit 1
健康檢查命令是:curl -f http://localhost/ || exit 1
兩次檢查的間隔時間是5秒
命令超時時間為3秒
[root@wang test]# cat Dockerfile
FROM nginx
ADD test.sh /opt
RUN chmod a+x /opt/test.sh
HEALTHCHECK --interval=10s --timeout=5s CMD /bin/bash /opt/test.sh
[root@wang test]# cat test.sh
#!/bin/bahs
ss -an|grep 80
if [ $? -eq 0 ]
then
exit 0
else
exit 1
fi
[root@wang test]# docker build -t nginx:v0.1 .
[root@wang test]# docker run -it -P --name web1 nginx:v0.1 /bin/bash
[root@wang test]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5d5086b33f71 nginx:v0.1 "/docker-entrypoint.…" 21 seconds ago Up 20 seconds (health: starting) 0.0.0.0:49155->80/tcp, :::49155->80/tcp web1
[root@wang test]#
[root@wang test]# docker run -it -P --name web1 nginx:v0.1 /bin/bash
root@5d5086b33f71:/# nginx -s stop
2021/08/10 06:38:22 [notice] 52#52: signal process started
2021/08/10 06:38:22 [error] 52#52: open() "/var/run/nginx.pid" failed (2: No such file or directory)
nginx: [error] open() "/var/run/nginx.pid" failed (2: No such file or directory)
root@5d5086b33f71:/#
[root@wang test]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5d5086b33f71 nginx:v0.1 "/docker-entrypoint.…" About a minute ago Up About a minute (unhealthy) 0.0.0.0:49155->80/tcp, :::49155->80/tcp web1
[root@wang test]#
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/293332.html
標籤:其他
