5个您应避免的 Dockerfile 误配置
Source: Dev.to
当我开始学习 Docker 并优化我的容器时,大多数问题并不是缺少工具,而是我编写 Dockerfile 的方式。随着时间的推移,我发现了一些反复出现的错误,并想分享出来,让其他人避免同样的陷阱。
1. 忘记启动 Docker Desktop(或 Docker 守护进程)
如果你在本地构建镜像,务必确保 Docker 守护进程已经运行。这样可以为你省去数小时的烦恼。
2. 以 Root 身份运行容器
默认情况下 Docker 以 root 用户运行,这虽然方便,却很危险。请在容器内部使用非 root 用户。
# Dockerfile
FROM python:3.12-slim
# Create a non‑root user
RUN useradd -m appuser
USER appuser
WORKDIR /app
COPY . .
CMD ["python", "app.py"]
像这样的小改动就能大幅提升安全性。
3. 使用未固定版本或臃肿的基础镜像
依赖 python:latest 之类的标签或体积庞大的基础镜像会导致镜像臃肿且不可预测。推荐使用带版本号的标签并采用多阶段构建。
# Build Stage
FROM maven:3.9.6-eclipse-temurin-21 AS builder
WORKDIR /app
COPY . .
RUN mvn clean package
# Runtime Stage
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
COPY --from=builder /app/target/app.jar /app/
CMD ["java", "-jar", "app.jar"]
这种做法可以让最终镜像更小、更可预测。
4. 复制所有内容(COPY . .)
不加选择地使用 COPY . . 会把构建产物、配置文件以及机密信息一起带进去。请明确要复制的内容。
# Only copy the built artifact
COPY target/app.jar /app/
多花一点点功夫,就能避免后期出现更大的、风险更高的镜像。
5. 将软件包安装拆分为多个 RUN 命令
在不同的 RUN 语句中分别执行 apt-get update 和 apt-get install 会产生不必要的层,并可能破坏缓存。
# Single‑layer install with cleanup
RUN apt-get update && \
apt-get install -y curl vim && \
rm -rf /var/lib/apt/lists/*
层数更少 = 缓存更干净 = 镜像更小。
6. 安装不必要的包
安装带有全部推荐依赖的包会膨胀镜像体积并扩大攻击面。只安装所需的内容,完成后再清理。
# Install only required packages
RUN apt-get update && \
apt-get install -y --no-install-recommends curl && \
rm -rf /var/lib/apt/lists/*
少点杂乱,控制更多。
结论
正确编写 Dockerfile 需要围绕以下几点:
- 最小特权 – 使用非 root 用户运行
- 精简基础镜像 – 使用带版本号的标签并采用多阶段构建
- 明确的
COPY指令 – 避免拉入不需要的文件 - 单层安装 – 保持镜像精简且友好缓存
- 裁剪依赖 – 只安装必要的内容
运用这些经验可以让容器更小、更安全、更可预测——这正是现代 DevOps 所追求的目标。