文章目录
1. Dockerfile的结构
- 基础镜像信息
- 维护者信息
- 镜像操作指令
- 容器启动时默认要执行的指令
Dockerfile 是一个文本文件,其内包含了一条条的指令,它也支持以 # 开头的注释行。
Dockerfile 描述了组装镜像的步骤,其中每条指令都是单独执行的。除了FROM指令,其他每一条指令都会在上一条指令所生成镜像的基础上执行,执行完后会生成一个新的镜像层,新的镜像层覆盖在原来的镜像之上从而形成了新的镜像。Dockerfile所生成的最终镜像就是在基础镜像上面叠加一层层的镜像层组件的。
Dockerfile 文件本身是不区分大小写的,但是为了统一,一般指令都写成大写。
2. 常用的指令
2.1 FROM
语法:FROM <image>
第一条指令必须为FROM指令。并且,如果在同一个Dockerfile中创建多个镜像时,可以使用多个FROM指令(每个镜像一次)。
2.2 LABL MAINTAINER
语法:LABL MAINTAINER <name email_address>
构建镜像的作者信息,姓名+邮箱。
2.3 RUN
语法:RUN <command>
或RUN ["executable","param1","param2"]
构建镜像需要执行的命令,前者将在shell终端中运行命令,即/bin/sh -c;后者则使用exec执行。
每条RUN指令将在当前镜像基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用 \ 来换行。
2.4 ADD
语法:ADD <src> <dest>
该命令将复制指定的 <src>
到容器中的<dest>
。其中可以是Dockerfile所在目录的一个相对路径(文件或目录);也可以是一个URL;还可以是一个tar文件(会自动解压为目录)。
2.5 COPY
语法:COPY <src> <dest>
与ADD有点相似。复制本地主机的 <src>
(为Dockerfile所在目录的相对路径,文件或目录)为容器中的<dest>
。目标路径不存在时会自动创建。
复制的内容是目录时,推荐使用COPY。
2.6 WORKDIR
语法:WORKDIR /path/to/workdir
就是Linux系统中的 cd 指令,可以使用多个WORKDIR指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。
2.7 VOLUME
语法:VOLUME ["/data"]
创建一个可以从本地主机或其他容器挂载的目录,一般用来存放数据库和需要保持的数据等。
2.8 USER
语法:USER daemon
指定运行容器时的用户名或UID,后续的RUN也会使用指定用户。指定的用户必须要事先创建好。
例如:
RUN groupadd -r redis && useradd -r -g redis redis
USER redis
RUN [ "redis-server" ]
2.9 ONBUILD
语法:ONBUILD [INSTRUCTION]
ONBUILD 是一个特殊的指令,它后面跟的是其它指令,比如 RUN , COPY 等,而这些指令,在当前镜像构建时并不会被执行。只有当以当前镜像为基础镜像,去构建下一级镜像的时候才会被执行。
2.10 ENV
语法:ENV <key> <value>
设置环境变量,无论是后面的其它指令,如 RUN ,还是运行时的应用,都可以直接使用这里定义的环境变量。
例如:
ENV version 2.4.43
RUN cd /usr/src/httpd-$version
2.11 ENTRYPOINT
语法1:ENTRYPOINT ["executable","param1","param2"]
语法2:ENTRYPOINT command param1 param2(在shell中执行)
配置容器启动后执行的命令,并且不可被docker run提供的参数覆盖。而且,如果在docker run的后面提供了参数,这些命令行参数会被当作参数传递给ENTRYPOINT指定的程序。
每个Dockerfile中只能有一个ENTRYPOINT,当指定多个ENTRYPOINT时,只有最后一个生效。
ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数。ENTRYPOINT 在运行时也可以替代,不过比 CMD 要略显繁琐,需要通过 docker run 的参数 –entrypoint 来指定。
当指定了 ENTRYPOINT 后, CMD 的含义就发生了改变,不再是直接的运行其命令,而是将CMD 的内容作为参数传给 ENTRYPOINT 指令,换句话说实际执行时,将变为:<ENTRYPOINT> "<CMD>"
2.12 EXPOSE
语法:EXPOSE <port> [<port>...]
EXPOSE 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。在 Dockerfile 中写入这样的声明有两个好处,一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
在启动容器时通过-P,Docker主机会自动分配一个端口转发到指定的端口;
使用-p则可以具体指定哪个本地端口映射过来。
3. 使用Dockerfile构建镜像
语法:docker build [选项] 路径
该命令将读取指定路径下(包括子目录)的Dockerfile,并将该路径下所有内容发送给Docker服务端,由服务端来创建镜像。因此一般建议放置Dockerfile的目录为空目录。
另外,可以通过 .dockerignore 文件(每一行添加一条匹配模式)来让Docker忽略路径下的目录和文件。
要指定镜像的标签信息,可以通过-t选项。
例如,指定Dockerfile所在路径为/tmp/docker_builder/,并且希望生成镜像标签为build_repo/first_image,可以使用下面的命令:
docker build -t build_repo/first_image /tmp/docker_builder/