首页 > 编程开发 > 使用 Dockerfile 构建镜像
2025
04-01

使用 Dockerfile 构建镜像

本文介绍基于 Dockerfile 和 docker build 命令构建新的 Docker 镜像。

1 第一个 Dockerfile

让我们创建一个目录并编写一个 Dockerfile 文件吧,这是一个包含简单 Web 服务器的 Docker 镜像。

static_web 是存储 Dockerfile 文件的文件夹,称这个目录为构建上下文(build context),Docker 会在构建竟像时将上下文中的文件和目录上传到 Docker 守护进程。

mkdir static_web
cd static_web
vim Dockerfile

Dockerfile 的内容如下:

# Version: 0.0.1
FROM ubuntu:24.04
LABEL maintainer="lwg0452 <test@test.com>"
RUN apt-get update && apt-get install -y nginx
RUN echo 'Hi, I am in your container' >usr/share/nginx/html/index.html
EXPOSE 80
WORKDIR /usr/sbin
ENTRYPOINT ["nginx"]
CMD ["-h"]
WORKDIR /root
ENV TEST=1
USER nginx
LABEL version="0.0.1" role="Web Server"

Dockerfile 由一系列的指令和参数构成,每条指令都必须为大写字母(例如 FROM),Dockerfile 中的指令会按照顺序由上到下执行。每条指令都会创建一个新的镜像层,并对镜像进行提交。Docker 答题上按照如下流程执行 Dockerfile 中的指令:

  • Docker 从基础镜像运行一个容器;
  • 执行一条指令,对容器进行修改;
  • 执行类似 docker commit 的操作,提交一个新的镜像层;
  • Docker 再基于刚提交的镜像运行一个新容器;
  • 执行 Dockerfile 中的下一条指令,知道所有指令都执行完毕。

Dockerfile 中以 # 开头的行是注释,Dockerfile 不支持行内注释,例如如下的注释是不合法的:

yum install -y nginx  # 安装 Nginx

2 使用 docker build 命令构建新镜像

docker build 命令示例如下:

# 进入 Dockerfile 所在的目录
cd static_web
# 执行 docker build 命令,注意命令最后的".",它表示在当前目录寻找 Dockerfile 文件
docker build -t lwg0452/static_web:0.0.1 .

命令输出如下:

使用 Dockerfile 构建镜像 - 第1张  | Weiguang的博客

docker build 命令构建镜像会用到缓存机制来加速构建过程,当构建步骤没有变化时,Docker 会跳过这些步骤,直接使用之前的构建结果,例如重新执行以上命令,输出如下:

使用 Dockerfile 构建镜像 - 第2张  | Weiguang的博客

如果希望在构建过程不使用缓存,可以使用 --no-cache 参数:

docker build --no-cache -t "lwg0452/static_web:0.0.1" .

如果希望查看新镜像的构建过程,可以使用 docker history 命令:

docker history lwg0452/static_web:0.0.1

输出如下,其中 <missing> 表示该层已被合并或优化,无法直接看到中间层 ID,但仍然可以看到每个步骤的执行情况:

 => => naming to docker.io/lwg0452/static_web:0.0.1                                                                                                                                                      0.0s
root@lwg0452-VMware-Virtual-Platform:~/static_web# docker history lwg0452/static_web:0.0.1
IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
8aa7a50dd409   4 minutes ago   LABEL version=0.0.3 role=Web Server             0B        buildkit.dockerfile.v0
<missing>      4 minutes ago   USER nginx                                      0B        buildkit.dockerfile.v0
<missing>      4 minutes ago   ENV TEST=1                                      0B        buildkit.dockerfile.v0
<missing>      4 minutes ago   WORKDIR /root                                   0B        buildkit.dockerfile.v0
<missing>      4 minutes ago   CMD ["-h"]                                      0B        buildkit.dockerfile.v0
<missing>      4 minutes ago   ENTRYPOINT ["nginx"]                            0B        buildkit.dockerfile.v0
<missing>      4 minutes ago   WORKDIR /usr/sbin                               0B        buildkit.dockerfile.v0
<missing>      4 minutes ago   EXPOSE map[80/tcp:{}]                           0B        buildkit.dockerfile.v0
<missing>      4 minutes ago   RUN /bin/sh -c echo 'Hi, I am in your contai…   27B       buildkit.dockerfile.v0
<missing>      4 minutes ago   RUN /bin/sh -c apt-get update && apt-get ins…   55.6MB    buildkit.dockerfile.v0
<missing>      4 minutes ago   LABEL maintainer=lwg0452 <test@test.com>        0B        buildkit.dockerfile.v0
<missing>      2 months ago    /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B
<missing>      2 months ago    /bin/sh -c #(nop) ADD file:6df775300d76441aa…   78.1MB
<missing>      2 months ago    /bin/sh -c #(nop)  LABEL org.opencontainers.…   0B
<missing>      2 months ago    /bin/sh -c #(nop)  LABEL org.opencontainers.…   0B
<missing>      2 months ago    /bin/sh -c #(nop)  ARG LAUNCHPAD_BUILD_ARCH     0B
<missing>      2 months ago    /bin/sh -c #(nop)  ARG RELEASE                  0B
root@lwg0452-VMware-Virtual-Platform:~/static_web#

3 Dockerfile 指令

Dockerfile 文件中需要用到许多 Dockerfile 指令,以下表格总结了各个指令的作用和用法:

指令 作用 示例
FROM 指定基础镜像 FROM ubuntu:24.04
LABEL 添加元数据(如维护者信息) LABEL maintainer="user@example.com"
RUN 运行命令并创建新镜像层 RUN apt-get update && apt-get install -y nginx
COPY 复制本地文件到容器(不会自动解压) COPY index.html /usr/share/nginx/html/
ADD 复制文件(支持自动解压 .tar.gz 和 URL 下载) ADD my_archive.tar.gz /app/
WORKDIR 设置工作目录 WORKDIR /app
CMD 指定默认启动命令(可被 docker run 覆盖) CMD ["nginx", "-g", "daemon off;"]
ENTRYPOINT 指定入口点(不会被 docker run 覆盖) ENTRYPOINT ["python", "app.py"]
ENV 设置环境变量 ENV APP_ENV=production
EXPOSE 声明容器暴露的端口(但不会自动映射) EXPOSE 80
VOLUME 定义数据卷(持久化存储) VOLUME /data
ARG 定义构建时变量(仅 docker build 期间有效) ARG BUILD_VERSION=1.0
ONBUILD 继承该镜像时执行的指令 ONBUILD COPY . /app
USER 指定容器运行的用户 USER nginx
HEALTHCHECK 定义健康检查机制 HEALTHCHECK CMD curl --fail http://localhost || exit 1
  • COPYADD 指令复制的文件必须在 Docker 构建上下文(build context) 中,构建上下文是指 docker build 命令的当前目录或 -f 指定的 Dockerfile 所在目录。Docker 只能访问 上下文内的文件,无法直接访问上下文外的文件。

  • ONBUILD 只会在继承该镜像的 Dockerfile 中触发,不会影响当前构建的镜像

  • 如果子镜像 DockerfileFROMmy_base,但不希望执行 ONBUILD 指令,可以手动 清除它们
FROM my_base
ONBUILD OFF

4 将镜像推送到 DockerHub

可以通过 docker push 命令将镜像推送到 DockerHub,这样所有人就能使用这个镜像了。

docker push lwg0452/static_web:0.0.1

lwg0452需要替换成自己的镜像 ID。

最后编辑:
作者:lwg0452
这个作者貌似有点懒,什么都没有留下。
捐 赠如果您觉得这篇文章有用处,请支持作者!鼓励作者写出更好更多的文章!

留下一个回复

你的email不会被公开。