Dockerfile入门

Dockerfile


Dockerfile 是一个文本格式的配置文件,用户可以使用 Dockerfile 来快速创建自定义的镜像

--内容参考 《Docker技术入门与实战第2版

Dockerfile 由一行行命令语句组成,并且支持 # 开头的注释行

 

目录

Dockerfile

1.预览

2.指令说明

2.1 FROM

2.2 MAINTAINER

2.3 RUN

2.4 CMD

2.5 LABEL

2.6 EXPOSE

2.7 ENV

2.8 ADD

2.9 COPY

2.10 ENTRYPOINT

2.11 VOLUME

2.12 USER

2.13 WORKDIR

2.14 ARG

2.15 ONBUILD

2.16 STOPSIGNAL

2.17 HEALTHCHECK

2.18 SHELL

3.创建镜像

4.使用 .dockerignore 文件

5.实践经验

经验


 

 

1.预览

一般而言,Dockerfile 分为四个部分:基础镜像信息维护者信息镜像操作指令和容器启动时执行指令

 # This Dockerfile uses the centos image
 # VERSION 2 - EDITION 1
 # Author : Dcpnet
 # Command dormat : Instruction [arguments / command] ..
 # Base image to user , this must be set as the first line
 FROM ubuntu
 # Maintainer : dcpnet <dcpnet at email.com> (@dcpnet)
 MAINTAINER dcpnet dcpnet@815787213@qq.com
 # Commands to update the image
 RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/sources.list
 RUN apt-get update && apt-get install -y nginx
 RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf
 # Commands when creating a new container
 CMD /usr/sbin/nginx

 

2.指令说明

指令的一般格式为 INSTRUCTION arguments

指令包括:FROMMAINTAINERRUN

指令说明
FROM指定所创建镜像的基础镜像
MAINTAINER指定维护者的信息
RUN运行命令
CMD指定启动容器时默认执行的命令
LABEL指定生成镜像的元数据标签信息
EXPOSE生命镜像内服务所监听的端口
ENV指定环境变量
ADD复制指定的 <src> 路径下的内容到容器中的 <dest> 路径下,<src>可以为URL;如果为tar文件,会自动解压到<dest>路径下
COPY复制本地主机的 <src> 路径下的内容到镜像中的 <dest> 路径下;一般情况下推荐使用 COPY,而不是 ADD
ENTRYPOINT指定镜像的默认入口
VOLUME创建数据卷挂载点
USER指定运行容器时的用户名或UID
WORKDIR配置工作目录
ARG指定镜像内使用的参数(例如版本信息等)
ONBUILD配置当所创建的镜像作为其他镜像的基础镜像时,所执行的创建操作指令
STOPSIGNAL容器退出时的信号值
HEALTHCHECK如何进行健康检查
SHELL指定使用 shell 时的默认 shell 类型

 

2.1 FROM

指定所创建镜像的基础镜像,如果本地不存在,则默认会去 Docker Hub 下载指定镜像

三种格式

 FROM <image>
 FROM <image>:<tag>
 FROM <image>@<digest>

任何 Dockerfile 中的第一条指令必须为 FROM 指令。并且,如果在同一个 Dockerfile 中创建多个镜像,可以使用多个 FROM 指令(每个镜像一次)

 

2.2 MAINTAINER

指定维护者信息

格式 MAINCONTAINER <name>

 MAINCONTAINER dcpnet@815787213@qq.com

该信息会写入 镜像的 Author 属性域中

 

2.3 RUN

格式为 : RUN <command> RUN["executable","param1","param2"]

注意,后一个指令会被解析为 Json 数组,因此必须使用双引号。

前者默认将在 shell 终端中运行命令 , 即 /bin/sh -c

后者则使用 exec 执行,不会启动 shell 环境

指定使用其他终端类型可是使用第二种方式实现:

 RUN ["/bin/bash","-c","echo Hello"]

每条 RUN 指令将在当前镜像的基础上执行指定命令,并提交为新的镜像。当命令较长时,可以使用 \ 来换行:

 RUN apt-get update \
         && apt-get install -y libsnappy-dev zliblg-dev libbz2-dev \
         && rm -rf /var/cache/apt

 

2.4 CMD

CMD 指令用来指定启动容器时默认执行的命令

支持三种格式:

  1.  # 使用 exec 执行,是推荐使用的方式
     CMD ["executable","param1","param2"]
     
  2.  # 在 /bin/sh 中执行,提供给需要交互的应用
     CMD command param1 param2
     
  3.  # 提供给 ENTRYPOINT 的默认参数
     CMD ["param1","param2"]
     

每个 Dockerfile 只能有一条 CMD 命令,如果有多条,则只有最后一条有效

如果拥堵启动容器时收订制定了运行的命令(作为 run 的参数),则会覆盖掉 CMD 指定的命令

 

2.5 LABEL

LABLEL 指令用来指定生成井下过的元数据标签信息

格式 LABEL <key>=<value><key>=<value><key>=<value>...

 LABEL version="1.0"
 LABEL description="This is a Test Label."

 

2.6 EXPOSE

生命镜像内服务所监听的端口

格式 EXPOSE <port>[<port>...]

 EXPOSE 22 80 8443

该指令只是起到神明的作用,并不会自动完成端口映射

在启动容器的时候需要

  • 使用 -P ,Docker 著聚会自动分配一个宿主注解临时端口转发到指定的端口

  • 使用-p,则可以具体指定那个宿主机的本地端口会映射过来

 

2.7 ENV

指定环境变量,在镜像生成过程中会被后续 RUN 指令使用,在镜像启动的容器中也会存在

格式 ENV <key> <value>ENV <key>=<value>

 ENV PG_MAJOR 9.3
 ENV PG_VERSION 9.3.4
 RUN curl -SL http://example.com/postgres-^PG_VERSION.tar.xz | tar -xJC /usr/src/posrfres && ...
 ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH

指令指定的环境变量在运行时可以被覆盖掉 ,如 docker run --env <key>=<value> build_image

 

2.8 ADD

该命令将复制指定的 <src> 路径下的内容到容器中的 <dest> 路径下

格式 ADD <src> <dest>

其中 <src> 可以实 Dockerfile 所在目录的一个相对路径(文件或目录),也可以是一个 URL,还可以是一个 tar 文件 (如果是 tar 文件,会自动解压到 <dest> 路径下)。<dest> 可以实镜像内的绝对路径,或者是相对于工作目录 (WORKDIR) 的相对路径.

路径支持正则格式

 ADD *.c /code/

 

2.9 COPY

格式为 COPY <src> <dest>

复制本地的 <src> (为 Dockerfile 所在目录的相对路径、文件或目录) 下的内容到镜像中 <dest> 下。目标路径不存在时,会自动创建。

路径同样支持正则格式

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

 

2.10 ENTRYPOINT

指定镜像的默认入口命令,该入口命令会在启动容器时作为跟命令执行,所有传入值作为该命令的参数

支持两种格式

 # 第一种 exec 调用执行
 ENTRYPOINT ["executable","param1","param2"]
 # 第二种 shell 中执行
 ENTRYPOINT command param1 param2

此时 ,CMD 指令指定值将作为根命令的参数

【注】每个 Dockerfile 中只能有一个 ENTRYPOINT ,当指定多个,只有最后一个生效

在运行时,可以被 --entrypoint 参数覆盖掉,如

 docker run --entrypoint

 

2.11 VOLUME

创建一个数据卷挂载点

格式为 VOLUME ["/data"]

可以从本地主机或者其他容器挂载数据卷,一般用来存放数据库和需要保存的数据等。

 

2.12 USER

指定运行容器时的用户名或 UID,后续的 RUN 等指令也会使用指定的用户身份。

格式 USER daemon

放服务不需要管理员权限时,可以通过命令指定运行用户,并且可以在之前创建所需要的用户

 RUN troupadd -r postgres && useradd -r -g postgres postgres

幺零是获取管理员权限可以使用 gosu 或者 sudo

 

2.13 WORKDIR

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

格式为 WORKDIR /path/to/workdir

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

 WORKDIR /a
 WORKDIR b
 WORKDIR c
 RUN pwd
 # 最终路径 /a/b/c

 

2.14 ARG

制定一些镜像内使用的参数(版本号信息等),这些参数在指定 docker build 命令时才以 --build-arg <varname>=<value> 格式传入

格式为 ARG <name>[=<default value>]

则可以使用 docke build-build-arg <name>=<value>

 

2.15 ONBUILD

配置当所创建的镜像作为其他镜像的基础镜像时,所执行的创建操作指令

格式为 ONBUILD [INSTRUCTION]

例如,Dockerfile 使用如下的内容创建了镜像 image-A

 [...]
 ONBUILD ADD . /app/src
 ONBUILD RUN /usr/local/bin/python-build --dir /app/src
 [...]

如果基于 image-A 创建新的竟像是,新的 Dockerfile 中使用 From image-A 指定基础镜像自动执行 ONBUILD 指定的那日容,等价于在后面添加了两条指令

 FROM image-A
 # Auromatically run the following
 ADD . /app/src
 RUN /usr/local/bin/python-build --dir /app/src

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

 

2.16 STOPSIGNAL

指定所创建镜像启动的容器接受退出的信号值

 STOPSIGNAL signal

 

2.17 HEALTHCHECK

配置所启动容器如何进行健康检查(如何判断健康与否),自 Docker 1.12开始支持

格式

 # 根据所执行命令返回值是否为 0 来判断
 HEALTHCHECK [OPTONS] CMD command
 
  • HEALTHCHECK [OPTIONS ] CMD command : 根据所执行命令返回值是否为 0 来判断

  • HEALTHCHECK NONE:禁止基础镜像中的健康检查

OPTION :

  1. --interval=DURATION (默认为30s):过多久检查一次

  2. --timeout=DURATION(默认为30s):每次检查等待结果的超时

  3. --retries(默认为3):如果失败了,重试几次才确定失败

 

2.18 SHELL

指定其他命令使用 shell 时的默认 shell 类型

默认值为 ["/bin/bash","-c"]

 

对于 Windows 系统,建议在 Dockerfile 开头添加 #escape= 来指定转义信息

 

3.创建镜像

编写完 Dockerfile 之后,可以通过 docker build 命令来创建镜像。

基本的格式为 : docker build [选项] 内容 路径

该命令读取指定路径下(包括子目录)的 Dokcerfile ,并将给路径下的所有内容发送给 Docker 服务端,由服务端来创建镜像。因此除非生成镜像需要,否则一般建议放置 Dockerfile 的目录为空目录。

如果使用非内容路径下的 Dockerfile ,可以通过 -f 选项来指定其路径

要指定生成镜像的标签信息,可以使用 -t 选项

eg. 指定 Dockerfile 所在路径为 /temp/docker_builder/ ,并且希望申城镜像标签为 build_repo/first_image:

 docker build -t build_repo/first_image /temp/docker_builder/

 

4.使用 .dockerignore 文件

可以通过 .dockerignore 文件(每一行添加一条匹配模式) 来让 Docker 忽略匹配模式路径下的目录和文件:

 # comment
     */temp*
     */*/temp*
     temp?
     ~*

 

5.实践经验

在实际开发中,根据需求要对镜像等进行配置和选择。

所以要对每个指令的含义和执行效果要有一个比较清晰的理解,自己多编写一些例子进行测试,弄清楚了在撰写正式的 Dockerfile 。此外,Docker Hub 官方仓库提供了大量的优秀镜像和对应的 Dockerfile,可以通过阅读他们来学习如何撰写高效的 Dockerfile

经验

  1. 精简镜像用途:尽量让每个镜像的用途都比较机中、单一,避免构造大而复杂、多功能的镜像

  2. 选用合适的镜像:过大的基础镜像会造成臃肿的镜像,一般推荐较小的 debian 镜像

  3. 提供足够清晰的命令注释和维护者信息:Dockerfile 也是一种代码,需要考虑方便后续拓展和他人使用

  4. 正确使用版本号:使用明确的版本号信息,如 1.0、2.0,而非 latest,将避免内容不一致可能引发的惨案

  5. 减小镜像层数:如果希望所生成镜像的层数尽量少,则要尽量合并指令,例如多个 RUN 指令可以合并为一条。

  6. 及时删除临时文件和缓存文件: 特别是在执行 apt-get 指令后, /var/cache/apt 下会缓存一些安装包

  7. 提高生成速度:如合理使用缓存,减少内容目录下的文件,或使用 .dockerignore 文件指定等

  8. 调整合理的指令顺序:在开启缓存的情况下,内容不变的指令尽量放在前面,这样可以尽量复用

  9. 减少外部源的干扰:如果确实要从外部引入数据,需要指定持久的地址,并带有版本信息,让他人可以重复而不出错

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值