关于 docker-best-practices
面向开发与运维人员的 Docker 技能,覆盖容器开发、部署和运维,并按镜像构建、运行时安全、Compose、性能优化及生产准备组织实践指南。
主要功能
- 01基础镜像与分层建议
- 02多阶段构建实践
- 03运行时安全控制
- 04Compose 配置模式
- 05构建与运行优化
- 06生产就绪检查清单
适用场景
- 01通过多阶段构建缩小镜像
- 02加固容器运行时设置
- 03配置 Compose 服务与网络
- 04为生产环境准备容器
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ josiahsiegel/ claude-plugin-marketplace --skill docker-best-practices安装后在 Claude Code 中输入/docker-best-practices确认已加载。
详细介绍
🚨 关键指南
Windows 文件路径要求
强制要求:在 Windows 上始终对文件路径使用反斜杠
在 Windows 上使用 Edit 或 Write 工具时,文件路径 MUST 使用反斜杠(\),而不是正斜杠(/)。
示例:
- ❌ 错误:
D:/repos/project/file.tsx - ✅ 正确:
D:\repos\project\file.tsx
适用于:
- Edit 工具的 file_path 参数
- Write 工具的 file_path 参数
- 在 Windows 系统上的所有文件操作
文档指南
除非用户明确要求,否则绝不创建新的文档文件。
- 优先级:更新现有的 README.md 文件,而不是创建新文档
- 保持仓库整洁:保持仓库根目录整洁——仅保留 README.md,除非用户另有要求
- 风格:文档应简洁、直接、专业——避免使用 AI 生成式语气
- 用户偏好:仅在用户明确要求提供文档时,才创建额外的 .md 文件
Docker 最佳实践
本指南涵盖容器开发、部署和运行各个方面的最新 Docker 最佳实践。
镜像最佳实践
基础镜像选择
2025 年推荐层级:
- Wolfi/Chainguard(
cgr.dev/chainguard/*)——目标是零 CVE,包含 SBOM - Alpine(
alpine:3.19)——约 7MB,攻击面小 - Distroless(
gcr.io/distroless/*)——约 2MB,不含 shell - Slim 变体(
node:20-slim)——约 70MB,平衡之选
关键规则:
- 始终指定精确的版本标签:
node:20.11.0-alpine3.19 - 切勿使用
latest(不可预测,会破坏可复现性) - 使用来自可信镜像仓库的官方镜像
- 根据实际需求选择基础镜像
Dockerfile 结构
最佳层排序(从最少变更到最频繁变更):
1. Base image and system dependencies
2. Application dependencies (package.json, requirements.txt, etc.)
3. Application code
4. Configuration and metadata
**原因:**Docker 会缓存各层。如果代码变更但依赖项不变,就能重用缓存的依赖项层,从而加快构建速度。
示例:
FROM python:3.12-slim
# 1. System packages (rarely change)
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
&& rm -rf /var/lib/apt/lists/*
# 2. Dependencies (change occasionally)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 3. Application code (changes frequently)
COPY . /app
WORKDIR /app
CMD ["python", "app.py"]
多阶段构建
使用多阶段构建,将构建依赖项与运行时分离:
# Build stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Production stage
FROM node:20-alpine AS runtime
WORKDIR /app
# Only copy what's needed for runtime
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
USER node
CMD ["node", "dist/server.js"]
优势:
- 最终镜像更小(不包含构建工具)
- 安全性更高(攻击向量更少)
- 部署更快(上传和下载的数据量更少)
层优化
合并命令以减少层数和镜像大小:
# Bad - 3 layers, cleanup doesn't reduce size
RUN apt-get update
RUN apt-get install -y curl
RUN rm -rf /var/lib/apt/lists/*
# Good - 1 layer, cleanup effective
RUN apt-get update && \
apt-get install -y --no-install-recommends curl && \
rm -rf /var/lib/apt/lists/*
.dockerignore
始终创建 .dockerignore,以排除不必要的文件:
# Version control
.git
.gitignore
# Dependencies
node_modules
__pycache__
*.pyc
# IDE
.vscode
.idea
# OS
.DS_Store
Thumbs.db
# Logs
*.log
logs/
# Testing
coverage/
.nyc_output
*.test.js
# Documentation
README.md
docs/
# Environment
.env
.env.local
*.local
容器运行时最佳实践
安全性
docker run \
# Run as non-root
--user 1000:1000 \
# Drop all capabilities, add only needed ones
--cap-drop=ALL \
--cap-add=NET_BIND_SERVICE \
# Read-only filesystem
--read-only \
# Temporary writable filesystems
--tmpfs /tmp:noexec,nosuid \
# No new privileges
--security-opt="no-new-privileges:true" \
# Resource limits
--memory="512m" \
--cpus="1.0" \
my-image
资源管理
生产环境中始终设置资源限制:
# docker-compose.yml
services:
app:
deploy:
resources:
limits:
cpus: '2.0'
memory: 1G
reservations:
cpus: '1.0'
memory: 512M
健康检查
为所有长期运行的容器实现健康检查:
HEALTHCHECK --interval=30s --timeout=3s --retries=3 --start-period=40s \
CMD curl -f http://localhost:3000/health || exit 1
或在 compose 中:
services:
app:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
timeout: 3s
retries: 3
start_period: 40s
日志记录
配置适当的日志记录,防止磁盘空间耗尽:
services:
app:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
或者在 /etc/docker/daemon.json 中进行系统级配置:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
重启策略
services:
app:
# For development
restart: "no"
# For production
restart: unless-stopped
# Or with fine-grained control (Swarm mode)
deploy:
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
Docker Compose 最佳实践
文件结构
# No version field needed (Compose v2.40.3+)
services:
# Service definitions
web:
# ...
api:
# ...
database:
# ...
networks:
# Custom networks (preferred)
frontend:
backend:
internal: true
volumes:
# Named volumes (preferred for persistence)
db-data:
app-data:
configs:
# Configuration files (Swarm mode)
app-config:
file: ./config/app.conf
secrets:
# Secrets (Swarm mode)
db-password:
file: ./secrets/db_pass.txt
网络隔离
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true # No external access
services:
web:
networks:
- frontend
api:
networks:
- frontend
- backend
database:
networks:
- backend # Not accessible from frontend
环境变量
services:
app:
# Load from file (preferred for non-secrets)
env_file:
- .env
# Inline for service-specific vars
environment:
- NODE_ENV=production
- LOG_LEVEL=info
# For Swarm mode secrets
secrets:
- db_password
重要事项:
- 将
.env添加到.gitignore - 提供
.env.example作为模板 - 切勿将机密提交到版本控制中
依赖管理
services:
api:
depends_on:
database:
condition: service_healthy # Wait for health check
redis:
condition: service_started # Just wait for start
生产环境最佳实践
镜像标签策略
# Use semantic versioning
my-app:1.2.3
my-app:1.2
my-app:1
my-app:latest
# Include git commit for traceability
my-app:1.2.3-abc123f
# Environment tags
my-app:1.2.3-production
my-app:1.2.3-staging
机密管理
切勿这样做:
# BAD - secret in layer history
ENV API_KEY=secret123
RUN echo "password" > /app/config
应这样做:
# Use Docker secrets (Swarm) or external secret management
docker secret create db_password ./password.txt
# Or mount secrets at runtime
docker run -v /secure/secrets:/run/secrets:ro my-app
# Or use environment files (not in image)
docker run --env-file /secure/.env my-app
监控与可观测性
services:
app:
# Health checks
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
# Labels for monitoring tools
labels:
- "prometheus.io/scrape=true"
- "prometheus.io/port=9090"
- "com.company.team=backend"
- "com.company.version=1.2.3"
# Logging
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
备份策略
# Backup named volume
docker run --rm \
-v VOLUME_NAME:/data \
-v $(pwd):/backup \
alpine tar czf /backup/backup-$(date +%Y%m%d).tar.gz -C /data .
# Restore volume
docker run --rm \
-v VOLUME_NAME:/data \
-v $(pwd):/backup \
alpine tar xzf /backup/backup.tar.gz -C /data
更新策略
services:
app:
# For Swarm mode - rolling updates
deploy:
replicas: 3
update_config:
parallelism: 1 # Update 1 at a time
delay: 10s # Wait 10s between updates
failure_action: rollback
monitor: 60s
rollback_config:
parallelism: 1
delay: 5s
特定平台的最佳实践
Linux
- 使用用户命名空间重映射来增强安全性
- 利用原生性能优势
- 使用 Alpine 构建最小镜像
- 配置 SELinux/AppArmor 配置文件
- 使用 systemd 管理 Docker 守护进程
// /etc/docker/daemon.json
{
"userns-remap": "default",
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"storage-driver": "overlay2",
"live-restore": true
}
macOS
- 在 Docker Desktop 中分配充足资源
- 对绑定挂载使用
:delegated或:cached - 考虑针对 ARM(M1/M2)进行多平台构建
- 将文件共享限制在必要目录
# Better volume performance on macOS
volumes:
- ./src:/app/src:delegated # Host writes are delayed
- ./build:/app/build:cached # Container writes are cached
Windows
- 选择容器类型:Windows 或 Linux
- 路径中使用正斜杠
- 确保在 Docker Desktop 中共享了驱动器
- 注意换行符的差异(CRLF 与 LF)
- 考虑使用 WSL2 后端以获得更好的性能
# Windows-compatible paths
volumes:
- C:/Users/name/app:/app # Forward slashes work
# or
- C:\Users\name\app:/app # Backslashes need escaping in YAML
性能最佳实践
构建性能
# Use BuildKit (faster, better caching)
export DOCKER_BUILDKIT=1
# Use cache mounts
RUN --mount=type=cache,target=/root/.cache/pip \
pip install -r requirements.txt
# Use bind mounts for dependencies
RUN --mount=type=bind,source=package.json,target=package.json \
--mount=type=bind,source=package-lock.json,target=package-lock.json \
--mount=type=cache,target=/root/.npm \
npm ci
镜像大小
- 使用多阶段构建
- 选择精简的基础镜像
- 在同一层中进行清理
- 使用 .dockerignore
- 移除构建依赖项
# Install and cleanup in one layer
RUN apt-get update && \
apt-get install -y --no-install-recommends \
package1 \
package2 && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
运行时性能
# Use exec form (no shell overhead)
CMD ["node", "server.js"] # Good
# vs
CMD node server.js # Bad - spawns shell
# Optimize signals
STOPSIGNAL SIGTERM
# Run as non-root (slightly faster, much more secure)
USER appuser
安全最佳实践摘要
镜像安全:
- 使用官方、精简的基础镜像
- 扫描漏洞(Docker Scout、Trivy)
- 不要在层中包含密钥
- 以非 root 用户身份运行
- 保持镜像更新
运行时安全:
- 移除功能
- 使用只读文件系统
- 设置资源限制
- 启用安全选项
- 隔离网络
- 使用密钥管理
合规性:
- 遵循 CIS Docker 基准
- 在 CI/CD 中实施容器扫描
- 使用签名镜像(Docker Content Trust)
- 保留审计日志
- 定期进行安全审查
应避免的常见反模式
❌ 不要:
- 以 root 身份运行
- 使用
--privileged - 挂载 Docker 套接字
- 使用
latest标签 - 将密钥硬编码
- 跳过运行状况检查
- 忽略资源限制
- 使用体积庞大的基础镜像
- 跳过漏洞扫描
- 暴露不必要的端口
- 使用低效的层缓存
- 将密钥提交到 Git
✅ 应该:
- 以非 root 用户身份运行
- 使用最少的功能
- 隔离容器
- 使用版本号标记
- 使用密钥管理
- 实施运行状况检查
- 设置资源限制
- 使用精简镜像
- 定期扫描
- 遵循最小权限原则
- 优化构建缓存
- 使用 .env.example 模板
生产就绪镜像检查清单
- 基于官方、有版本号且精简的镜像
- 多阶段构建(如适用)
- 以非 root 用户身份运行
- 层中不包含密钥
- 已配置 .dockerignore
- 已通过漏洞扫描
- 已实施运行状况检查
- 标签正确(版本、描述等)
- 层缓存高效
- 已定义资源限制
- 已配置日志记录
- 正确处理信号
- 已设置安全选项
- 文档完整
- 已在目标平台上测试
本技能介绍了当前的 Docker 最佳实践。Docker 持续演进,请务必对照官方文档核实最新建议。
评论
支持 Markdown