构建镜像:从手动提交到 Dockerfile 革命

发布: (2025年12月8日 GMT+8 11:27)
5 分钟阅读
原文: Dev.to

Source: Dev.to

1. 手动方式:使用 docker commit 构建镜像

A. docker commit 的工作原理

  1. 启动一个基础容器 – 运行一个带交互式 shell 的镜像。

    docker run -it --name my_sandbox ubuntu:latest bash
  2. 手动进行更改 – 在容器内部安装或配置软件,例如:

    apt-get update && apt-get install -y nginx
  3. 退出容器 – 输入 exit 停止容器,同时保留可写层中的更改。

  4. 提交更改 – 将容器当前状态保存为一个新的、不可变的镜像。

    docker commit  :

示例

docker commit my_sandbox my_custom_nginx:v1.0

B. 升级已提交的镜像

要“升级”镜像,重复以下过程:

  1. my_custom_nginx:v1.0 启动一个新容器。
  2. 进行进一步的手动更改(例如,更新 Nginx 配置)。
  3. 再次提交容器,并为新镜像打标签。
docker commit  my_custom_nginx:v2.0

2. docker commit 的局限性

局限性描述影响
不可追溯容器内部执行的命令没有记录,无法看到文件为何存在或软件包是如何安装的。审计、调试和安全检查几乎不可能。
不可复现删除镜像后必须手动重复相同的 shell 命令且顺序必须完全一致才能重新构建。在不同环境之间导致开发和部署不一致。
镜像体积大docker commit 常会把不必要的文件(如临时安装缓存)一起捕获进镜像层。镜像臃肿,拉取慢,占用更多磁盘空间。
安全风险难以验证镜像层的内容或历史。隐蔽漏洞的风险增加。

3. Dockerfile 革命

Dockerfile 是一个纯文本文件,包含一系列指令,Docker 按顺序执行这些指令来构建镜像。

为什么要使用 Dockerfile?

  • 自动化 – 整个构建过程全部自动化。
  • 可追溯 – 每条命令都显式列出,提供透明、可审计的历史。
  • 可复现 – 任何拥有 Dockerfile 的人都能一致地重新构建完全相同的镜像。

Dockerfile 成为镜像的源代码,使得构建能够保持小巧、安全并受版本控制的最佳实践。

4. 基本 Dockerfile 指令(第 1 部分)

指令用途是否创建层?示例
FROM指定 构建的基础镜像(必须是第一行)。FROM node:18-alpine
RUN在新层中执行命令(例如安装软件包)。RUN apk add --no-cache git
WORKDIR为后续的 RUNCMDENTRYPOINTCOPYADD 设置工作目录。WORKDIR /app
COPY将主机上的文件/目录复制到镜像文件系统中。COPY package.json /app
CMD运行中的容器 提供默认命令;通常在启动时被覆盖。只能有一个 CMDCMD ["node", "server.js"]
EXPOSE记录容器运行时监听的端口(不实际发布端口)。EXPOSE 8080

理解 CMDRUN 的区别

  • RUN – 在构建镜像时执行(例如安装软件)。
  • CMD – 在容器启动时执行(例如启动应用)。

对未涉及主题的简要说明

网络

EXPOSE 指令仅记录应用使用的端口。实际的端口映射(如 -p 8080:80)是在 docker run 时或通过编排工具完成的,而不是在 Dockerfile 中。

数据卷

数据卷用于持久化数据,通常通过 docker run -v 或 Docker Compose 定义。可选的 VOLUME 指令可以标记挂载点,但一般更倾向于在镜像外部管理卷。

接下来会讲什么?

现在你已经了解了 Dockerfile 为什么必不可少。第 2 部分我们将深入 docker build 的完整构建流程,探讨 ENTRYPOINT 等高级指令,介绍多阶段构建,并分享将镜像发布到仓库的最佳实践。

Back to Blog

相关文章

阅读更多 »