什么是Dockerfile?
使用Dockerfile,可以方便的创建自定义镜像。
基本结构
由一行行命令组成,支持#注释。Dockerfile一般分为四个部分:
- 基础镜像信息
- 维护者信息
- 镜像操作指令
- 容器启动指令
如下面是一个基础的Dockerfile
#dockerfile 使用centos作为基础镜像,基础镜像必须在第一行设置
FROM centos:7.2.1511
#维护人员,< weiha322 at 163.com>
MAINTAINER weihao322 weihao@322@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 .
完