Dockerfile Cheatsheet - Docker Image Build Reference
Dockerfile 是定义 Docker 镜像的文本文件,最常用的指令和最佳实践都在这里了,按基础指令、环境变量、文件操作、多阶段构建分组整理,快速编写高效镜像。
Back to Containers & Orchestration基础指令 7
FROM node:18-alpine指定基础镜像,alpine 版本体积更小
FROM scratch空基础镜像,用于极致最小化静态二进制
WORKDIR /app设置工作目录,不存在会自动创建
COPY package*.json ./复制文件到容器,支持通配符
RUN npm ci执行命令构建镜像层
EXPOSE 3000声明容器端口,仅文档作用不实际映射
CMD ["node", "app.js"]容器默认启动命令,exec 形式推荐
环境变量与参数 7
ENV NODE_ENV=production设置环境变量,运行时也可用
ENV PATH="/app/bin:$PATH"追加 PATH 让自定义命令全局可用
ARG VERSION=1.0构建时参数,运行时不存在
ARG NPM_TOKEN无默认值,从 --build-arg 传入
LABEL maintainer="email@example.com"添加镜像元数据
USER appuser切换运行用户降低容器权限
HEALTHCHECK --interval=30s CMD curl -f http://localhost/ || exit 1健康检查,连续失败到阈值标记为 unhealthy
文件操作 5
COPY src/ ./src/复制目录到容器,目标不存在会自动创建
COPY --chown=node:node . .复制时指定文件属主,避免 root 拥有
COPY --chmod=755 entrypoint.sh /entrypoint.sh复制时直接设置可执行权限(BuildKit)
ADD https://example.com/file.tar.gz /tmp/ADD 可下载 URL 文件到镜像
ADD file.tar.gz /app/自动解压本地 tar 包,普通文件用 COPY 更明确
多阶段构建 5
FROM node:18 AS builder命名构建阶段,便于后续引用
COPY --from=builder /app/dist ./dist从构建阶段复制产物到最终镜像
COPY --from=nginx:alpine /etc/nginx/nginx.conf /etc/nginx/从外部镜像复制文件,不必先 pull
FROM golang:1.21 AS builderGo 多阶段构建的编译阶段
FROM alpine:3.18最终镜像用更小基础,体积可降至几 MB
入口点 ENTRYPOINT 5
CMD ["node", "app.js"]默认命令,可被 docker run 参数覆盖
ENTRYPOINT ["node"]固定入口点,不会被 run 参数覆盖
ENTRYPOINT ["node"]
CMD ["app.js"]组合使用:ENTRYPOINT 定程序 CMD 定默认参数
SHELL ["/bin/bash", "-c"]改变 RUN/CMD 的默认 shell,Windows 容器常用
ENTRYPOINT ["./docker-entrypoint.sh"]自定义入口脚本做初始化后再启动主进程
构建优化 6
COPY package*.json ./先复制依赖文件再 npm ci,利用缓存层
RUN npm ci && npm cache clean --force合并 RUN 减少层数并清理缓存
RUN apk add --no-cache curlAlpine 安装包不缓存索引,减小体积
.dockerignore排除 node_modules、.git 等不需要构建的文件
RUN --mount=type=cache,target=/root/.npm npm ciBuildKit 挂载缓存,跨构建复用 npm 包提速
FROM node:18-alpinealpine 基础镜像比完整版小约 5 倍
完整示例 3
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
CMD ["node", "dist/index.js"]Node 多阶段构建:编译期装依赖编译,运行期只带产物和依赖
FROM python:3.11 AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt
FROM python:3.11-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
CMD ["python", "main.py"]Python 多阶段构建:依赖装到 --user 目录,运行镜像只复制该目录
FROM golang:1.21 AS builder
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /app/server .
FROM alpine:3.18
COPY --from=builder /app/server /app/server
CMD ["/app/server"]Go 多阶段构建:静态编译后镜像可压到 10 MB 内
💡 Tips
- 每条 RUN/COPY/ADD 指令都会创建新层,尽量合并 RUN 命令减少层数。
- 多阶段构建可以大幅减小最终镜像体积,适合编译型语言如 Go、Rust、Java。
- 使用 .dockerignore 排除 node_modules、.git、.env 等不需要构建的文件。
- CMD 和 ENTRYPOINT 区别:CMD 可被 docker run 参数覆盖,ENTRYPOINT 是固定的。
- 优先用 exec 形式 ["cmd","arg"] 而非 shell 形式,前者能正确接收 SIGTERM 信号,避免容器停止超时。
- 别用 --build-arg 传密码或密钥,它会留在镜像构建历史里,用 BuildKit secrets 方案更安全。