
Dockerfile构建镜像
1.ockerfile自动构建docker镜像
dockerfile 支持自定义容器的初始命令
dockerfile主要组成部分:
- 基础镜像信息 FROM centos:6.9
- 制作镜像操作指令 RUN yum install openssh-server -y
- 容器启动时执行指令 CMD ["/bin/bash"]
dockerfile常用指令:
- FROM 这个镜像的妈妈是谁?(指定基础镜像)
- MAINTAINER 告诉别人,谁负责养它?(指定维护者信息,可以没有)
- LABLE 标签
- RUN 你想让它干啥(在命令前面加上RUN即可)
- ADD 给它点创业资金(会自动解压 tar) 制作docker基础的系统镜像
- WORKDIR 我是cd,今天刚化了妆(设置当前工作目录)
- VOLUME 给它一个存放行李的地方(设置卷,挂载主机目录)
- EXPOSE 它要打开的门是啥(指定对外的端口)(-P 随机端口)
- CMD 奔跑吧,兄弟!(指定容器启动后的要干的事情)(容易被替换)
dockerfile其他指令:
- COPY 复制文件(不会解压)
- ENV 环境变量
- ENTRYPOINT 容器启动后执行的命令(无法被替换,启容器的时候指定的命令,会被当成参数)
4.参考其他的dockerfile
官方dockerfile或者时速云镜像广场
2.指令详解释
COPY
复制指令,从上下文目录中复制文件或者目录到容器里指定路径
格式:
COPY [--chown=<user>:<group>] <源路径1> 。。。 <目标路径>[--chown=:] 可选参数,用户改变复制到容器内文件的拥有者和属组
<源路径> 源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足Go的filepath.Match规则,例如
COPY hom* /mydir/ COPY hom?.txt /mydir/<目标路径> 容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建
ADD
ADD指令和COPY的使用格式一致,功能也类型,不同之处如下:
- ADD的优点:在执行<源文件>为tar压缩文件的话,压缩格式为gzip,bzip2以及xz的情况下,会自动复制解压到<目标路径>
- ADD的缺点:在不解压的前提下,无法复制tar压缩文件,会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢,具体的使用,可以根据是否需要自动解压来决定
CMD
类似于RUN指令,用于运行程序,但二者运行的时间不同
- CMD 在docker run时运行
- RUN 是在docker build
作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD指令指定的程序可以被docker run命令行参数中指定要运行的程序所覆盖
注意:如果Dockerfile中如果存在多个CMD指令,仅最后一个生效
格式
CMD <shell命令> CMD ["可执行文件或命令","param1","param2",.....] CMD ["<param1>","<param2>",...] #该写法是为ENIRYPOINT指令的程序提供默认参数推荐使用第二种格式,执行过程比较明确。第一种格式实际上在运行的过程中也会自动转换成第二种格式运行,并且默认可执行文件是sh
ENTRYPOINT
类似于CMD指令,但其不会被docker run 的命令参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给ENTRYPOINT指令指定的程序
但是,如果运行docker run时候用了 --entrypoint 选项,将覆盖CMD指令指定的程序
- 优点:在执行docker run的时候可以指定ENTRYPOINT运行所需的参数
- 注意:如果Dockerfile只存在多个ENTRYPOINT指令,仅最后一个生效
格式:
ENTRYPOINT ["<executeable>","<param1>","<param2>",...]可以搭配CMD命令使用:一般是变参才会使用CMD,这里的CMD等于是在给ENTRYPOINT传参,以下示例会提到
FROM nginx ENTRYPOINT ["nginx","-c"] #定参 CMD ["/etc/nginx/nginx.conf"] #变参1.不传参运行
$ docker run nginx:test 容器内会默认运行以下命令,启动主进程 nginx -c /etc/nginx/nginx.conf2.传参运行
$ docker run nginx:test -c /etc/nginx/new.conf 容器内会默认运行以下命令,启动主进程(/etc/nginx/new.conf) nginx -c /etc/nginx/new.confENV
设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量
格式
ENV <key> <value> ENV <key1>=<value1> <key2>=<value2>...以下示例设置NODE_VERSION = 7.2.0,在后续的指令中可以通过$NODE_VERSION引用:
ENV NODE_VERSION 7.2.0 RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.gz" \ && curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION.txt"ARG
构建参数,与ENV作用一致,不过作用域不一样,ARG设置的环境变量仅对Dockerfile内有效,也就是说只有docker build的过程中有效,构建好的镜像内不存在此环境变量
构建命令docker build中可以用 --build-arg <参数名>=<值>来覆盖
ARG <参数名>[=<默认值>]VOLUME
定义匿名数据卷,在启动容器时忘记挂载数据卷,会自动挂载到匿名卷
作用:
- 避免重要的数据,因为容器重启而丢失,这是非常致命的
- 避免容器不断变大
格式
VOLUME ["路径1","路径2"] VOLUME <路径>在启动容器docker run的时候,我们可以通过-v参数修改挂载点
EXPOSE
仅仅只是声明端口
作用
- 帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射
- 在运行时使用随机端口映射时,也就是docker run -P时,会自动随机映射EXPOSE的端口
EXPOSE <端口1> [<端口2>...]WORKDIR
指定工作目录。用WORKDIR指定的工作目录,会在构建镜像的每一层中都存在。WORKDIR指定的工作目录,必须是提前创建好的
docker build构建镜像过程中,每一个RUN命令都是新建的一层,只有通过WORKDIR创建的目录才会一直存在
WORKDIR <工作目录>USER
用于指定执行后续命令的用户和用户组,这边只是切换后续命令的用户(用户和用户组必须提前已经存在)
USER <用户名>[:<用户组>]HEALTHCHECK
用于指定某个程序或者指令来监控docker容器服务的运行状态
HEALTHCHECK [选项] CMD <命令> :设置检查容器健康状况的命令 HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉健康检查指令 HEALTHCHECK [选项] CMD <命令>:这边CMD后面跟随的命令使用ONBUILD
用于延迟构建命令的执行。简单的说,就是Dockerfile里面用ONBUILD指定的命令,在本次构建镜像的过程中不会执行,当有心的Dockerfile使用了之前构建的镜像,这时执行心镜像的Dockerfile构建时候,会执行ONBUILD指定的命令
LABEL
LABEL指令用来给镜像添加一些元数据,以键值对的形式,语法格式如下
LABEL <key>=<value> <key>=<value>
3.相似命令间的区别
1.RUN 和 CMD
RUN 用于docker build,RUN可以使用多次,每次都是一层镜像 CMD 用于docker run,多个CMD只有最后一条生效,CMD会被docker run 命令行参数中指定要运行的程序所覆盖2.ADD 和 COPY
使用格式一样,功能也类型,官方建议使用COPY 优点:在执行源文件是tar压缩文件的话,压缩格式为gzip,bzip2,xz的情况下,会自动复制并解压到目标路径 缺点:在不解压的前提下,无法复制tar文件,会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢3.CMD 和 ENTRYPOINT
CMD和ENTRYPOINT都是如果存在多个,只有最后一个生效 ENTRYPOINT不会被docker run的命令行参数指定的指令覆盖,而且这些命令行参数会被当作参数送给ENTRYPOINT指令指定的程序,但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 CMD 指令指定的程序。 优点:在执行docker run的时候可以指定ENTRYPOINT运行所需的参数 可以搭配CMD命令使用:一般是变参才会使用CMD,这里的CMD等于是在给ENTRYPOINT传参 ENTRYPOINT ["nginx", "-c"] # 定参 CMD ["/etc/nginx/nginx.conf"] # 变参4.ENV 和 ARG
他们的作用域不一样 ENV定义了环境变量,那么在后续的指令中,就可以使用这个环境变量 ARG环境变量仅对 Dockerfile 内有效
4.dockerfile制作镜像
第一步:编写dockerfile
第二步:docker build 构建镜像
第三部:测试实例1
1.创建存放dockerfile的文件夹,并建立dockerfile文件
[root@docker01 dockerfile]# cat dockerfile FROM centos:6.9 RUN yum install openssh-server -y RUN service sshd start RUN echo '123456'|passwd --stdin root CMD ["/usr/sbin/sshd","-D"]2.构建镜像
[root@docker01 dockerfile]# docker image build -t centos6.9_ssh:v1 . //在当前目录构建3.测试镜像
[root@docker01 dockerfile]# docker run -d -p 2222:22 centos6.9_ssh:v1示例2
2.1.创建dockerfile
[root@docker01 dockerfile]# cat dockerfile FROM centos:6.9 RUN yum install openssh-server -y RUN service sshd start RUN echo '123456'|passwd --stdin root RUN curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo RUN yum install nginx -y ADD start.sh /start.sh // 添加与dockerfile同级目录下的init.sh脚本到docker镜像的根目录 EXPOSE 80 22 VOLUME /usr/share/nginx/html WORKDIR /usr/share/nginx/html // build镜像过程中,RUN提交镜像时当前目录不会发生改变 CMD ["/bin/bash","/start.sh"]2.2.创建脚本
docker在启动容器的时候只运行一条命令,所以多服务启动需要用脚本启动[root@docker01 dockerfile]# cat init.sh #!/bin/bash service nginx start /usr/sbin/sshd -D2.3.构建镜像
[root@docker01 abc]# docker image build -t centos6.9_ssh_nginx:v15 .示例3
3.ENV的使用(脚本传参)可以让镜像变的很灵活
3.1.ENTRYPOINT代替CMD的写法[root@docker01 dockerfile]# cat dockerfile FROM centos:6.9 RUN yum install openssh-server -y RUN service sshd start ENV SSH_PASS 123456 COPY init.sh /init.sh ENTRYPOINT ["/usr/sbin/sshd","-D"] [root@docker01 dockerfile]# cat init.sh #!/bin/bash echo '$SSH_PASS' |passwd --stdin root [root@docker01 dockerfile]# docker run -d --env 'SSH_PASS=1QWE#@!10' -P 7022:22 centos6.9:v14.Volume持久化
[root@docker01 centos6.9_ssh_nginx]# docker volume ls DRIVER VOLUME NAME local x86cloud [root@docker01 centos6.9_ssh_nginx]# docker volume inspect x86cloud [ { "CreatedAt": "2019-02-24T01:59:15+08:00", "Driver": "local", "Labels": {}, "Mountpoint": "/var/lib/docker/volumes/x86cloud/_data", "Name": "x86cloud", "Options": {}, "Scope": "local" } ]