九、Dockerfile语法

  在Dockerfile中定义了不少关键字,经过关键字来完成Dockerfile的编写。
  Dockerfile官方文档python

9.1 FROM

  在Dockerfile中FROM主要是指定这个Dockerfile基于哪个base image构建。Docker Dockerfile按顺序运行指令。一个Dockerfile 必须用FROM指令启动,放在第一行。mysql

FROM scratch        # 制做base image
FROM centos         # 使用base image
FROM ubuntu:14.04   # 使用指定版本的base image

安全起见,尽可能使用官方的image做为base image。sql

9.2 LABEL

  在Dockerfile中LABEL其实是英译了Metadata,就像是代码中的注释。主要包含了该镜像的做者、版本和描述信息。docker

LABEL maintainer="staryjie@163.com"
LABEL version="1.0"
LABEL description="This is description"

Metadata不可少!shell

9.3 RUN

  在Dockerfile中RUN用来运行命令,其中命令必须是在第一行FROM中指定的base image所能运行的。每运行一次RUN,构建的image都会生成新的一层layer。ubuntu

RUN yum update && yum install -y vim \
    python-dev                # 反斜杠换行
RUN apt-get update && apt-get install -y perl \
    pwgen --no-install-recommends && rm -rf \
    /var/lib/apt/lists/*      # 注意清理cache
RUN /bin/bash -C 'source $HOME/.bashrc;echo $HOME'

为了美观,复杂的RUN可使用反斜杠换行。
为了不无用分层,多条命令尽可能合并一行。vim

9.4 WORKDIR

  在Dockerfile中WORKDIR用来设定当前工做目录,相似Linux系统中的cd命令。centos

WORKDIR /root
WORKDIR /test        # 若是没有该目录,则会自动建立
WORKDIR demo
RUN pwd              # 输出的结果应该是/test/demo

用WORKDIR,不要使用RUN cd !!!
为了不出错,尽可能使用绝对路径。安全

9.4 ADD和COPY

  在Dockerfile中ADD和COPY做用类似,都是把本地的文件添加到docker image中。区别:ADD不只能够添加文件,还能够解压缩文件,COPY不能够解压缩文件。bash

ADD hello /
ADD test.tar.gz /        # 添加到image的根目录而且解压
WORKDIR /root
ADD hello test/          # 将hello添加到image的/root/test/hello
WORKDIR /root
COPY hello test/         # 跟上面的效果同样

大部分状况下COPY优于ADD。
ADD除了COPY还有额外功能(解压)。
添加远程文件/目录,请使用curl或者wget。

9.5 ENV

  在Dockerfile中ENV来设置环境变量或者一些常量。能够在ENV设置的常量后面直接使用。

ENV MYSQL_VERSION 5.6        # 设置常量
RUN apt-get install -y mysql-server="${MYSQL_VERSION}" \
    && rm -rf /var/lib/apt/lists/*        #引用常量

尽可能使用ENV增长可维护性!

9.6 VOLUME

  在Dockerfile中VOLUME用于向基于镜像建立的容器添加卷,一个卷能够存在于一个或多个容器的特定目录,这个目录能够绕过联合文件系统,并提供共享数据、数据持久化的功能。

VOLUME ["/data"]

9.7 EXPOSE

  在Dockerfile中EXPOSE设置容器暴露的端口,能够指定一个或多个端口。

EXPOSE 80

虽然在EXPOSE指令中已经暴露了指定的端口,可是在启动容器的时候仍是要指定端口信息,容器自己不会自动暴露端口。

9.8 CMD

  在Dockerfile中CMD设置容器启动后默认执行的命令和参数。若是定义了多个CMD,只会执行最后一个。

CMD ["executable","param1","param2"]        # 执行形式,这是首选形式
CMD ["param1","param2"]                     # 做为进入点的默认参数
CMD command param1 param2                   # 壳形式

不要定义多个CMD,多个CMD只有最后一个会执行。

9.9 ENTRYPOINT

  在Dockerfile中ENTRYPOINT设置容器启动时运行的命令,可让容器以应用程序或者服务器的形式运行,并且ENTRYPOINT设定的命令不会被忽略,必定会执行。

COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"]

能够写一个shell脚本做为ENTRYPOINT的入口。

RUN、CMD、ENTRYPOINT对比

  • RUN 执行命令并建立新的image layer
  • CMD 设置容器启动后默认执行的命令和参数
  • ENTRYPOINT 设置容器启动时运行的命令

shell格式和exec格式

  • shell格式
RUN apt-get install -y vim
CMD echo "hello docker"
ENTRYPOINT echo "hello docker"

  Dockerfile

FROM centos
ENV name Docker
ENTRYPOINT echo "hello $name"

  构建镜像:

docker build -t staryjie/centos-entrypoint-shell .

  运行容器:

docker run staryjie/centos-entrypoint-shell

hello Docker
  • exec格式
RUN ["apt-get","install","-y","vim"]
CMD ["/bin/echo","hello docker"]
ENTRYPOINT ["/bin/echo","hello docker"]

  Dockerfile

FROM centos
ENV name Docker
ENTRYPOINT ["/bin/echo","hello $name"]

  构建镜像:

docker build -t staryjie/centos-entrypoint-exec .

  运行容器:

docker run staryjie/centos-entrypoint-exec

hello $name

  改写Dockerfile

FROM centos
ENV name Docker
ENTRYPOINT ["/bin/bash","-c","echo hello $name"]

  构建镜像:

docker build -t staryjie/centos-entrypoint-exec-new .

  运行容器:

docker run staryjie/centos-entrypoint-exec-new

hello Docker
  1. CMD
    • 容器启动时默认执行的命令
    • 若是docker run指定了其余命令,CMD命令会被忽略
    • 若是定义了多个CMD,只有最后一个会执行
  2. ENTRYPOINT
    • 让容器以应用程序或者服务的形式运行
    • 不会被忽略,必定会执行
相关文章
相关标签/搜索