docker-best-practices

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Docker 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
    python-backend-expert
    or
    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
references/python-dockerfile-template
for the complete template.
Key decisions for Python:
dockerfile
undefined
完整模板请参考
references/python-dockerfile-template
Python项目的关键配置决策:
dockerfile
undefined

Stage 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/*
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/*
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/*
RUN apt-get update && apt-get install -y --no-install-recommends
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 ["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 command
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 ["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
references/react-dockerfile-template
for the complete template.
Key decisions for React:
dockerfile
undefined
完整模板请参考
references/react-dockerfile-template
React项目的关键配置决策:
dockerfile
undefined

Stage 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
USER appuser EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=5s --retries=3
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 + 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
USER appuser EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=5s --retries=3
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运行时——仅包含静态文件和Nginx

Base Image Selection Guide

基础镜像选择指南

Use CaseBase ImageSizeNotes
Python backend
python:3.12-slim
~150MBBest compatibility with binary wheels
Python backend (minimal)
python:3.12-alpine
~50MBMay need musl workarounds for some packages
React build stage
node:20-alpine
~130MBOnly used during build
React runtime
nginx:alpine
~7MBProduction static file serving
Utility/scripts
alpine:3.19
~5MBFor helper containers
Rules:
  1. Never use
    latest
    tag -- always pin major.minor version
  2. Prefer
    -slim
    variants for Python (avoids musl issues)
  3. Prefer
    -alpine
    variants for Node.js and Nginx (smaller images)
  4. Update base images monthly for security patches
适用场景基础镜像体积说明
Python后端
python:3.12-slim
~150MB与二进制wheel包兼容性最佳
Python后端(极简版)
python:3.12-alpine
~50MB部分包可能需要musl兼容处理
React构建阶段
node:20-alpine
~130MB仅在构建时使用
React运行阶段
nginx:alpine
~7MB生产环境静态文件服务
工具/脚本
alpine:3.19
~5MB适用于辅助容器
选择规则:
  1. 切勿使用
    latest
    标签——始终固定主版本.次版本
  2. Python项目优先选择
    -slim
    变体(避免musl兼容性问题)
  3. Node.js和Nginx优先选择
    -alpine
    变体(镜像体积更小)
  4. 每月更新基础镜像以获取安全补丁

Layer Optimization

层优化

Docker caches layers. Order instructions from least-changing to most-changing.
Optimal layer order:
dockerfile
undefined
Docker会缓存镜像层。请按变更频率从低到高排列指令顺序。
最优指令顺序:
dockerfile
undefined

1. 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/*
RUN apt-get update && apt-get install -y --no-install-recommends
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:**
```dockerfile
USER appuser EXPOSE 8000 CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8000"]

**需避免的常见错误:**
```dockerfile

BAD: 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:**
```dockerfile
COPY requirements.txt . RUN pip install -r requirements.txt COPY src/ ./src/

**最小化镜像层数:**
```dockerfile

BAD: 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/*
undefined
RUN apt-get update && apt-get install -y --no-install-recommends
curl
&& rm -rf /var/lib/apt/lists/*
undefined

.dockerignore

.dockerignore配置

Always include a
.dockerignore
to prevent unnecessary files from entering the build context.
dockerignore
undefined
始终配置
.dockerignore
以避免不必要的文件进入构建上下文。
dockerignore
undefined

Version 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
undefined

Create 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
RUN groupadd -r 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
undefined
USER appuser
undefined

Security Scanning with Trivy

使用Trivy进行安全扫描

Scan images for vulnerabilities before deployment.
bash
undefined
部署前扫描镜像中的漏洞。
bash
undefined

Install 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
undefined
dockerfile
undefined

Read-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包,否则避免使用

undefined
undefined

Docker Compose for Local Development

面向本地开发的Docker Compose配置

See
references/docker-compose-template.yml
for the full template.
Architecture:
┌────────────┐    ┌────────────┐
│  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
    depends_on
    with
    condition: service_healthy
    for startup ordering
  • Mount source code as volumes for hot reloading in development
  • Use named volumes for database persistence
  • Set
    target: builder
    to use the build stage with dev dependencies
  • 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:
TagWhenExamplePurpose
git-<sha>
Every build
git-a1b2c3d
Immutable reference to exact code
branch-<name>
Every push
branch-main
Latest from branch (mutable)
v<semver>
Release
v1.2.3
Semantic version release
latest
Production deploy
latest
Current production (mutable)
staging
Staging deploy
staging
Current staging (mutable)
Implementation:
bash
undefined
在所有环境中使用统一的标签策略。
标签格式:
registry.example.com/app-backend:<tag>
标签规则:
标签类型适用场景示例用途
git-<sha>
每次构建
git-a1b2c3d
代码的不可变精确引用
branch-<name>
每次推送
branch-main
分支的最新版本(可变)
v<semver>
版本发布
v1.2.3
语义化版本发布
latest
生产环境部署
latest
当前生产版本(可变)
staging
预发布环境部署
staging
当前预发布版本(可变)
实现方式:
bash
undefined

Build 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

```dockerfile
docker tag "app-backend:git-${GIT_SHA}" "app-backend:latest"

**注意规则:**
1. 始终使用git SHA打标签——这是不可变、可追溯的引用
2. 切勿使用`latest`标签进行部署——始终使用SHA标签
3. 仅在生产部署成功后,将`latest`作为便捷别名使用
4. 在镜像标签中包含构建元数据

```dockerfile

Add 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}"
undefined
LABEL org.opencontainers.image.source="https://github.com/org/repo" LABEL org.opencontainers.image.revision="${GIT_SHA}" LABEL org.opencontainers.image.created="${BUILD_DATE}"
undefined

Quick Reference

快速参考

bash
undefined
bash
undefined

Build 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
undefined
docker image prune -f
undefined