Dockerfile是由一系列命令和参数构成的脚本,这些命令应用于基础镜像并最终创建一个新的镜像。它们简化了从头到尾的流程并极大的简化了部署工作。Dockerfile从FROM命令开始,紧接着跟随者各种方法,命令和参数。其产出为一个新的可以用于创建容器的镜像。
Dockerfile 语法在我们深入讨论Dockerfile之前,让我们快速过一下Dockerfile的语法和它们的意义。什么是语法?非常简单,在编程中,语法意味着一个调用命令,输入参数去让应用执行程序的文法结构。这些语法被规则或明或暗的约束。程序员遵循语法规范以和计算机 交互。如果一段程序语法不正确,计算机将无法识别。Dockerfile使用简单的,清楚的和干净的语法结构,极为易于使用。这些语法可以自我释义,支持注释。
Dockerfile 语法示例Dockerfile语法由两部分构成,注释和命令+参数一个简单的例子:复制代码代码如下:# Print "Hello docker!"RUN echo "Hello docker!"
Dockerfile 命令Dockerfile有十几条命令可用于构建镜像,下文将简略介绍这些命令。
FROM 命令复制代码代码如下:FROM <image>或复制代码代码如下:FROM <image>:<tag>这个设置基本的镜像,为后续的命令使用,所以应该作为Dockerfile的第一条指令。比如:复制代码代码如下:FROM ubuntu如果没有指定 tag ,则默认tag是latest,如果都没有则会报错。
RUN 命令RUN命令会在上面FROM指定的镜像里执行任何命令,然后提交(commit)结果,提交的镜像会在后面继续用到。两种格式:复制代码代码如下:RUN <command> (the command is run in a shell - `/bin/sh -c`)或:复制代码代码如下:RUN ["executable", "param1", "param2" ... ] (exec form)RUN命令等价于:复制代码代码如下:docker run image commanddocker commit container_id
注释使用 # 作为注释如:复制代码代码如下:# Memcached## VERSION 1.0</p><p># use the ubuntu base image provided by dotCloudFROM ubuntu</p><p># make sure the package repository is up to dateRUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.listRUN apt-get update</p><p># install memcachedRUN apt-get install -y memcached
MAINTAINER 命令MAINTAINER <name>MAINTAINER命令用来指定维护者的姓名和联系方式如:复制代码代码如下:MAINTAINER Guillaume J. Charmes, guillaume@dotcloud.com
ENTRYPOINT 命令有两种语法格式,一种就是上面的(shell方式):复制代码代码如下:ENTRYPOINT cmd param1 param2 ...第二种是 exec 格式:复制代码代码如下:ENTRYPOINT ["cmd", "param1", "param2"...]如:复制代码代码如下:ENTRYPOINT ["echo", "Whale you be my container"]ENTRYPOINT 命令设置在容器启动时执行命令复制代码代码如下:root@tankywoo-docker:~# cat DockerfileFROM ubuntuENTRYPOINT echo "Welcome!"</p><p>root@tankywoo-docker:~# docker run 62fda5e450d5Welcome!
USER 命令比如指定 memcached 的运行用户,可以使用上面的 ENTRYPOINT 来实现:复制代码代码如下:ENTRYPOINT ["memcached", "-u", "daemon"]更好的方式是:复制代码代码如下:ENTRYPOINT ["memcached"]USER daemon
EXPOSE 命令EXPOSE 命令可以设置一个端口在运行的镜像中暴露在外复制代码代码如下:EXPOSE <port> [<port>...]比如memcached使用端口 11211,可以把这个端口暴露在外,这样容器外可以看到这个端口并与其通信。复制代码代码如下:EXPOSE 11211一个完整的例子:复制代码代码如下:# Memcached## VERSION 2.2</p><p># use the ubuntu base image provided by dotCloudFROM ubuntu</p><p>MAINTAINER Victor Coisne victor.coisne@dotcloud.com</p><p># make sure the package repository is up to dateRUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.listRUN apt-get update</p><p># install memcachedRUN apt-get install -y memcached</p><p># Launch memcached when launching the containerENTRYPOINT ["memcached"]</p><p># run memcached as the daemon userUSER daemon</p><p># expose memcached portEXPOSE 11211上面是官方例子,国内建议换成163或sohu的源,不然太慢了。复制代码代码如下:root@tankywoo-docker:~# docker build -t tankywoo - < dck [38/480]Uploading context 2.56 kBUploading contextStep 0 : FROM ubuntu ---> 99ec81b80c55Step 1 : MAINTAINER Victor Coisne victor.coisne@dotcloud.com ---> Using cache ---> 2b58110877f6Step 2 : RUN echo "deb http://mirrors.163.com/ubuntu/ precise main restricted universe multiverse" > /etc/apt/sources.list ---> Running in f55a4a8bb069 ---> d48c6a965398Step 3 : RUN apt-get update ---> Running in da091a1dd6e7Ign http://mirrors.163.com precise InReleaseGet:1 http://mirrors.163.com precise Release.gpg [198 B]</p><p>....</p><p>Processing triggers for libc-bin (2.19-0ubuntu6) ...Processing triggers for ureadahead (0.100.0-16) ... ---> 2886671b5b86Step 5 : ENTRYPOINT ["memcached"] ---> Running in e8aeeab92cb6 ---> 7148293a4053Step 6 : USER daemon ---> Running in 288766b19606 ---> 235e7f630ffaStep 7 : EXPOSE 11211 ---> Running in c6f881b9d51f ---> 666c5d65f396Successfully built 666c5d65f396Removing intermediate container f55a4a8bb069Removing intermediate container da091a1dd6e7Removing intermediate container f23631d3d45aRemoving intermediate container e8aeeab92cb6Removing intermediate container 288766b19606Removing intermediate container c6f881b9d51f
ENV 命令用于设置环境变量复制代码代码如下:ENV <key> <value>设置了后,后续的RUN命令都可以使用。使用此dockerfile生成的image新建container,可以通过 docker inspect 看到这个环境变量:复制代码代码如下:root@tankywoo-docker:~# docker inspect 49bfc7a9817f ... "Env": [ "name=tanky", "HOME=/", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ], ...里面的name=tanky就是设置的。也可以通过在docker run时设置或修改环境变量:复制代码代码如下:docker run -i -t --env name="tanky" ubuntu:newtest /bin/bash
ADD 命令从src复制文件到container的dest路径:复制代码代码如下:ADD <src> <dest><src> 是相对被构建的源目录的相对路径,可以是文件或目录的路径,也可以是一个远程的文件url<dest> 是container中的绝对路径VOLUME 命令复制代码代码如下:VOLUME ["<mountpoint>"]如:复制代码代码如下:VOLUME ["/data"]创建一个挂载点用于共享目录
WORKDIR 命令复制代码代码如下:WORKDIR /path/to/workdir配置RUN, CMD, ENTRYPOINT 命令设置当前工作路径可以设置多次,如果是相对路径,则相对前一个 WORKDIR 命令比如:复制代码代码如下:WORKDIR /a WORKDIR b WORKDIR c RUN pwd其实是在 /a/b/c 下执行 pwd
CMD 命令有三种格式:复制代码代码如下:CMD ["executable","param1","param2"] (like an exec, preferred form)CMD ["param1","param2"] (as default parameters to ENTRYPOINT)CMD command param1 param2 (as a shell)一个Dockerfile里只能有一个CMD,如果有多个,只有最后一个生效。