Dockerfile

Dockerfile是由一系列命令和参数构成的脚本,这些命令应用于基础镜像并最终创建一个新的镜像。它们简化了从头到尾的流程并极大的简化了部署工作。Dockerfile从FROM命令开始,紧接着跟随者各种方法,命令和参数。其产出为一个新的可以用于创建容器的镜像。

Dockerfile 语法

在我们深入讨论Dockerfile之前,让我们快速过一下Dockerfile的语法和它们的意义。

什么是语法?

非常简单,在编程中,语法意味着一个调用命令,输入参数去让应用执行程序的文法结构。这些语法被规则或明或暗的约束。程序员遵循语法规范以和计算机 交互。如果一段程序语法不正确,计算机将无法识别。Dockerfile使用简单的,清楚的和干净的语法结构,极为易于使用。这些语法可以自我释义,支持注释。

Dockerfile 语法示例

Dockerfile语法由两部分构成,注释和命令+参数

  1. # Line blocks used for commenting
  2. command argument argument ..

一个简单的例子:

  1. # Print "Hello docker!"
  2. RUN echo "Hello docker!"

Dockerfile 命令

Dockerfile有十几条命令可用于构建镜像,下文将简略介绍这些命令。

ADD

ADD命令有两个参数,源和目标。它的基本作用是从源系统的文件系统上复制文件到目标容器的文件系统。如果源是一个URL,那该URL的内容将被下载并复制到容器中。

  1. # Usage: ADD [source directory or URL] [destination directory]
  2. ADD /my_app_folder /my_app_folder 

CMD

和RUN命令相似,CMD可以用于执行特定的命令。和RUN不同的是,这些命令不是在镜像构建的过程中执行的,而是在用镜像构建容器后被调用。

  1. # Usage 1: CMD application "argument", "argument", ..
  2. CMD "echo" "Hello docker!"

ENTRYPOINT

配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。

每个 Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最后一个起效。

ENTRYPOINT 帮助你配置一个容器使之可执行化,如果你结合CMD命令和ENTRYPOINT命令,你可以从CMD命令中移除“application”而仅仅保留参数,参数将传递给ENTRYPOINT命令。

  1. # Usage: ENTRYPOINT application "argument", "argument", ..
  2. # Remember: arguments are optional. They can be provided by CMD
  3. # or during the creation of a container.
  4. ENTRYPOINT echo
  5. # Usage example with CMD:
  6. # Arguments set with CMD can be overridden during *run*
  7. CMD "Hello docker!"
  8. ENTRYPOINT echo

ENV 

ENV命令用于设置环境变量。这些变量以”key=value”的形式存在,并可以在容器内被脚本或者程序调用。这个机制给在容器中运行应用带来了极大的便利。

  1. # Usage: ENV key value
  2. ENV SERVER_WORKS 4

 

EXPOSE

EXPOSE用来指定端口,使容器内的应用可以通过端口和外界交互。

  1. # Usage: EXPOSE [port]
  2. EXPOSE 8080

FROM

FROM命令可能是最重要的Dockerfile命令。该命令定义了使用哪个基础镜像启动构建流程。基础镜像可以为任意镜 像。如果基础镜像没有被发现,Docker将试图从Docker image index来查找该镜像。FROM命令必须是Dockerfile的首个命令。

  1. # Usage: FROM [image name]
  2. FROM ubuntu 

MAINTAINER

我建议这个命令放在Dockerfile的起始部分,虽然理论上它可以放置于Dockerfile的任意位置。这个命令用于声明作者,并应该放在FROM的后面。

  1. # Usage: MAINTAINER [name]
  2. MAINTAINER authors_name 

RUN

RUN命令是Dockerfile执行命令的核心部分。它接受命令作为参数并用于创建镜像。不像CMD命令,RUN命令用于创建镜像(在之前commit的层之上形成新的层)。

  1. # Usage: RUN [command]
  2. RUN aptitude install -y riak

USER

USER命令用于设置运行容器的UID。

  1. # Usage: USER [UID]
  2. USER 751

VOLUME

VOLUME命令用于让你的容器访问宿主机上的目录。

  1. # Usage: VOLUME ["/dir_1", "/dir_2" ..]
  2. VOLUME ["/my_files"]

WORKDIR

WORKDIR命令用于设置CMD指明的命令的运行目录。

  1. # Usage: WORKDIR /path
  2. WORKDIR ~/

copy

COPY 是用于复制本地主机的(为 Dockerfile 所在目录的相对路径)到容器中的。

当使用本地目录为源目录时,推荐使用 COPY 。一般格式为 COPY。

例如我们要拷贝当前目录到容器中的 /app 目录下,我们可以这样操作

    1. COPY . /app

如何使用Dockerfiles

使用Dockerfiles和手工使用Docker Daemon运行命令一样简单。脚本运行后输出为新的镜像ID。

    1. # Build an image using the Dockerfile at current location
    2. # Example: sudo docker build -t [name] .
    3. sudo docker build -t my_mongodb . 

ADD和COPY区别

Dockerfile中的COPY指令和ADD指令都可以将主机上的资源复制或加入到容器镜像中,都是在构建镜像的过程中完成的。

COPY指令和ADD指令的唯一区别在于是否支持从远程URL获取资源。COPY指令只能从执行docker build所在的主机上读取资源并复制到镜像中。而ADD指令还支持通过URL从远程服务器读取资源并复制到镜像中。

满足同等功能的情况下,推荐使用COPY指令。ADD指令更擅长读取本地tar文件并解压缩。

使用Dockerfile创建web应用范例

FROM tomcat
MAINTAINER suxiaodong 793119251@qq.com
ADD unzip_war /usr/local/tomcat/webapps/
EXPOSE 8080
CMD ["/usr/local/tomcat/bin/catalina.sh", "run"]
docker build -t ord-demo:v1
docker run -p 8080:8080 ord-demo:v1

 java 范例

FROM xxxx:8021/public/java:8u_112
ADD ctg-ag-server-2.5.0-SNAPSHOT.tar.gz /ag/server
RUN chmod a+x /ag/server/startup.sh
RUN export AG_HOME=/ag/server
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
CMD sh /ag/server/startup.sh cluster.aep.xml