十、指令10:RUN指令html
RUM命令是基于Dockerfile构建镜像的时候要运行的命令mysql
好比基于url的方式获取nginx安装包:获取到gz包之后须要使用RUN指令来运行tar来解压展开这个nginx的包了。nginx
案例:编写docker file,并制做镜像
web
#my first docker file FROM busybox:latest MAINTAINER "zxhk <237745635@qq.com>" ENV DOC_ROOT=/data/ \ WORK_DIR=/var/usr/src/ \ REPO_DIR=/etc/yum.repos.d/ \ MYSQL_DIR=/data/mysql/ COPY index.html ${DOC_ROOT:-/var/www/html/} COPY yum.repos.d $REPO_DIR WORKDIR $WORK_DIR ADD http://nginx.org/download/nginx-1.17.6.tar.gz ./ RUN cd ${WORK_DIR} && tar -xf nginx-1.17.6.tar.gz && mv nginx-1.17.6 nginx VOLUME $MYSQL_DIR EXPOSE 80/tcp 53/udp
[root@host1 img1]# docker build -t miniser:v1-8 ./
基于镜像启动一个容器,检测是否已经解压sql
[root@host1 img1]# docker run --rm --name t1 miniser:v1-8 ls /var/usr/src/ nginx nginx-1.17.6.tar.gz
十一、指令11:CMD指令docker
CMD是定义一个镜像文件启动为容器的时候,默认要运行的程序,也就是那个pid为1的程序shell
CMD能够有多个,可是只有最后一个才是生效的。apache
CMD指令有三种格式vim
格式1:CMD <命令>bash
这种格式的话,会自动的将这个命令运行为shell的子进程,这样的好处就是在这个命令中能够有各类的特殊的符号,可是缺点就得是这个命令的进程号不是 1
也能够借助于exec,让这个进程的ID成为1
格式2:CMD ["<命令>", "<参数1>","<参数2>"]
这种格式的话是直接将这个进程启动为ID为1的进程
格式3:CMD ["<参数1>","<参数2>"]
这种格式须要借助于ENTRYPOINT才能运行
案例1:使用格式1让容器运行的时候,自动运行apache
第一步:建立dockerfile
FROM busybox LABEL maintainer="zxhk<237745635@qq.com>" ENV DOC_ROOT="/var/www/html/" RUN mkdir -p ${DOC_ROOT} && \ echo "<h1>test</h1>">${DOC_ROOT}index.html CMD /bin/httpd -f -h ${DOC_ROOT}
第二步:制做镜像
[root@host1 img2]# docker build -t miniser:v2-1 ./
第三步:查看镜像的详细信息
[root@host1 img2]# docker inspect miniser:v2-1 -f '{{.ContainerConfig.Cmd}}' [/bin/sh -c #(nop) CMD ["/bin/sh" "-c" "/bin/httpd -f -h ${DOC_ROOT}"]]
第四步:建立容器
[root@host1 img2]# docker run --name t1 --rm -d miniser:v2-1
第五步:登陆容器,查看容器信息
[root@host1 img2]# docker exec -it t1 /bin/sh / # / # netstat -an Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 :::80 :::* LISTEN / # / # ps PID USER TIME COMMAND 1 root 0:00 /bin/httpd -f -h /var/www/html/ 10 root 0:00 /bin/sh 15 root 0:00 ps / #
案例2:使用格式2让容器运行的时候,自动运行apache
FROM busybox LABEL maintainer="zxhk<237745635@qq.com>" ENV DOC_ROOT="/var/www/html/" RUN mkdir -p ${DOC_ROOT} && \ echo "<h1>test</h1>">${DOC_ROOT}index.html CMD ["/bin/sh", "-c", "/bin/httpd", "-f", "-h", "${DOC_ROOT}"]
十一、指令11:ENTRYPOINT指令
ENTRYPOINT的功能就是和CMD相似的,用于指定容器启动后要默认运行的程序
在启动容器的时候,run后面指定的命令,能够覆盖镜像中的CMD命令
ENTRYPOINT所运行的命令不会不被docker run所指定的命令覆盖
案例:用ENTRYPOINT制做镜像实现启动容器自动运行apache
FROM busybox LABEL maintainer="zxhk<237745635@qq.com>" ENV DOC_ROOT="/var/www/html/" RUN mkdir -p ${DOC_ROOT} && \ echo "<h1>test</h1>">${DOC_ROOT}index.html ENTRYPOINT /bin/httpd -f -h ${DOC_ROOT}
制做镜像并启动容器测试
[root@host1 img2]# docker build -t miniser:v2-2 ./ [root@host1 img2]# docker run --name t2 --rm -it miniser:v2-2 ls /data
此时命令会卡住
ls /data会做为参数传递给httpd -f -h /data,由于httpd没法识别这个参数,所以会卡住
ENTRYPOINT和CMD组合使用的状况
此时CMD后的内容就会做为默认参数传递给ENTRYPOINT
FROM busybox LABEL maintainer="zxhk<237745635@qq.com>" ENV DOC_ROOT="/var/www/html/" RUN mkdir -p ${DOC_ROOT} && \ echo "<h1>test</h1>">${DOC_ROOT}index.html CMD ["/bin/httpd", "-f", "-h", "${DOC_ROOT}"] ENTRYPOINT ["/bin/sh","-c"]
使用ENTRYPOINT的好处是,他比CMD更方便,由于他能够在启动容器的时候,直接向容器传递命令
案例:在启动容器的时候,动态生成配置文件
一、建立工做目录
[root@host1 img3]# mkdir /img3 [root@host1 img3]# cd /img3
二、准备一个shell脚本,用于生成配置文件
[root@host1 img3]# vim entrypoint.sh
#!/bin/sh cat>/etc/nginx/conf.d/www.conf<<EOF server { server_name $HOSTNAME; listen ${IP:-0.0.0.0}:${PORT:-80}; root ${NGX_DOC_ROOT:-/usr/share/nginx/html}; } EOF exec "$@"
三、建立测试页面
[root@host1 img3]# echo "test page">index.html
四、编写Dockerfile文件
[root@host1 img3]# vim Dockerfile
FROM nginx:1.14-alpine LABEL author="zxhk<237745635@qq.com>" ENV NGX_DOC_ROOT='/data/web/html/' ADD index.html ${NGX_DOC_ROOT} ADD entrypoint.sh /bin/ #nginx的配置文件必须以;为结尾 CMD ["/usr/sbin/nginx","-g","daemon off;"] ENTRYPOINT ["/bin/entrypoint.sh"]
在执行dockerfile的时候,CMD的内容会传递到ENTRYPOINT中
ENTRYPOIN会启动运行这个shell脚本,shell脚本就是pid为1的进程,shell脚本就会生成配置文件
在脚本的最后会经过exec 来执行nginx,让nginx工做在前台,同时nginx进程顶替shell成为pid为1的进程
五、构建镜像
[root@host1 img3]# docker build -t miniser:v2-4 ./
六、启动容器
[root@host1 img3]# docker run --name nginx1 --rm miniser:v2-4
登陆容器看看
[root@host1 ~]# docker exec -it nginx1 /bin/sh / # / # cat /etc/nginx/conf.d/www.conf server { server_name c1d255997da4; listen 0.0.0.0:80; root /data/web/html/; } / #
七、再从新启动一个容器,让nginx监听127.0.0.1的8080端口
[root@host1 img3]# docker run --name nginx1 --rm \ > -e "PORT=8080" -e "IP=1.2.3.4" miniser:v2-4
再登陆容器看看
[root@host1 ~]# docker exec -it nginx1 /bin/sh / # / # / # cat /etc/nginx/conf.d/www.conf server { server_name 92c978c97b3c; listen 127.0.0.1:8080; root /data/web/html/; } / #
经过这种方式能够快速的为不一样的环境准备特定的配置文件
十二、指令12:USER指令
用于指定容器中的主进程是以哪一个用户的身份来运行
也能够用来指定在执行dockerfile的CMD RUN ENTRYPOIND的时候,以那个用户的身份来运行
须要确保容器的/etc/passwd中有这个用户,不然会报错
语法格式:
USER <UID> | <USERNAME>
1三、指令13:HEALTHCHECK指令
检查容器和容器中的服务是否正常工做
HEALTHCHECK的功能选项
--interval=xx 指定每隔多久检查一次(默认每隔30s检查一次)
--timeout=xx 指定等待超时时间(默认也是30s)
--start-period=xx 启动容器后,等待多久开始作健康检查(默认是0秒,也就是不等)
--retries=xx 指定请求几回数据都没得到返回的状况下才认为是出现了异常(默认是3次)
HEALTHCHECK的返回值
0:success成功
1:unhealth不健康
2:预留,没有意义
案例:每隔5分钟检查一次,超时时间是3秒
HEALTHCHECK --interval=5m --timeout=3s CMD curl -f http://1.2.3.4 || exit 1
若是健康检查失败,就返回1
1四、指令14:SHELL指令
这个是用来指定运行程序的时候默认要用的程序
举例:
SHELL ["/bin/sh","-c"]
1五、指令15:STOPSIGNAL指令
这个指令能够指定在执行docker stop的时候,本质上是向容器发送什么什么指令,默认是发送15,若是想执行stop的时候发送9的指令
格式
STOPSIGNAL 9
1六、指令16:ARG指令
ARG也是定义一个变量,只是这个变量是用在执行build dockerfile的过程当中
能够将nginx的版本定义成变量,而后在构建镜像的时候能够经过变量来动态指定做者
编写镜像文件
FROM nginx:1.14-alpine ARG info="zxhk<237745635@qq.com>" LABEL author="${info}" ENV NGX_DOC_ROOT='/data/web/html/' ADD index.html ${NGX_DOC_ROOT} ADD entrypoint.sh /bin/ #nginx的配置文件必须以;为结尾 CMD ["/usr/sbin/nginx","-g","daemon off;"] ENTRYPOINT ["/bin/entrypoint.sh"]
制做镜像
[root@host1 img3]# docker build -t miniser:v2-5 --build-arg new="tom@qq.com" ./
Dockerfile中的arg至关因而配置了一个默认值,在制做镜像的时候,若是没有传值,就用默认值
注意区分ENV和ARG
docker run的时候能够传值,可是在docker build的时候是没法传值的
ENV所定义的变量在够构建镜像的时候使用的,而在构建镜像的时候是只能用ARG的默认值的
1七、指令17:ONBUILD指令
本指令实际上是定义一个触发器
经过ONBUILD定义的Dcokerfile,在执行docker build的时候不执行,只有别人基于这个镜像作新镜像的时候,才会被执行
案例:若是别人基于这个镜像作新镜像,就让其下载一个文件
第一步:制做一个基础镜像
[root@host1 img3]# vim Dockerfile
FROM nginx:1.14-alpine LABEL author="zxhk<237745635@qq.com>" ENV NGX_DOC_ROOT='/data/web/html/' ADD index.html ${NGX_DOC_ROOT} ADD entrypoint.sh /bin/ ONBUILD ADD http://x.x.x.x/xxx /data/web/html/ #nginx的配置文件必须以;为结尾 CMD ["/usr/sbin/nginx","-g","daemon off;"] ENTRYPOINT ["/bin/entrypoint.sh"]
制做镜像
[root@host1 img3]# docker build -t base:v1.1 ./
第二步:基于基础镜像作新镜像
[root@host1 ~]# mkdir /img4 [root@host1 img4]# cd /img4 [root@host1 img4]# vim Dockerfile
FROM base:v1-1 RUN mkdir /data
制做镜像
[root@host1 img4]# docker build -t newimg:v1-1 ./