Dockerfile命令速查表
FROM 命令
FROM <p_w_picpath>:<tag>
用于设置基础镜像,一般是Dockerfile的第一句。如果没有指定 tag ,则默认tag是latest。
MAINTAINER
MAINTAINER <name>
用来指定维护者的姓名和联系方式。
RUN
RUN <command> 或 RUN ["executable", "param1", "param2"]
每条 RUN 指令将在当前镜像基础上执行指定命令,并提交为新的镜像。
ADD
ADD <src> <dest>
将 <src> 文件复制到 <dst> 文件:<src> 是相对被构建的源目录的相对路径,可以是文件或目录的路径,也可以是一个远程的文件 url,<dst> 是容器中的绝对路径。
COPY
COPY <src> <dest>
复制本地主机的 <src> (为Dockerfile所在目录的相对路径)到容器中的 <dest>,与ADD指令差不多
<src>可以是多个,甚至可以是通配符,其通配符规则要满足 Go 的filepath.Match 规则
例如
COPY hom* /mydir/ COPY hom?.txt /mydir/
在 Docker 官方的最佳实践文档中要求,尽可能的使用 COPY ,因为 COPY 的语义很明确,就是复制文件而已,而 ADD 则包含了更复杂的功能,其行为也不一定很清晰。最适合使用 ADD 的场合,就是所提及的需要自动解压缩的场合。
另外需要注意的是, ADD 指令会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。
因此在 COPY 和 ADD 指令中选择的时候,可以遵循这样的原则,所有的文件复制均使用 COPY 指令,仅在需要自动解压缩的场合使用 ADD 。
ENTRYPOINT
ENTRYPOINT ["executable", "param1", "param2"] :推荐使用的 exec 形式
ENTRYPOINT command param1 param2 :shell 形式
配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。一个 Dockerfile 中只能有一个 ENTRYPOINT,如果有多个,则最后一个生效。
CMD
CMD ["executable","param1","param2"] 使用 exec 执行,推荐方式;
CMD command param1 param2 在 /bin/sh 中执行,提供给需要交互的应用;
CMD ["param1","param2"] 提供给 ENTRYPOINT 的默认参数;
指定启动容器时执行的命令,每个 Dockerfile 只能有一条 CMD 命令。如果指定了多条命令,只有最后一条会被执行。
如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的命令。
提到 CMD 就不得不提容器中应用在前台执行和后台执行的问题。这是初学者常出现的一个混淆。
Docker 不是虚拟机,容器中的应用都应该以前台执行,而不是像虚拟机、物理机里面那样,用 upstart/systemd 去启动后台服务,容器内没有后台服务的概念。
一些初学者将 CMD 写为:
CMD service nginx start
然后发现容器执行后就立即退出了。甚至在容器内去使用 systemctl 命令结果却发现根本执行不了。这就是因为没有搞明白前台、后台的概念,没有区分容器和虚拟机的差异,依旧在以传统虚拟机的角度去理解容器。
对于容器而言,其启动程序就是容器应用进程,容器就是为了主进程而存在的,主进程退出,容器就失去了存在的意义,从而退出,其它辅助进程不是它需要关心的东西。
而使用 service nginx start 命令,则是希望 upstart 来以后台守护进程形式启动 nginx 服务。而刚才说了 CMD service nginx start 会被理解为 CMD ["sh", "-c", "service nginx start"] ,因此主进程实际上是 sh 。那么当service nginx start 命令结束后, sh 也就结束了, sh 作为主进程退出
了,自然就会令容器退出。
正确的做法是直接执行 nginx 可执行文件,并且要求以前台形式运行。比如:
CMD ["nginx", "-g", "daemon off;"]
WORKDIR
WORKDIR /path/to/workdir
为后续的 RUN、CMD、ENTRYPOINT 指令配置工作目录。
可以使用多个 WORKDIR 指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。例如
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
则最终路径为 /a/b/c 。
EXPOSE
EXPOSE <port> [<port>...]
告诉 Docker 服务端容器暴露的端口号,供互联系统使用。例如 EXPOSE 8080 3000,开放 8080 和 3000 端口。
ENV
ENV <key> <value>
指定一个环境变量,会被后续 RUN 指令使用,并在容器运行时保持。
VOLUME
VOLUME ["/data"]
创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等。
USER
USER <UID/Username>
为容器内指定 CMD RUN ENTRYPOINT 命令运行时的用户名或UID。
ONBUILD
ONBUILD [INSTRUCTION]
配置当所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令。例如,利用Dockerfile创建了一个镜像A,其中Dockerfile中有这么几个命令
ONBUILD RUN mkdir test
ONBUILD ADD app.js /test/app.js
那么镜像B基于镜像A去构建的时候,默认会在最后加上这两行命令
实战
我们通过一个编译nginx的Dockerfile来实战看看
先mkdir dockerfile,在cd到该目录
[root@localhost dockerfile]# ll total 972 -rw-r--r--. 1 root root 289 Jun 27 15:08 Dockerfile -rw-r--r--. 1 root root 546 Jun 27 08:52 install_nginx.sh -rw-r--r--. 1 root root 980831 Apr 17 21:28 nginx-1.12.0.tar.gz -rw-r--r--. 1 root root 1353 Jun 27 10:08 nginx.conf
可以看到,这个目录有4个文件
nginx.conf就是我线上优化好缺省的配置文件
install_nginx.sh是基础搭建脚本
内容如下
[root@localhost dockerfile]# more install_nginx.sh #!/bin/bash useradd site cat > /etc/yum.repos.d/CentOS-Base.repo <<EOF [base] name=aliyun - base baseurl=http://mirrors.aliyun.com/centos/6/os/x86_64/ enabled=1 gpgcheck=0 [epel] name=aliyun - epel baseurl=http://mirrors.aliyun.com/epel/6Server/x86_64/ enabled=1 gpgcheck=0 EOF yum -y install pcre-devel zlib-devel gcc gcc-c++ ncurses-devel perl cmake zip unzip screen tar zxf nginx-1.12.0.tar.gz cd nginx-1.12.0 ./configure --prefix=/usr/local/nginx make && make install cd .. mv -f nginx.conf /usr/local/nginx/conf/nginx.conf
Dockerfile内容如下
FROM hasedon/centos6.5 MAINTAINER yee.wql <yee.wql@gmail.com> ADD install_nginx.sh nginx-1.12.0.tar.gz nginx.conf /root/ WORKDIR /root RUN /bin/bash install_nginx.sh && echo "hello world!" >/usr/local/nginx/html/index.html EXPOSE 80 CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
构建镜像
[root@localhost dockerfile]# docker build -t mynginx .
构建完以后,检查镜像
[root@localhost dockerfile]# docker p_w_picpaths REPOSITORY TAG IMAGE ID CREATED SIZE mynginx latest 2ab9d60af257 3 minutes ago 733MB
再就可以运行镜像了
[root@localhost dockerfile]# docker run -d -p 80:80 --name mynginx mynginx [root@localhost dockerfile]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ce9903642f63 mynginx "/usr/local/nginx/..." 2 seconds ago Up 1 second 0.0.0.0:80->80/tcp mynginx
最后访问下页面