Bootstrap

Docker基础入门(三) - 构建Dockerfile详解


上一篇: Docker基础入门(二) - Docker指令(最详细)
详细介绍了Docker的常用指令,包括 拉取镜像构建基本的Dockerfile文件构建镜像启动容器停止容器等常用的操作。

相信大家已经对Docker的整体构建和使用流程,已经有了较为全面的了解。接下来我们将详细介绍以下如何构建功能更加丰富的Dockerfile文件。

俗话说:“工欲善其事,必先利其器”,只有熟练掌握了Dockerfile的构建,才能更好地使用Docker来构建和管理我们的应用。

构建Dockerfile详解

1. 简介

Dockerfile 是一个文本文件,其中包含了一系列命令,这些命令用于构建一个Docker镜像。Dockerfile中的命令会按照顺序执行,每一条命令都会创建一个新的镜像层,并将该层添加到之前的镜像之上。最终,Dockerfile中的所有命令都会生成一个最终的镜像。

2. 基本结构

一个基本的Dockerfile通常包含以下几个部分:

  1. 基础镜像:指定一个已有的镜像作为基础镜像,例如FROM ubuntu:latest
  2. 维护者信息:指定维护者的信息,例如MAINTAINER [email protected]
  3. 环境变量:设置环境变量,例如ENV PATH /usr/local/bin:$PATH
  4. 工作目录:设置工作目录,例如WORKDIR /app
  5. 复制文件:将本地的文件复制到镜像中,例如COPY . /app
  6. 安装软件包:使用包管理器安装软件包,例如RUN apt-get update && apt-get install -y python3
  7. 设置启动命令:设置容器启动时执行的命令,例如CMD ["python3", "app.py"]

示例
下面是一个简单的Dockerfile示例,用于构建一个基于Python的Web应用:

# 使用官方Python运行时作为父镜像
FROM python:3.7-slim

# 设置工作目录
WORKDIR /app

# 将当前目录内容复制到容器的/app目录中
COPY . /app

# 安装依赖
RUN pip install --no-cache-dir -r requirements.txt

# 设置环境变量
ENV NAME World

# 暴露容器的5000端口
EXPOSE 5000

# 定义容器启动时执行的命令
CMD ["python3", "app.py"]

3. 指令详解

Dockerfile 中常用的指令有很多,下面我们详细介绍其中一些常用的指令。

Dockerfile 指令说明
FROM指定基础镜像
LABEL为镜像添加元数据
RUN容器构建时需要运行的命令
CMD指定容器创建时的默认命令(可以被覆盖)
ENTRYPOINT设置容器创建时的主要命令。(不可被覆盖)
EXPOSE声明容器运行时监听的端口
ENV设置容器内部环境变量
ADD将宿主机目录下的文件复制到容器中,如果是压缩包会自动解压
COPY将宿主机目录下的文件复制到容器中,不会自动解压
VOLUME为容器数据卷,用于数据持久化
WORKDIR指定在创建容器后,终端默认登录进来的工作目录
USER指定运行容器时的用户
ARG构建参数,与 ENV 作用一致,不过作用域不一样,ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量
ONBUILD当构建一个被继承的 Dockerfile 时,指定所执行的内容
STOPSIGNAL设置发送给容器以退出的系统调用信号
HEALTHCHECK定义周期性检查容器健康状态的命令
SHELL覆盖Docker中默认的shell,用于RUN、CMD和ENTRYPOINT指令

3.1 FROM

FROM指令用于指定基础镜像,是Dockerfile中的第一条指令,必须放在文件开头。例如:

FROM ubuntu:latest

这将从Docker Hub上拉取最新的Ubuntu镜像作为基础镜像。

3.2 MAINTAINER

MAINTAINER指令用于指定维护者的信息,例如:

MAINTAINER [email protected]

这将在镜像的元数据中添加维护者的信息。

3.3 LABEL

LABEL指令用于为镜像添加元数据,例如:

LABEL version="1.0" description="My Docker image" maintainer="[email protected]"

这将在镜像的元数据中添加版本、描述和维护者的信息。

3.4 RUN

RUN指令用于在容器中执行命令。
有两种格式:

  • shell格式:RUN <command>,相当于在终端操作shell命令。例如:
RUN apt-get update && apt-get install -y python3
  • exec格式:RUN ["executable", "param1", "param2"],等价于RUN /bin/sh -c executable param1 param2

例如:

RUN ["apt-get", "update", "&&", "apt-get", "install", "-y", "python3"]

注意:
RUN 指令在构建镜像时执行会创建一个新的镜像层。因此,过多无关的RUN指令会增加镜像的大小,建议将多个RUN指令合并为一个RUN指令。
例如:

RUN apt-get update 
RUN apt-get install -y python3 
RUN apt-get clean

以上执行会创建3个镜像层,而使用’&&'符号连接命令合并为一个RUN指令后,只会创建1个镜像层。

RUN apt-get update && apt-get install -y python3 && apt-get clean

3.5 CMD

类似于RUN指令。
之间的区别,简单来说就是:

  • RUN指令是在构建镜像时执行,
  • CMD指令是在容器启动时执行。

作用:

  • 为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束(即容器退出,无法使用exec方式进入容器内)。

注意:

  • CMD 指令指定的程序可被 docker run 命令行参数覆盖。
  • CMD 指令只能存在一个,如果有多个,只有最后一个生效。

例如:

CMD ["python3", "app.py"]

这将在容器启动时执行python3 app.py命令。

如果在运行容器时指定了其他命令,例如:

docker run -it my-python-app python3 app2.py

这将在容器启动时执行`python3 app2.py`命令。

3.6 ENTRYPOINT

类似于CMD指令,然而ENTRYPOINT指令指定的命令,一般来说是不能被docker run命令行参数指定的指令所覆盖,而且这些命令行参数会被当做参数送给ENTRYPOINT指令指定的命令。

但是,但是,但是,倘若docker run命令行中指定了-entrypoint指令的话,ENTRYPOINT指令指定的命令将会被docker run命令行参数指定的指令覆盖。

注意:

  • ENTRYPOINT指令只能存在一个,如果有多个,只有最后一个生效。
  • 运行docker run时候可以指定 ENTRYPOINT 运行所需的参数。

格式:

ENTRYPOINT ["python3", "app.py"]

3.7 EXPOSE

EXPOSE指令用于声明容器运行时监听的端口,例如:

EXPOSE 5000

这将在容器中声明监听5000端口。

作用:

  • 帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
  • 在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。

3.8 ENV

ENV指令用于设置环境变量,例如:

ENV MY_VAR=myvalue

这将在容器中设置一个名为MY_VAR的环境变量,其值为myvalue

作用:

  • 用来指定某个环境变量,会被后续RUN指令使用,并在容器运行时保持。
  • 在镜像构建时设置环境变量,在容器运行时使用。

3.9 ADD

ADD指令用于将文件或目录复制到镜像中,例如:

ADD app.py /app/

这将在镜像中创建一个名为/app/的目录,并将app.py文件复制到该目录中。

作用:

  • 将宿主机的文件复制到镜像中。
  • 将远程文件复制到镜像中。
  • 将URL下载的文件复制到镜像中。
  • 将压缩文件解压到镜像中。

3.10 COPY

COPY指令与ADD指令类似,用于将文件或目录复制到镜像中,例如:

COPY app.py /app/

ADD指令和COPY指令的使用格式类似,功能类似,区别在于:

  • ADD指令会自动处理URL和压缩文件。
  • COPY指令只会复制文件,不会处理URL和压缩文件。

3.11 VOLUME

VOLUME指令用于创建一个挂载点,例如:

VOLUME /data

这将在镜像中创建一个名为/data的挂载点。
在启动容器时,可以使用-v参数将宿主机上的目录挂载到该挂载点上,可以通过-v参数修改挂载点路径。

作用:

  • 将容器内的目录挂载到宿主机上,以便持久化存储数据。
  • 将容器内的目录挂载到其他容器上,以便共享数据。

3.12 WORKDIR

WORKDIR指令用于设置工作目录,例如:

WORKDIR /app

这将在镜像中设置工作目录为/app

作用:

  • 设置工作目录,后续的RUN、CMD、ENTRYPOINT指令都会在该目录下执行。
  • 如果目录不存在,会自动创建。

3.13 USER

USER指令用于设置运行容器时的用户,例如:

USER myuser

这将在镜像中设置运行容器时的用户为myuser

作用:

  • 设置运行容器时的用户,以便限制权限。
  • 如果用户不存在,会自动创建。

3.14 ARG

ARG指令用于定义构建参数,例如:

ARG MY_VAR=myvalue

这将在镜像中定义一个名为MY_VAR的构建参数,其默认值为myvalue

作用:

  • 定义构建参数,可以在构建镜像时通过--build-arg参数指定参数值。
  • 用来传递在构建过程中需要的参数。

3.15 ONBUILD

ONBUILD指令用于定义镜像触发器,例如:

ONBUILD RUN echo "This is an ONBUILD trigger"

这将在镜像被用作基础镜像时触发,执行RUN echo "This is an ONBUILD trigger"命令。

作用:

  • 定义镜像触发器,当镜像被用作基础镜像时,会自动执行触发器中的命令。
  • 用来实现镜像的继承和扩展。

3.16 STOPSIGNAL

STOPSIGNAL指令用于设置容器停止时发送的信号,例如:

STOPSIGNAL SIGTERM

这将在容器停止时发送SIGTERM信号。

作用:

  • 设置容器停止时发送的信号,以便容器可以优雅地停止。
  • 如果不设置,默认发送SIGTERM信号。

3.17 HEALTHCHECK

HEALTHCHECK指令用于设置容器健康检查,例如:

HEALTHCHECK --interval=5m --timeout=3s CMD curl -f http://localhost/ || exit 1

这将在容器中每5分钟执行一次健康检查,如果3秒内无法访问http://localhost/,则认为容器不健康。

作用:

  • 设置容器健康检查,以便监控容器状态。
  • 如果容器不健康,可以自动重启容器。

3.18 SHELL

SHELL指令用于设置默认的shell,例如:

SHELL ["/bin/sh", "-c"]

这将在镜像中设置默认的shell为/bin/sh -c

作用:

  • 设置默认的shell,以便在RUN、CMD、ENTRYPOINT指令中使用。
  • 如果不设置,默认使用/bin/sh -c

4. 总结

本章节介绍了Dockerfile的常用指令,包括FROM、RUN、CMD、EXPOSE、ENV、ADD、COPY等指令。这些指令可以帮助我们构建自定义的Docker镜像,实现容器化部署。

下一篇将介绍docker仓库管理的相关内容。


📢 📢 📢
感谢各位阅读,大家的点赞👍- 关注🔥- 收藏⭐ - 评论📝 四连,都是博主坚持协作、更新高质量博文的最大动力!

;