Dockerfile构建是唯一推荐的生产级做法;docker commit仅适用于临时调试,不可复现、不可版本化、不支持CI/CD。FROM必须为首行且显式指定tag,优先选用alpine:3.21或debian:bookworm-slim等轻量基础镜像,避免ubuntu:latest或EOL系统。RUN需合并安装与清理以减少层数,CMD与ENTRYPOINT应明确区分用途,禁止默认启动bash/sh,构建时务必使用.dockerignore并严格控制上下文。

直接用 Dockerfile 构建基础镜像,是唯一推荐的生产级做法;docker commit 仅适合临时调试,无法复现、不可版本化、不适用于 CI/CD。
FROM 必须是第一行,且要选对基础镜像
基础镜像决定了整个环境的起点:体积、包管理器、glibc 版本、安全更新节奏。别盲目用 ubuntu:latest 或 centos:7 —— 前者太大(>70MB),后者已 EOL(2024年6月停止维护)。
- Web 服务 / Go/Python 应用优先选
alpine:3.21(~5MB),但注意 musl libc 兼容性问题(比如某些预编译二进制不支持) - Java/.NET/需要 glibc 的场景,用
debian:bookworm-slim(~40MB)或官方语言镜像如openjdk:21-jre-slim - FROM 后不带 tag 时默认是
latest,但会随时间漂移;务必显式写死 tag,例如FROM python:3.12-slim-bookworm - 一个
Dockerfile中可多次出现FROM(多阶段构建),但第一个FROM才是运行时基础镜像
RUN 要合并、清理、避免缓存失效
RUN 每执行一次就生成一层镜像,层数越多,镜像越臃肿、拉取越慢、安全扫描越麻烦。关键不是“能不能跑”,而是“能不能干净地跑”。
- 把 apt/yum/apk 安装和清理写在同一条
RUN里,例如:RUN apt-get update && apt-get install -y curl nginx && rm -rf /var/lib/apt/lists/* - 不要拆成多个
RUN apt-get install xxx,否则中间层会残留未清理的包缓存 - 用
--no-cache构建只在调试时有用;日常应靠指令合并 + 清理来控制体积 - 如果某条
RUN依赖外部文件(如requirements.txt),把它放在 COPY 之后、其他安装命令之前,才能利用 Docker 构建缓存
CMD 和 ENTRYPOINT 别混用,启动逻辑必须明确
容器不是虚拟机,它只负责运行一个主进程。CMD 是默认命令,ENTRYPOINT 是执行外壳——两者组合决定你最终看到的 ps aux 进程树。
- 纯应用服务(如 Nginx、Gunicorn)直接用
ENTRYPOINT ["nginx", "-g", "daemon off;"],确保进程前台运行 - 需要传参的场景(如脚本包装器),用
ENTRYPOINT ["./entrypoint.sh"]+CMD ["--verbose"],后者会作为参数传给 entrypoint - 绝对不要写
CMD ["bash"]或CMD ["sh"]作为默认启动项——这会让容器一启动就挂起,不符合 12-factor 原则 -
docker run myimage /bin/sh会覆盖CMD,但不会覆盖ENTRYPOINT;这点在调试时很关键
构建命令末尾的点(.)不能漏,上下文路径决定 COPY 范围
docker build 不是读取单个 Dockerfile,而是把当前目录(或指定路径)整个打包上传为“构建上下文”(build context)。所有 COPY 和 ADD 都只能从这个上下文中取文件。
- 命令必须带结尾的
.(表示当前目录)或具体路径,例如:docker build -t myapp .;漏掉会报错"unable to prepare context: path '.' not found" - 如果
Dockerfile不在当前目录,用-f指定路径,但上下文仍是.,所以COPY ./src /app仍从当前目录找src - 用
.dockerignore排除node_modules、__pycache__、.git等,否则它们会被打包上传,拖慢构建、暴露敏感信息 - 构建时实际生效的是上下文中的文件,不是本地编辑器里“看起来存在”的文件——改了
requirements.txt但没保存?构建就会用旧内容
最常被忽略的其实是构建上下文的边界和缓存行为:你以为改了一行 RUN 就只重跑那一步,但只要上面某层的文件(比如 COPY 的配置)变了,后面所有层都会失效重建。真正的可控性,来自对每一层输入源的精确控制。


















