docker-best-practices
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDocker Best Practices
Docker最佳实践
When to Use
适用场景
Activate this skill when:
- Creating a new Dockerfile for a Python backend or React frontend
- Optimizing existing Docker images for smaller size or faster builds
- Setting up Docker Compose for local development
- Configuring multi-stage builds to separate build and runtime dependencies
- Hardening container security (non-root user, minimal base images)
- Running security scans on Docker images with Trivy
- Designing an image tagging strategy for CI/CD pipelines
- Troubleshooting Docker build failures or runtime issues
Do NOT use this skill for:
- Deployment orchestration or CI/CD pipelines (use )
deployment-pipeline - Kubernetes configuration or Helm charts
- Cloud infrastructure provisioning (Terraform, CloudFormation)
- Application code patterns (use or
python-backend-expert)react-frontend-expert
在以下场景启用此技能:
- 为Python后端或React前端创建新的Dockerfile
- 优化现有Docker镜像以减小体积或加快构建速度
- 为本地开发配置Docker Compose
- 配置多阶段构建以分离构建时和运行时依赖
- 加固容器安全(非根用户、最小化基础镜像)
- 使用Trivy对Docker镜像进行安全扫描
- 为CI/CD流水线设计镜像标签策略
- 排查Docker构建失败或运行时问题
请勿在以下场景使用此技能:
- 部署编排或CI/CD流水线(请使用技能)
deployment-pipeline - Kubernetes配置或Helm Charts
- 云基础设施部署(Terraform、CloudFormation)
- 应用代码模式(请使用或
python-backend-expert技能)react-frontend-expert
Instructions
操作指南
Multi-Stage Build Strategy
多阶段构建策略
Multi-stage builds keep final images small by separating build-time and runtime dependencies.
Principle: Build in a full image, run in a minimal image. Only copy what is needed for runtime.
┌──────────────────────────────────┐
│ Stage 1: Builder │
│ Full SDK, build tools, deps │
│ Compile, install, build │
├──────────────────────────────────┤
│ Stage 2: Runtime │
│ Minimal base image │
│ COPY --from=builder artifacts │
│ Non-root user, health check │
└──────────────────────────────────┘多阶段构建通过分离构建时和运行时依赖,保持最终镜像体积小巧。
核心原则: 在完整镜像中构建,在最小化镜像中运行。仅复制运行时所需的内容。
┌──────────────────────────────────┐
│ Stage 1: Builder │
│ Full SDK, build tools, deps │
│ Compile, install, build │
├──────────────────────────────────┤
│ Stage 2: Runtime │
│ Minimal base image │
│ COPY --from=builder artifacts │
│ Non-root user, health check │
└──────────────────────────────────┘Python Backend Dockerfile
Python后端Dockerfile
See for the complete template.
references/python-dockerfile-templateKey decisions for Python:
dockerfile
undefined完整模板请参考。
references/python-dockerfile-templatePython项目的关键配置决策:
dockerfile
undefinedStage 1: Build dependencies
Stage 1: Build dependencies
FROM python:3.12-slim AS builder
WORKDIR /app
RUN apt-get update && apt-get install -y --no-install-recommends
build-essential libpq-dev
&& rm -rf /var/lib/apt/lists/*
build-essential libpq-dev
&& rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt
FROM python:3.12-slim AS builder
WORKDIR /app
RUN apt-get update && apt-get install -y --no-install-recommends
build-essential libpq-dev
&& rm -rf /var/lib/apt/lists/*
build-essential libpq-dev
&& rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt
Stage 2: Runtime
Stage 2: Runtime
FROM python:3.12-slim AS runtime
FROM python:3.12-slim AS runtime
Install only runtime system dependencies
Install only runtime system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends
libpq5 curl
&& rm -rf /var/lib/apt/lists/*
libpq5 curl
&& rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y --no-install-recommends
libpq5 curl
&& rm -rf /var/lib/apt/lists/*
libpq5 curl
&& rm -rf /var/lib/apt/lists/*
Create non-root user
Create non-root user
RUN groupadd -r appuser && useradd -r -g appuser -d /app -s /sbin/nologin appuser
WORKDIR /app
COPY --from=builder /install /usr/local
COPY src/ ./src/
COPY alembic/ ./alembic/
COPY alembic.ini .
RUN chown -R appuser:appuser /app
USER appuser
EXPOSE 8000
HEALTHCHECK --interval=30s --timeout=10s --retries=3
CMD curl -f http://localhost:8000/health || exit 1
CMD curl -f http://localhost:8000/health || exit 1
CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8000"]
**Why these choices:**
- `python:3.12-slim` instead of `alpine` -- avoids musl compatibility issues with binary wheels
- `--no-cache-dir` -- prevents pip cache from bloating the image
- `--prefix=/install` -- isolates installed packages for clean COPY
- `libpq5` at runtime, `libpq-dev` only at build -- minimizes runtime dependencies
- `curl` in runtime -- needed for HEALTHCHECK commandRUN groupadd -r appuser && useradd -r -g appuser -d /app -s /sbin/nologin appuser
WORKDIR /app
COPY --from=builder /install /usr/local
COPY src/ ./src/
COPY alembic/ ./alembic/
COPY alembic.ini .
RUN chown -R appuser:appuser /app
USER appuser
EXPOSE 8000
HEALTHCHECK --interval=30s --timeout=10s --retries=3
CMD curl -f http://localhost:8000/health || exit 1
CMD curl -f http://localhost:8000/health || exit 1
CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8000"]
**为何选择这些配置:**
- 使用`python:3.12-slim`而非`alpine`——避免二进制wheel包与musl的兼容性问题
- `--no-cache-dir`——防止pip缓存增大镜像体积
- `--prefix=/install`——隔离已安装的包,便于干净复制
- 运行时仅安装`libpq5`,`libpq-dev`仅在构建时安装——最小化运行时依赖
- 运行时安装`curl`——为HEALTHCHECK命令提供支持React Frontend Dockerfile
React前端Dockerfile
See for the complete template.
references/react-dockerfile-templateKey decisions for React:
dockerfile
undefined完整模板请参考。
references/react-dockerfile-templateReact项目的关键配置决策:
dockerfile
undefinedStage 1: Build
Stage 1: Build
FROM node:20-alpine AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --ignore-scripts
COPY . .
RUN npm run build
FROM node:20-alpine AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --ignore-scripts
COPY . .
RUN npm run build
Stage 2: Serve with Nginx
Stage 2: Serve with Nginx
FROM nginx:alpine AS runtime
COPY --from=builder /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
RUN addgroup -g 1001 -S appgroup &&
adduser -S appuser -u 1001 -G appgroup &&
chown -R appuser:appgroup /var/cache/nginx /var/log/nginx /etc/nginx/conf.d &&
touch /var/run/nginx.pid && chown appuser:appgroup /var/run/nginx.pid
adduser -S appuser -u 1001 -G appgroup &&
chown -R appuser:appgroup /var/cache/nginx /var/log/nginx /etc/nginx/conf.d &&
touch /var/run/nginx.pid && chown appuser:appgroup /var/run/nginx.pid
USER appuser
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=5s --retries=3
CMD wget -q --spider http://localhost:8080/ || exit 1
CMD wget -q --spider http://localhost:8080/ || exit 1
CMD ["nginx", "-g", "daemon off;"]
**Why these choices:**
- `node:20-alpine` for build -- smallest Node image, only needed at build time
- `nginx:alpine` for serving -- ~7MB base, production-grade static file server
- `npm ci` -- deterministic installs from lockfile, faster than `npm install`
- `--ignore-scripts` -- security measure, prevents running arbitrary scripts during install
- Final image has NO Node.js runtime -- only static files + NginxFROM nginx:alpine AS runtime
COPY --from=builder /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
RUN addgroup -g 1001 -S appgroup &&
adduser -S appuser -u 1001 -G appgroup &&
chown -R appuser:appgroup /var/cache/nginx /var/log/nginx /etc/nginx/conf.d &&
touch /var/run/nginx.pid && chown appuser:appgroup /var/run/nginx.pid
adduser -S appuser -u 1001 -G appgroup &&
chown -R appuser:appgroup /var/cache/nginx /var/log/nginx /etc/nginx/conf.d &&
touch /var/run/nginx.pid && chown appuser:appgroup /var/run/nginx.pid
USER appuser
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=5s --retries=3
CMD wget -q --spider http://localhost:8080/ || exit 1
CMD wget -q --spider http://localhost:8080/ || exit 1
CMD ["nginx", "-g", "daemon off;"]
**为何选择这些配置:**
- 构建阶段使用`node:20-alpine`——体积最小的Node镜像,仅在构建时需要
- 运行阶段使用`nginx:alpine`提供服务——基础镜像约7MB,是生产级静态文件服务器
- `npm ci`——基于lockfile进行确定性安装,比`npm install`更快
- `--ignore-scripts`——安全措施,防止安装过程中运行任意脚本
- 最终镜像不包含Node.js运行时——仅包含静态文件和NginxBase Image Selection Guide
基础镜像选择指南
| Use Case | Base Image | Size | Notes |
|---|---|---|---|
| Python backend | | ~150MB | Best compatibility with binary wheels |
| Python backend (minimal) | | ~50MB | May need musl workarounds for some packages |
| React build stage | | ~130MB | Only used during build |
| React runtime | | ~7MB | Production static file serving |
| Utility/scripts | | ~5MB | For helper containers |
Rules:
- Never use tag -- always pin major.minor version
latest - Prefer variants for Python (avoids musl issues)
-slim - Prefer variants for Node.js and Nginx (smaller images)
-alpine - Update base images monthly for security patches
| 适用场景 | 基础镜像 | 体积 | 说明 |
|---|---|---|---|
| Python后端 | | ~150MB | 与二进制wheel包兼容性最佳 |
| Python后端(极简版) | | ~50MB | 部分包可能需要musl兼容处理 |
| React构建阶段 | | ~130MB | 仅在构建时使用 |
| React运行阶段 | | ~7MB | 生产环境静态文件服务 |
| 工具/脚本 | | ~5MB | 适用于辅助容器 |
选择规则:
- 切勿使用标签——始终固定主版本.次版本
latest - Python项目优先选择变体(避免musl兼容性问题)
-slim - Node.js和Nginx优先选择变体(镜像体积更小)
-alpine - 每月更新基础镜像以获取安全补丁
Layer Optimization
层优化
Docker caches layers. Order instructions from least-changing to most-changing.
Optimal layer order:
dockerfile
undefinedDocker会缓存镜像层。请按变更频率从低到高排列指令顺序。
最优指令顺序:
dockerfile
undefined1. Base image (changes rarely)
1. 基础镜像(极少变更)
FROM python:3.12-slim
FROM python:3.12-slim
2. System dependencies (changes monthly)
2. 系统依赖(每月变更)
RUN apt-get update && apt-get install -y --no-install-recommends
libpq5 curl && rm -rf /var/lib/apt/lists/*
libpq5 curl && rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y --no-install-recommends
libpq5 curl && rm -rf /var/lib/apt/lists/*
libpq5 curl && rm -rf /var/lib/apt/lists/*
3. Create user (changes never)
3. 创建用户(从不变更)
RUN groupadd -r appuser && useradd -r -g appuser appuser
RUN groupadd -r appuser && useradd -r -g appuser appuser
4. Python dependencies (changes weekly)
4. Python依赖(每周变更)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
5. Application code (changes every commit)
5. 应用代码(每次提交都变更)
COPY src/ ./src/
COPY src/ ./src/
6. Runtime config (changes rarely)
6. 运行时配置(极少变更)
USER appuser
EXPOSE 8000
CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8000"]
**Common mistakes to avoid:**
```dockerfileUSER appuser
EXPOSE 8000
CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8000"]
**需避免的常见错误:**
```dockerfileBAD: Copying everything before installing dependencies (busts cache)
错误做法:先复制所有文件再安装依赖(会破坏缓存)
COPY . .
RUN pip install -r requirements.txt
COPY . .
RUN pip install -r requirements.txt
GOOD: Copy only requirements first, then install, then copy code
正确做法:先仅复制requirements文件,安装依赖后再复制代码
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY src/ ./src/
**Minimize layers:**
```dockerfileCOPY requirements.txt .
RUN pip install -r requirements.txt
COPY src/ ./src/
**最小化镜像层数:**
```dockerfileBAD: Multiple RUN commands create multiple layers
错误做法:多个RUN命令会创建多个镜像层
RUN apt-get update
RUN apt-get install -y curl
RUN rm -rf /var/lib/apt/lists/*
RUN apt-get update
RUN apt-get install -y curl
RUN rm -rf /var/lib/apt/lists/*
GOOD: Single RUN command, single layer, clean up in same layer
正确做法:单个RUN命令,单个镜像层,在同一层完成清理
RUN apt-get update && apt-get install -y --no-install-recommends
curl
&& rm -rf /var/lib/apt/lists/*
curl
&& rm -rf /var/lib/apt/lists/*
undefinedRUN apt-get update && apt-get install -y --no-install-recommends
curl
&& rm -rf /var/lib/apt/lists/*
curl
&& rm -rf /var/lib/apt/lists/*
undefined.dockerignore
.dockerignore配置
Always include a to prevent unnecessary files from entering the build context.
.dockerignoredockerignore
undefined始终配置以避免不必要的文件进入构建上下文。
.dockerignoredockerignore
undefinedVersion control
Version control
.git
.gitignore
.git
.gitignore
Python
Python
pycache
*.pyc
*.pyo
.pytest_cache
.mypy_cache
.ruff_cache
*.egg-info
dist/
build/
.venv/
venv/
pycache
*.pyc
*.pyo
.pytest_cache
.mypy_cache
.ruff_cache
*.egg-info
dist/
build/
.venv/
venv/
Node
Node
node_modules/
npm-debug.log*
.next/
coverage/
node_modules/
npm-debug.log*
.next/
coverage/
IDE
IDE
.vscode/
.idea/
*.swp
*.swo
.vscode/
.idea/
*.swp
*.swo
Docker
Docker
Dockerfile*
docker-compose*
.dockerignore
Dockerfile*
docker-compose*
.dockerignore
Environment files
Environment files
.env
.env.*
!.env.example
.env
.env.*
!.env.example
Documentation
Documentation
*.md
docs/
LICENSE
*.md
docs/
LICENSE
CI/CD
CI/CD
.github/
.gitlab-ci.yml
.github/
.gitlab-ci.yml
OS
OS
.DS_Store
Thumbs.db
**Impact of .dockerignore:**
- Without it: Build context may be 500MB+ (node_modules, .git)
- With it: Build context typically 5-20MB
- Faster builds, no risk of leaking secrets from `.env` files.DS_Store
Thumbs.db
**.dockerignore的作用:**
- 未配置时:构建上下文可能超过500MB(包含node_modules、.git等)
- 配置后:构建上下文通常为5-20MB
- 加快构建速度,避免`.env`文件中的密钥泄露风险Security Hardening
安全加固
Non-Root User
非根用户
Never run containers as root in production.
dockerfile
undefined生产环境中切勿以root用户运行容器。
dockerfile
undefinedCreate a dedicated user with no shell and no home directory
创建专用用户,无shell且无主目录
RUN groupadd -r appuser &&
useradd -r -g appuser -d /app -s /sbin/nologin appuser
useradd -r -g appuser -d /app -s /sbin/nologin appuser
RUN groupadd -r appuser &&
useradd -r -g appuser -d /app -s /sbin/nologin appuser
useradd -r -g appuser -d /app -s /sbin/nologin appuser
Set ownership of application files
设置应用文件的所有权
COPY --chown=appuser:appuser src/ ./src/
COPY --chown=appuser:appuser src/ ./src/
Switch to non-root user
切换至非根用户
USER appuser
undefinedUSER appuser
undefinedSecurity Scanning with Trivy
使用Trivy进行安全扫描
Scan images for vulnerabilities before deployment.
bash
undefined部署前扫描镜像中的漏洞。
bash
undefinedInstall Trivy
安装Trivy
Scan image for vulnerabilities
扫描镜像中的漏洞
trivy image --severity HIGH,CRITICAL app-backend:latest
trivy image --severity HIGH,CRITICAL app-backend:latest
Scan and fail if HIGH/CRITICAL vulnerabilities found
扫描并在发现高/严重漏洞时失败
trivy image --exit-code 1 --severity HIGH,CRITICAL app-backend:latest
trivy image --exit-code 1 --severity HIGH,CRITICAL app-backend:latest
Generate JSON report
生成JSON报告
trivy image --format json --output trivy-report.json app-backend:latest
trivy image --format json --output trivy-report.json app-backend:latest
Scan Dockerfile for misconfigurations
扫描Dockerfile中的配置错误
trivy config Dockerfile
**Integrate into CI/CD:**
```yaml
- name: Trivy vulnerability scan
uses: aquasecurity/trivy-action@master
with:
image-ref: 'app-backend:${{ github.sha }}'
format: 'sarif'
output: 'trivy-results.sarif'
severity: 'CRITICAL,HIGH'
exit-code: '1'trivy config Dockerfile
**集成到CI/CD流水线:**
```yaml
- name: Trivy vulnerability scan
uses: aquasecurity/trivy-action@master
with:
image-ref: 'app-backend:${{ github.sha }}'
format: 'sarif'
output: 'trivy-results.sarif'
severity: 'CRITICAL,HIGH'
exit-code: '1'Additional Security Measures
额外安全措施
dockerfile
undefineddockerfile
undefinedRead-only filesystem where possible
尽可能使用只读文件系统
(set at runtime with docker run --read-only)
(运行时通过docker run --read-only设置)
No new privileges
禁止新增权限
(set at runtime with docker run --security-opt=no-new-privileges)
(运行时通过docker run --security-opt=no-new-privileges设置)
Drop all capabilities, add only what is needed
移除所有权限,仅添加必要权限
(set at runtime with docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE)
(运行时通过docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE设置)
Use COPY instead of ADD (ADD can auto-extract tarballs, security risk)
使用COPY而非ADD(ADD会自动解压tar包,存在安全风险)
COPY requirements.txt . # GOOD
COPY requirements.txt . # 推荐做法
ADD requirements.txt . # AVOID unless you need tar extraction
ADD requirements.txt . # 除非需要解压tar包,否则避免使用
undefinedundefinedDocker Compose for Local Development
面向本地开发的Docker Compose配置
See for the full template.
references/docker-compose-template.ymlArchitecture:
┌────────────┐ ┌────────────┐
│ Frontend │ │ Backend │
│ React:3000 │───>│ FastAPI:8000│
└────────────┘ └─────┬──────┘
│
┌──────┴──────┐
│ │
┌────┴────┐ ┌────┴────┐
│PostgreSQL│ │ Redis │
│ :5432 │ │ :6379 │
└─────────┘ └─────────┘Key Compose features for development:
yaml
services:
backend:
build:
context: .
dockerfile: Dockerfile.backend
target: builder # Use builder stage for development (has dev tools)
volumes:
- ./src:/app/src # Hot reload
environment:
- DEBUG=true
- DATABASE_URL=postgresql+asyncpg://postgres:postgres@db:5432/app_dev
depends_on:
db:
condition: service_healthy
ports:
- "8000:8000"
frontend:
build:
context: ./frontend
target: builder
volumes:
- ./frontend/src:/app/src # Hot reload
ports:
- "3000:3000"
db:
image: postgres:16
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
volumes:
- pgdata:/var/lib/postgresql/data
redis:
image: redis:7-alpine
healthcheck:
test: ["CMD", "redis-cli", "ping"]
volumes:
pgdata:Essential Compose patterns:
- Use with
depends_onfor startup orderingcondition: service_healthy - Mount source code as volumes for hot reloading in development
- Use named volumes for database persistence
- Set to use the build stage with dev dependencies
target: builder - Define health checks for all infrastructure services
完整模板请参考。
references/docker-compose-template.yml架构:
┌────────────┐ ┌────────────┐
│ Frontend │ │ Backend │
│ React:3000 │───>│ FastAPI:8000│
└────────────┘ └─────┬──────┘
│
┌──────┴──────┐
│ │
┌────┴────┐ ┌────┴────┐
│PostgreSQL│ │ Redis │
│ :5432 │ │ :6379 │
└─────────┘ └─────────┘面向开发环境的核心Compose特性:
yaml
services:
backend:
build:
context: .
dockerfile: Dockerfile.backend
target: builder # 开发环境使用builder阶段(包含开发工具)
volumes:
- ./src:/app/src # 热重载
environment:
- DEBUG=true
- DATABASE_URL=postgresql+asyncpg://postgres:postgres@db:5432/app_dev
depends_on:
db:
condition: service_healthy
ports:
- "8000:8000"
frontend:
build:
context: ./frontend
target: builder
volumes:
- ./frontend/src:/app/src # 热重载
ports:
- "3000:3000"
db:
image: postgres:16
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
volumes:
- pgdata:/var/lib/postgresql/data
redis:
image: redis:7-alpine
healthcheck:
test: ["CMD", "redis-cli", "ping"]
volumes:
pgdata:Compose核心模式:
- 使用搭配
depends_on控制启动顺序condition: service_healthy - 挂载源代码卷以实现开发环境热重载
- 使用命名卷实现数据库持久化
- 设置以使用包含开发依赖的构建阶段
target: builder - 为所有基础设施服务定义健康检查
Image Tagging Strategy
镜像标签策略
Use a consistent tagging strategy across all environments.
Tag format:
registry.example.com/app-backend:<tag>Tagging rules:
| Tag | When | Example | Purpose |
|---|---|---|---|
| Every build | | Immutable reference to exact code |
| Every push | | Latest from branch (mutable) |
| Release | | Semantic version release |
| Production deploy | | Current production (mutable) |
| Staging deploy | | Current staging (mutable) |
Implementation:
bash
undefined在所有环境中使用统一的标签策略。
标签格式:
registry.example.com/app-backend:<tag>标签规则:
| 标签类型 | 适用场景 | 示例 | 用途 |
|---|---|---|---|
| 每次构建 | | 代码的不可变精确引用 |
| 每次推送 | | 分支的最新版本(可变) |
| 版本发布 | | 语义化版本发布 |
| 生产环境部署 | | 当前生产版本(可变) |
| 预发布环境部署 | | 当前预发布版本(可变) |
实现方式:
bash
undefinedBuild with git SHA tag (immutable)
使用git SHA构建标签(不可变)
GIT_SHA=$(git rev-parse --short HEAD)
docker build -t "app-backend:git-${GIT_SHA}" .
GIT_SHA=$(git rev-parse --short HEAD)
docker build -t "app-backend:git-${GIT_SHA}" .
Tag for the branch
为分支打标签
BRANCH=$(git rev-parse --abbrev-ref HEAD)
docker tag "app-backend:git-${GIT_SHA}" "app-backend:branch-${BRANCH}"
BRANCH=$(git rev-parse --abbrev-ref HEAD)
docker tag "app-backend:git-${GIT_SHA}" "app-backend:branch-${BRANCH}"
Tag for release
为版本发布打标签
docker tag "app-backend:git-${GIT_SHA}" "app-backend:v1.2.3"
docker tag "app-backend:git-${GIT_SHA}" "app-backend:v1.2.3"
Tag as latest for production
为生产环境打latest标签
docker tag "app-backend:git-${GIT_SHA}" "app-backend:latest"
**Rules:**
1. Always tag with git SHA -- this is the immutable, traceable reference
2. Never deploy using `latest` tag -- always use the SHA tag
3. Use `latest` only as a convenience alias after a successful production deploy
4. Include build metadata in image labels
```dockerfiledocker tag "app-backend:git-${GIT_SHA}" "app-backend:latest"
**注意规则:**
1. 始终使用git SHA打标签——这是不可变、可追溯的引用
2. 切勿使用`latest`标签进行部署——始终使用SHA标签
3. 仅在生产部署成功后,将`latest`作为便捷别名使用
4. 在镜像标签中包含构建元数据
```dockerfileAdd metadata labels
添加元数据标签
LABEL org.opencontainers.image.source="https://github.com/org/repo"
LABEL org.opencontainers.image.revision="${GIT_SHA}"
LABEL org.opencontainers.image.created="${BUILD_DATE}"
undefinedLABEL org.opencontainers.image.source="https://github.com/org/repo"
LABEL org.opencontainers.image.revision="${GIT_SHA}"
LABEL org.opencontainers.image.created="${BUILD_DATE}"
undefinedQuick Reference
快速参考
bash
undefinedbash
undefinedBuild images
构建镜像
docker build -t app-backend:$(git rev-parse --short HEAD) -f Dockerfile.backend .
docker build -t app-frontend:$(git rev-parse --short HEAD) -f Dockerfile.frontend .
docker build -t app-backend:$(git rev-parse --short HEAD) -f Dockerfile.backend .
docker build -t app-frontend:$(git rev-parse --short HEAD) -f Dockerfile.frontend .
Start local development
启动本地开发环境
docker compose up -d && docker compose logs -f backend
docker compose up -d && docker compose logs -f backend
Scan for vulnerabilities
扫描漏洞
trivy image --severity HIGH,CRITICAL app-backend:latest
trivy image --severity HIGH,CRITICAL app-backend:latest
Check image sizes
查看镜像大小
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}" | grep app-
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}" | grep app-
Clean up
清理镜像
docker image prune -f
undefineddocker image prune -f
undefined