Dockerfile
Dockerfile是由一系列命令和参数构成的脚本,这些命令应用于基础镜像并最终创建一个新的镜像。它们简化了从头到尾的流程并极大的简化了部署工作。Dockerfile从FROM命令开始,紧接着跟随者各种方法,命令和参数。其产出为一个新的可以用于创建容器的镜像。
Dockerfile 语法
在我们深入讨论Dockerfile之前,让我们快速过一下Dockerfile的语法和它们的意义。
什么是语法?
非常简单,在编程中,语法意味着一个调用命令,输入参数去让应用执行程序的文法结构。这些语法被规则或明或暗的约束。程序员遵循语法规范以和计算机 交互。如果一段程序语法不正确,计算机将无法识别。Dockerfile使用简单的,清楚的和干净的语法结构,极为易于使用。这些语法可以自我释义,支持注释。
Dockerfile 语法示例
Dockerfile语法由两部分构成,注释和命令+参数
Line blocks used for commenting
command argument argument ..
一个简单的例子:
#Print "Hello docker!"
RUN echo "Hello docker!"
Dockerfile 命令
Dockerfile有十几条命令可用于构建镜像,下文将简略介绍这些命令。
ADD
ADD命令有两个参数,源和目标。它的基本作用是从源系统的文件系统上复制文件到目标容器的文件系统。如果源是一个URL,那该URL的内容将被下载并复制到容器中。
# Usage: ADD [source directory or URL] [destination directory]
ADD /my_app_folder /my_app_folder
CMD
和RUN命令相似,CMD可以用于执行特定的命令。和RUN不同的是,这些命令不是在镜像构建的过程中执行的,而是在用镜像构建容器后被调用。
# Usage 1: CMD application "argument", "argument", ..
CMD "echo" "Hello docker!"
ENTRYPOINT
配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。
每个 Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最后一个起效。
ENTRYPOINT 帮助你配置一个容器使之可执行化,如果你结合CMD命令和ENTRYPOINT命令,你可以从CMD命令中移除“application”而仅仅保留参数,参数将传递给ENTRYPOINT命令。
# Usage: ENTRYPOINT application "argument", "argument", ..
# Remember: arguments are optional. They can be provided by CMD
# or during the creation of a container.
ENTRYPOINT echo
# Usage example with CMD:
# Arguments set with CMD can be overridden during *run*
CMD "Hello docker!"
ENTRYPOINT echo
ENV
ENV命令用于设置环境变量。这些变量以”key=value”的形式存在,并可以在容器内被脚本或者程序调用。这个机制给在容器中运行应用带来了极大的便利。
# Usage: ENV key value
ENV SERVER_WORKS 4
EXPOSE
EXPOSE用来指定端口,使容器内的应用可以通过端口和外界交互。
# Usage: EXPOSE [port]
EXPOSE 8080
FROM
FROM命令可能是最重要的Dockerfile命令。改命令定义了使用哪个基础镜像启动构建流程。基础镜像可以为任意镜 像。如果基础镜像没有被发现,Docker将试图从Docker image index来查找该镜像。FROM命令必须是Dockerfile的首个命令。
# Usage: FROM [image name]
FROM ubuntu
MAINTAINER
我建议这个命令放在Dockerfile的起始部分,虽然理论上它可以放置于Dockerfile的任意位置。这个命令用于声明作者,并应该放在FROM的后面。
# Usage: MAINTAINER [name]
MAINTAINER authors_name
RUN
RUN命令是Dockerfile执行命令的核心部分。它接受命令作为参数并用于创建镜像。不像CMD命令,RUN命令用于创建镜像(在之前commit的层之上形成新的层)。
# Usage: RUN [command]
RUN aptitude install -y riak
USER
USER命令用于设置运行容器的UID。
# Usage: USER [UID]
USER 751
VOLUME
VOLUME命令用于让你的容器访问宿主机上的目录。
# Usage: VOLUME ["/dir_1", "/dir_2" ..]
VOLUME ["/my_files"]
WORKDIR
WORKDIR命令用于设置CMD指明的命令的运行目录。
# Usage: WORKDIR /path
WORKDIR ~/
最佳实践案例
案例一、生成Tomcat镜像
# cbss-web docker file from wangsucloud
# 增加tomcat启动参数设置优化项
# VERSION 1.1
# Author: wangsucloud
#基础镜像
FROM tomcat:stable
#作者
MAINTAINER wangsucloud <yaomh@wangsu.com>
#定义工作目录
ENV WORK_PATH /usr/local/tomcat/webapps
ENV BIN_PATH /usr/local/tomcat/bin
#修改时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
#修改tomcat运行参数
COPY ./catalina.sh $BIN_PATH/
#复制文件war包
COPY ./ROOT $WORK_PATH/cbss
案例二、生成Nginx镜像
# vi /data/docker/nginx/Dockerfile
# First docker file from yaomh
# VERSION 1.1
# Author: yaomh
#基础镜像
FROM nginx:latest
#作者
MAINTAINER yaomh <yaomh@wangsu.com>
#定义工作目录
ENV WORK_PATH /etc/nginx
ENV WEBAPPS_PATH /var/www
#定义conf文件名
ENV CONF_FILE_NAME nginx.conf
#修改时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
#删除原有配置文件
RUN rm $WORK_PATH/$CONF_FILE_NAME
#创建日志目录
RUN mkdir $WORK_PATH/logs
RUN mkdir $WEBAPPS_PATH
#复制新的配置文件
COPY ./$CONF_FILE_NAME $WORK_PATH/
COPY ./ams-client $WEBAPPS_PATH/ams-client
编译命令
#在Dockerfile所在目录编译生成docker镜像
docker build -t cbss-web:v2.5-beta-201810 .
执行后输出如下:
Step 1/8 : FROM tomcat:stable
---> 817bdf43f341
Step 2/8 : MAINTAINER wangsucloud yaomh@wangsu.com
---> Using cache
---> e726addd6af2
Step 3/8 : ENV WORK_PATH /usr/local/tomcat/webapps
---> Using cache
---> 07dd5bb77eaa
Step 4/8 : ENV BIN_PATH /usr/local/tomcat/bin
---> Using cache
---> de5c40da5ea4
Step 5/8 : ENV TZ Asia/Shanghai
---> Using cache
---> ad1f21de42dd
Step 6/8 : RUN ln -snf /usr/share/zoneinfo/TZ > /etc/timezone
---> Using cache
---> d061b4489847
Step 7/8 : COPY ./catalina.sh BIN_PATH/
---> Using cache
---> 73133f7c2b1a
Step 8/8 : COPY ./ROOT $WORK_PATH/cbss
---> 134ad3a9f842
Removing intermediate container 949961ca6c5b
Successfully built 134ad3a9f842
Successfully tagged cbss-web:v2.5-beta-201810
说明:
由于基础镜像均来自官方的镜像,官方镜像基于debian9系统的,系统时区上默认是US,直接启动容器将导致语言和编码格式的错乱,因此需要将编译环境的语言和时区配置映射到镜像中,另外在部署过程中需要建立镜像的WORK_PATH,才能将本地编译的程序部署到镜像中;最后为了监控和运维的需要还将日志文件输出到指定路径上便于文件卷的挂载使用。(完)