天天看点

Docker实践(四)Dockerfile

什么是Dockerfile?

使用Dockerfile,可以方便的创建自定义镜像。

基本结构

由一行行命令组成,支持#注释。Dockerfile一般分为四个部分:

  • 基础镜像信息
  • 维护者信息
  • 镜像操作指令
  • 容器启动指令

如下面是一个基础的Dockerfile

#dockerfile 使用centos作为基础镜像,基础镜像必须在第一行设置
FROM centos:7.2.1511
#维护人员,< weiha322 at 163.com>
MAINTAINER weihao322 [email protected]@163.com
#更新镜像的命令 安装nginx
RUN yum -y install nginx
#创建一个新容器的命令
CMD /usr/sbin/nginx
           

开始的第一行就应该先指定容器的基础镜像。接下来一般是说明维护者信息,后面是镜像的操作命令,对基础镜像进行改造,最后指定容器运行时的运行命令,即CMD命令

指令

指令的一般格式是INSTRUCTION arguments,指令包括FROM,MAINTAINER,RUN,CMD等,下面一一介绍。

FROM

一般格式是FROM <image>或者FROM <image>:<tag>,为容器指定基础镜像,Dockerfile的第一条指令必须是FROM指令,如果一个Dockerfile创建多个容器的话,可以使用多个FROM指令(每个镜像一次)

MAINTAINER

格式为 MAINTAINER <name>,指定Dockerfile的维护者信息

RUN

格式为 RUN <command>或RUN ["executable", "param1", "param2"],前者是在shell终端中运行命令,即/bin/sh -c;后者使用exec执行命令,指定使用其他终端可以通过第二种方式实现,如:RUN ["/bin/bash", "-c", "echo helloworld"]

每天RUN指令都是在基础镜像上执行指定命令并提交为新的命令,如果命令比较长时,使用\换行。

CMD

支持三种格式

CMD ["executable", "param1", "param2"]使用exec执行,推荐方式。

CMD command param1 param2在/bin/sh中执行,提供给需要交互的应用

CMD ["param1", "param2"]提供给ENTRYPOINT的默认参数

指定启动容器时执行的命令,每个Dockerfile只有一条CMD命令,如果一个容器制定了多条CMD命令,只有最后一条CMD命令会被执行。

如果用户启动容器是指定了运行的命令,会覆盖掉CMD指定命令。

EXPOSE

格式为 EXPOSE <port> [<port>…]。

告诉Docker服务端容器暴露的端口号,供互联系使用。在容器启动时需要通过-P,Docker主机会自动分配一个端口转发到指定的端口

ENV

格式为ENV <key> <value>。指定一个环境变量,会被后续RUN指令使用,并在容器运行时保持。

如:

ENV VERSION 7.2.1511
 RUN wget http://www.weihao.com/download/a.$VERSION.tar.gz
 ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH
           

ADD

格式为ADD <src> <dist>

ADD命令复制指定的src到容器中的dist目录,其中src可以是Dockerfile所在目录的一个相对路径,也可以是一个URL,也可以是一个tar文件,自动解压为目录

COPY

格式为 COPY <src> <dist>

复制本地主机的src目录(Dockerfile所在目录的相对路径)到容器中的dist目录

当时用本地目录为源目录时,推荐使用COPY

ENTRYPOINT

格式有两种

ENTRYPOINT ["executable", "param1" ,"param2"]

ENTRYPOINT command param1 param2 (在shell中执行)

配置容器启动后执行的命令,并且不可为docker run提供的参数覆盖,每个Dockerfile中只有一个ENTRYPOINT,当指定多个ENTRYPOINT时,最后一个生效

VOLUME

格式为 VOLUME ["/data"]

创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库,和需要保持的数据。

USER

格式为USER daemon

指定容器运行时的用户名或者UID,后续的RUN也会使用指定用户

当服务不需要管理员权限时,可以通过该命令指定运行用户,并且可以在之前创建所需要的用户,例如:RUN groupadd -r mysql && useradd -r -g mysql mysql,需要临时获取管理员权限,可以通过gosu,不推荐使用sudo。

WORKDIR

格式为 WORKDIR /path/to/workdir

为后续的RUN,CMD,ENTRYPOINT指令配置工作目录

可以使用多个WORKDIR命令,后续命令参数如果是相对路径,则会基于之前的命令指定目录

WORKDIR /a

WORKDIR b

WORKDIR c

ONBUILD

格式为 ONBUILD [instruction]

配置当前所创建的镜像作为其他镜像的基础镜像时,所执行的操作命令,如imageA包含ONBUILD命令如下:

[…]

ONBUILD ADD . /app/src

ONBUILD RUN /usr/local/bin/python-build --dir /app/src

[…]
           

如果基于imageA创建imageB时,在新的Dockerfile中使用FROM imageA指定基础镜像时,就会自动执行ONBUILD命令的内容。等价于在imageB的Dockerfile后面添加两条命令。如下:

FROM imageA

#自动执行

ADD . /app/src

RUN /usr/local/bin/python-build --dir /app/src
           

使用ONBUILD指令的镜像,推荐在标签中注明,如:ruby:1.9-onbuild

创建镜像

编写完成Dockerfile后,可以使用docker build命令来创建镜像。命令基本格式为docker build [选项] [路径]。

这个命令读取指定目录下的Dockerfile文件,并将路径下的所有内容发送给docker,由docker来创建镜像,因此指定目录下一般不要有其他不相关的文件,docker提供了.dockerignore机制来让提交到docker时忽略掉某些文件,.dockerignore文件每一行添加一个匹配格式。

要指定镜像的标签信息,可以通过-t命令来指定,如:

docker build -t myapp .