writing-dockerfiles
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseWriting Dockerfiles
编写Dockerfile
Create production-grade Dockerfiles with multi-stage builds, security hardening, and language-specific optimizations.
创建具备多阶段构建、安全加固和语言专属优化的生产级Dockerfile。
When to Use This Skill
何时使用该技能
Invoke when:
- "Write a Dockerfile for [Python/Node.js/Go/Rust] application"
- "Optimize this Dockerfile to reduce image size"
- "Use multi-stage build for..."
- "Secure Dockerfile with non-root user"
- "Use distroless base image"
- "Add BuildKit cache mounts"
- "Prevent secrets from leaking in Docker layers"
在以下场景中调用:
- "为[Python/Node.js/Go/Rust]应用编写Dockerfile"
- "优化此Dockerfile以减小镜像体积"
- "为……使用多阶段构建"
- "通过非root用户加固Dockerfile安全性"
- "使用distroless基础镜像"
- "添加BuildKit缓存挂载"
- "防止密钥在Docker层中泄露"
Quick Decision Framework
快速决策框架
Ask three questions to determine the approach:
1. What language?
- Python → See
references/python-dockerfiles.md - Node.js → See
references/nodejs-dockerfiles.md - Go → See
references/go-dockerfiles.md - Rust → See
references/rust-dockerfiles.md - Java → See
references/java-dockerfiles.md
2. Is security critical?
- YES → Use distroless runtime images (see )
references/security-hardening.md - NO → Use slim/alpine base images
3. Is image size critical?
- YES (<50MB) → Multi-stage + distroless + static linking
- NO (<500MB) → Multi-stage + slim base images
通过三个问题确定实现方案:
1. 使用什么语言?
- Python → 参考
references/python-dockerfiles.md - Node.js → 参考
references/nodejs-dockerfiles.md - Go → 参考
references/go-dockerfiles.md - Rust → 参考
references/rust-dockerfiles.md - Java → 参考
references/java-dockerfiles.md
2. 安全性是否至关重要?
- 是 → 使用distroless运行时镜像(参考)
references/security-hardening.md - 否 → 使用slim/alpine基础镜像
3. 镜像体积是否至关重要?
- 是(<50MB)→ 多阶段构建 + distroless + 静态链接
- 否(<500MB)→ 多阶段构建 + slim基础镜像
Core Concepts
核心概念
Multi-Stage Builds
多阶段构建
Separate build environment from runtime environment to minimize final image size.
Pattern:
dockerfile
undefined将构建环境与运行环境分离,以最小化最终镜像体积。
模式:
dockerfile
undefinedStage 1: Build
阶段1:构建
FROM build-image AS builder
RUN compile application
FROM build-image AS builder
RUN compile application
Stage 2: Runtime
阶段2:运行时
FROM minimal-runtime-image
COPY --from=builder /app/binary /app/
CMD ["/app/binary"]
**Benefits:**
- 80-95% smaller images (excludes build tools)
- Improved security (no compilers in production)
- Faster deployments
- Better layer cachingFROM minimal-runtime-image
COPY --from=builder /app/binary /app/
CMD ["/app/binary"]
**优势:**
- 镜像体积减小80-95%(不包含构建工具)
- 安全性提升(生产环境无编译器)
- 部署速度更快
- 分层缓存效果更佳Base Image Selection
基础镜像选择
Decision matrix:
| Language | Build Stage | Runtime Stage | Final Size |
|---|---|---|---|
| Go (static) | | | 10-30MB |
| Rust (static) | | | 5-15MB |
| Python | | | 200-400MB |
| Node.js | | | 150-300MB |
| Java | | | 200-350MB |
Distroless images (Google-maintained):
- → Static binaries (2MB)
gcr.io/distroless/static-debian12 - → Dynamic binaries with libc (20MB)
gcr.io/distroless/base-debian12 - → Python runtime (60MB)
gcr.io/distroless/python3-debian12 - → Node.js runtime (150MB)
gcr.io/distroless/nodejs20-debian12
See for complete comparison.
references/base-image-selection.md决策矩阵:
| 语言 | 构建阶段 | 运行时阶段 | 最终体积 |
|---|---|---|---|
| Go(静态) | | | 10-30MB |
| Rust(静态) | | | 5-15MB |
| Python | | | 200-400MB |
| Node.js | | | 150-300MB |
| Java | | | 200-350MB |
distroless镜像(谷歌维护):
- → 静态二进制文件(2MB)
gcr.io/distroless/static-debian12 - → 带libc的动态二进制文件(20MB)
gcr.io/distroless/base-debian12 - → Python运行时(60MB)
gcr.io/distroless/python3-debian12 - → Node.js运行时(150MB)
gcr.io/distroless/nodejs20-debian12
完整对比请参考。
references/base-image-selection.mdBuildKit Features
BuildKit特性
Enable BuildKit for advanced caching and security:
bash
export DOCKER_BUILDKIT=1
docker build .启用BuildKit以实现高级缓存和安全功能:
bash
export DOCKER_BUILDKIT=1
docker build .OR
或
docker buildx build .
**Key features:**
- `--mount=type=cache` → Persistent package manager caches
- `--mount=type=secret` → Inject secrets without storing in layers
- `--mount=type=ssh` → SSH agent forwarding for private repos
- Parallel stage execution
- Improved layer caching
See `references/buildkit-features.md` for detailed patterns.docker buildx build .
**核心特性:**
- `--mount=type=cache` → 持久化包管理器缓存
- `--mount=type=secret` → 注入密钥但不存储在镜像层中
- `--mount=type=ssh` → SSH代理转发以访问私有仓库
- 并行阶段执行
- 优化的分层缓存
详细模式请参考`references/buildkit-features.md`。Layer Optimization
分层优化
Order Dockerfile instructions from least to most frequently changing:
dockerfile
undefined将Dockerfile指令按变更频率从低到高排序:
dockerfile
undefined1. Base image (rarely changes)
1. 基础镜像(极少变更)
FROM python:3.12-slim
FROM python:3.12-slim
2. System packages (rarely changes)
2. 系统包(极少变更)
RUN apt-get update && apt-get install -y build-essential
RUN apt-get update && apt-get install -y build-essential
3. Dependencies manifest (changes occasionally)
3. 依赖清单(偶尔变更)
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY requirements.txt .
RUN pip install -r requirements.txt
4. Application code (changes frequently)
4. 应用代码(频繁变更)
COPY . .
COPY . .
5. Runtime configuration (rarely changes)
5. 运行时配置(极少变更)
CMD ["python", "app.py"]
**BuildKit cache mounts:**
```dockerfile
RUN --mount=type=cache,target=/root/.cache/pip \
pip install -r requirements.txtCache persists across builds, eliminating redundant downloads.
CMD ["python", "app.py"]
**BuildKit缓存挂载:**
```dockerfile
RUN --mount=type=cache,target=/root/.cache/pip \
pip install -r requirements.txt缓存会在多次构建之间保留,消除重复下载。
Security Hardening
安全加固
Essential security practices:
1. Non-root users
dockerfile
undefined必备安全实践:
1. 非root用户
dockerfile
undefinedDebian/Ubuntu
Debian/Ubuntu
RUN useradd -m -u 1000 appuser && chown -R appuser:appuser /app
USER appuser
RUN useradd -m -u 1000 appuser && chown -R appuser:appuser /app
USER appuser
Alpine
Alpine
RUN adduser -D -u 1000 appuser && chown -R appuser:appuser /app
USER appuser
RUN adduser -D -u 1000 appuser && chown -R appuser:appuser /app
USER appuser
Distroless (built-in)
Distroless(内置)
USER nonroot:nonroot
**2. Secret management**
```dockerfileUSER nonroot:nonroot
**2. 密钥管理**
```dockerfile❌ NEVER: Secret in layer history
❌ 绝对禁止:密钥出现在层历史中
RUN git clone https://${GITHUB_TOKEN}@github.com/private/repo.git
RUN git clone https://${GITHUB_TOKEN}@github.com/private/repo.git
✅ ALWAYS: BuildKit secret mount
✅ 正确做法:BuildKit密钥挂载
RUN --mount=type=secret,id=github_token
TOKEN=$(cat /run/secrets/github_token) &&
git clone https://${TOKEN}@github.com/private/repo.git
TOKEN=$(cat /run/secrets/github_token) &&
git clone https://${TOKEN}@github.com/private/repo.git
Build with:
```bash
docker buildx build --secret id=github_token,src=./token.txt .3. Vulnerability scanning
bash
undefinedRUN --mount=type=secret,id=github_token
TOKEN=$(cat /run/secrets/github_token) &&
git clone https://${TOKEN}@github.com/private/repo.git
TOKEN=$(cat /run/secrets/github_token) &&
git clone https://${TOKEN}@github.com/private/repo.git
构建命令:
```bash
docker buildx build --secret id=github_token,src=./token.txt .3. 漏洞扫描
bash
undefinedTrivy (recommended)
Trivy(推荐)
trivy image myimage:latest
trivy image myimage:latest
Docker Scout
Docker Scout
docker scout cves myimage:latest
**4. Health checks**
```dockerfile
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1See for comprehensive hardening patterns.
references/security-hardening.mddocker scout cves myimage:latest
**4. 健康检查**
```dockerfile
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1完整加固模式请参考。
references/security-hardening.md.dockerignore Configuration
.dockerignore配置
Create to exclude unnecessary files:
.dockerignoreundefined创建以排除不必要的文件:
.dockerignoreundefinedVersion control
版本控制
.git
.gitignore
.git
.gitignore
CI/CD
CI/CD
.github
.gitlab-ci.yml
.github
.gitlab-ci.yml
IDE
IDE
.vscode
.idea
.vscode
.idea
Testing
测试
tests/
coverage/
**/_test.go
**/.test.js
tests/
coverage/
**/_test.go
**/.test.js
Build artifacts
构建产物
node_modules/
dist/
build/
target/
pycache/
node_modules/
dist/
build/
target/
pycache/
Environment
环境配置
.env
.env.local
*.log
Reduces build context size and prevents leaking secrets..env
.env.local
*.log
减小构建上下文体积,防止密钥泄露。Language-Specific Patterns
语言专属模式
Python Quick Reference
Python快速参考
Three approaches:
- pip (simple) → Single-stage, requirements.txt
- poetry (production) → Multi-stage, virtual environment
- uv (fastest) → 10-100x faster than pip
Example: Poetry multi-stage
dockerfile
FROM python:3.12-slim AS builder
RUN \
pip install poetry==1.7.1
COPY pyproject.toml poetry.lock ./
RUN poetry export -f requirements.txt --output requirements.txt
RUN \
python -m venv /opt/venv && \
/opt/venv/bin/pip install -r requirements.txt
FROM python:3.12-slim
COPY /opt/venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
USER 1000:1000
CMD ["python", "-m", "uvicorn", "main:app", "--host", "0.0.0.0"]See for complete patterns and .
references/python-dockerfiles.mdexamples/python-fastapi.Dockerfile三种实现方式:
- pip(简单) → 单阶段构建,使用requirements.txt
- poetry(生产级) → 多阶段构建,使用虚拟环境
- uv(最快) → 速度比pip快10-100倍
示例:Poetry多阶段构建
dockerfile
FROM python:3.12-slim AS builder
RUN \
pip install poetry==1.7.1
COPY pyproject.toml poetry.lock ./
RUN poetry export -f requirements.txt --output requirements.txt
RUN \
python -m venv /opt/venv && \
/opt/venv/bin/pip install -r requirements.txt
FROM python:3.12-slim
COPY /opt/venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
USER 1000:1000
CMD ["python", "-m", "uvicorn", "main:app", "--host", "0.0.0.0"]完整模式请参考,示例请见。
references/python-dockerfiles.mdexamples/python-fastapi.DockerfileNode.js Quick Reference
Node.js快速参考
Key patterns:
- Use (not
npm ci) for reproducible buildsnpm install - Multi-stage: Build stage → Production dependencies only
- Built-in user (UID 1000)
node - Alpine variant smallest (~180MB vs 1GB)
Example: Express multi-stage
dockerfile
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN \
npm ci
COPY . .
RUN npm run build
RUN npm prune --omit=dev
FROM node:20-alpine
WORKDIR /app
COPY /app/node_modules ./node_modules
COPY /app/dist ./dist
USER node
CMD ["node", "dist/index.js"]See for npm/pnpm/yarn patterns and .
references/nodejs-dockerfiles.mdexamples/nodejs-express.Dockerfile核心模式:
- 使用(而非
npm ci)实现可复现构建npm install - 多阶段构建:构建阶段 → 仅保留生产依赖
- 内置用户(UID 1000)
node - Alpine变体体积最小(约180MB vs 1GB)
示例:Express多阶段构建
dockerfile
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN \
npm ci
COPY . .
RUN npm run build
RUN npm prune --omit=dev
FROM node:20-alpine
WORKDIR /app
COPY /app/node_modules ./node_modules
COPY /app/dist ./dist
USER node
CMD ["node", "dist/index.js"]npm/pnpm/yarn模式请参考,示例请见。
references/nodejs-dockerfiles.mdexamples/nodejs-express.DockerfileGo Quick Reference
Go快速参考
Smallest possible images:
- Static binary (CGO_ENABLED=0) + distroless = 10-30MB
- Strip symbols with
-ldflags="-s -w" - Cache both and build cache
/go/pkg/mod
Example: Distroless static
dockerfile
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN \
go mod download
COPY . .
RUN \
CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o main .
FROM gcr.io/distroless/static-debian12
COPY /app/main /app/main
USER nonroot:nonroot
ENTRYPOINT ["/app/main"]See and .
references/go-dockerfiles.mdexamples/go-microservice.Dockerfile最小化镜像方案:
- 静态二进制文件(CGO_ENABLED=0) + distroless = 10-30MB
- 使用剥离符号
-ldflags="-s -w" - 同时缓存和构建缓存
/go/pkg/mod
示例:Distroless静态镜像
dockerfile
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN \
go mod download
COPY . .
RUN \
CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o main .
FROM gcr.io/distroless/static-debian12
COPY /app/main /app/main
USER nonroot:nonroot
ENTRYPOINT ["/app/main"]请参考和。
references/go-dockerfiles.mdexamples/go-microservice.DockerfileRust Quick Reference
Rust快速参考
Ultra-small static binaries:
- musl static linking → No libc dependencies
- scratch base image (0 bytes overhead)
- Final image: 5-15MB
Example: Scratch base
dockerfile
FROM rust:1.75-alpine AS builder
RUN apk add --no-cache musl-dev
WORKDIR /app超小静态二进制文件:
- musl静态链接 → 无libc依赖
- scratch基础镜像(0字节开销)
- 最终镜像体积:5-15MB
示例:Scratch基础镜像
dockerfile
FROM rust:1.75-alpine AS builder
RUN apk add --no-cache musl-dev
WORKDIR /appCache dependencies
缓存依赖
COPY Cargo.toml Cargo.lock ./
RUN --mount=type=cache,target=/usr/local/cargo/registry
mkdir src && echo "fn main() {}" > src/main.rs &&
cargo build --release --target x86_64-unknown-linux-musl &&
rm -rf src
mkdir src && echo "fn main() {}" > src/main.rs &&
cargo build --release --target x86_64-unknown-linux-musl &&
rm -rf src
COPY Cargo.toml Cargo.lock ./
RUN --mount=type=cache,target=/usr/local/cargo/registry
mkdir src && echo "fn main() {}" > src/main.rs &&
cargo build --release --target x86_64-unknown-linux-musl &&
rm -rf src
mkdir src && echo "fn main() {}" > src/main.rs &&
cargo build --release --target x86_64-unknown-linux-musl &&
rm -rf src
Build application
构建应用
COPY src ./src
RUN --mount=type=cache,target=/usr/local/cargo/registry
cargo build --release --target x86_64-unknown-linux-musl
cargo build --release --target x86_64-unknown-linux-musl
FROM scratch
COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/app /app
USER 1000:1000
ENTRYPOINT ["/app"]
See `references/rust-dockerfiles.md` and `examples/rust-actix.Dockerfile`.COPY src ./src
RUN --mount=type=cache,target=/usr/local/cargo/registry
cargo build --release --target x86_64-unknown-linux-musl
cargo build --release --target x86_64-unknown-linux-musl
FROM scratch
COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/app /app
USER 1000:1000
ENTRYPOINT ["/app"]
请参考`references/rust-dockerfiles.md`和`examples/rust-actix.Dockerfile`。Package Manager Cache Mounts
包管理器缓存挂载
BuildKit cache mount locations:
| Language | Package Manager | Cache Mount Target |
|---|---|---|
| Python | pip | |
| Python | poetry | |
| Python | uv | |
| Node.js | npm | |
| Node.js | pnpm | |
| Go | go mod | |
| Rust | cargo | |
Persistent caches eliminate redundant package downloads across builds.
BuildKit缓存挂载路径:
| 语言 | 包管理器 | 缓存挂载目标 |
|---|---|---|
| Python | pip | |
| Python | poetry | |
| Python | uv | |
| Node.js | npm | |
| Node.js | pnpm | |
| Go | go mod | |
| Rust | cargo | |
持久化缓存可消除多次构建之间的重复包下载。
Validation and Testing
验证与测试
Validate Dockerfile quality:
bash
undefined验证Dockerfile质量:
bash
undefinedLint Dockerfile
检查Dockerfile规范
python scripts/validate_dockerfile.py Dockerfile
python scripts/validate_dockerfile.py Dockerfile
Scan for vulnerabilities
扫描漏洞
trivy image myimage:latest
trivy image myimage:latest
Analyze image size
分析镜像体积
docker images myimage:latest
docker history myimage:latest
**Compare optimization results:**
```bashdocker images myimage:latest
docker history myimage:latest
**对比优化效果:**
```bashBefore optimization
优化前
docker build -t myapp:before .
docker build -t myapp:before .
After optimization
优化后
docker build -t myapp:after .
docker build -t myapp:after .
Compare
对比
bash scripts/analyze_image_size.sh myapp:before myapp:after
See `scripts/validate_dockerfile.py` for automated Dockerfile linting.bash scripts/analyze_image_size.sh myapp:before myapp:after
自动化Dockerfile检查请参考`scripts/validate_dockerfile.py`。Integration with Related Skills
与相关技能的集成
Upstream (provide input):
- → Test application before containerizing
testing-strategies - → Application-level security before Docker layer
security-hardening
Downstream (consume Dockerfiles):
- → Build and push Docker images in CI
building-ci-pipelines - → Deploy containers to K8s clusters
kubernetes-operations - → Deploy containers with Terraform/Pulumi
infrastructure-as-code
Parallel (related context):
- → Inject runtime secrets (K8s secrets, vaults)
secret-management - → Container logging and metrics collection
observability
上游(提供输入):
- → 容器化前先测试应用
testing-strategies - → Docker层之前先实现应用级安全
security-hardening
下游(使用Dockerfile):
- → 在CI中构建并推送Docker镜像
building-ci-pipelines - → 将容器部署到K8s集群
kubernetes-operations - → 使用Terraform/Pulumi部署容器
infrastructure-as-code
并行(相关上下文):
- → 注入运行时密钥(K8s secrets、vaults)
secret-management - → 容器日志与指标收集
observability
Common Patterns Quick Reference
常见反模式
1. Static binary (Go/Rust) → Smallest image
- Build: Language-specific builder image
- Runtime: or
gcr.io/distroless/static-debian12scratch - Size: 5-30MB
2. Interpreted language (Python/Node.js) → Production-optimized
- Build: Install dependencies, build artifacts
- Runtime: Same base, production dependencies only
- Size: 150-400MB
3. JVM (Java) → Optimized runtime
- Build: Maven/Gradle with full JDK
- Runtime: JRE-only image (alpine variant)
- Size: 200-350MB
4. Security-critical → Maximum hardening
- Base: Distroless images
- User: Non-root (nonroot:nonroot)
- Secrets: BuildKit secret mounts
- Scan: Trivy/Docker Scout in CI
5. Development → Fast iteration
- Base: Full language image (not slim)
- Volumes: Mount source code
- Hot reload: Language-specific tools
- Not covered in this skill (see Docker Compose docs)
❌ 绝对禁止:
- 使用标签(构建结果不可预测)
latest - 生产环境以root用户运行
- 在环境变量或镜像层中存储密钥
- 安装不必要的包
- 合并不相关的RUN命令(破坏缓存)
- 忽略.dockerignore(构建上下文臃肿)
✅ 正确做法:
- 固定镜像的精确版本(如,而非
python:3.12.1-slim)python:3 - 创建并使用非root用户
- 使用BuildKit密钥挂载管理凭证
- 最小化镜像层和体积
- 按变更频率从低到高排序命令
- 创建.dockerignore文件
Anti-Patterns to Avoid
额外资源
❌ Never:
- Use tags (unpredictable builds)
latest - Run as root in production
- Store secrets in ENV vars or layers
- Install unnecessary packages
- Combine unrelated RUN commands (breaks caching)
- Skip .dockerignore (bloated build context)
✅ Always:
- Pin exact image versions (, not
python:3.12.1-slim)python:3 - Create and use non-root user
- Use BuildKit secret mounts for credentials
- Minimize layers and image size
- Order commands from least to most frequently changing
- Create .dockerignore file
基础镜像仓库:
- Google Distroless:
gcr.io/distroless/* - Docker Hub官方镜像:,
python:*,node:*golang:* - Red Hat UBI:
registry.access.redhat.com/ubi9/*
漏洞扫描工具:
- Trivy(推荐):
trivy image myimage:latest - Docker Scout:
docker scout cves myimage:latest - Grype:
grype myimage:latest
参考文档:
- → 完整基础镜像对比
references/base-image-selection.md - → 高级BuildKit模式
references/buildkit-features.md - → 全面安全指南
references/security-hardening.md - 目录下的语言专属参考文档
references/ - 目录下的可用示例
examples/
Additional Resources
—
Base image registries:
- Google Distroless:
gcr.io/distroless/* - Docker Hub Official: ,
python:*,node:*golang:* - Red Hat UBI:
registry.access.redhat.com/ubi9/*
Vulnerability scanners:
- Trivy (recommended):
trivy image myimage:latest - Docker Scout:
docker scout cves myimage:latest - Grype:
grype myimage:latest
Reference documentation:
- → Complete base image comparison
references/base-image-selection.md - → Advanced BuildKit patterns
references/buildkit-features.md - → Comprehensive security guide
references/security-hardening.md - Language-specific references in directory
references/ - Working examples in directory
examples/
—