AgentSkillsCN

containerization

遵循 Docker、Docker Compose 与 Kubernetes 的最佳实践,应用容器与编排技术。在编写 Dockerfile、创建 docker-compose 配置、部署至 Kubernetes、优化容器镜像,或排查容器网络问题时,可使用此技能。

SKILL.md
--- frontmatter
name: "containerization"
description: 'Apply container and orchestration best practices with Docker, Docker Compose, and Kubernetes. Use when writing Dockerfiles, creating docker-compose configurations, deploying to Kubernetes, optimizing container images, or troubleshooting container networking.'
metadata:
  author: "AgentX"
  version: "1.0.0"
  created: "2025-01-15"
  updated: "2025-01-15"
compatibility:
  platforms: ["windows", "linux", "macos"]

Containerization & Orchestration

Build, ship, and run applications with Docker and Kubernetes following production best practices.

When to Use

  • Building Docker images for applications
  • Writing Docker Compose for multi-service local development
  • Deploying to Kubernetes clusters
  • Creating CI/CD pipelines that build and push container images
  • Migrating from VMs to containers

Decision Tree

code
Containerizing an application?
├─ Single service, local dev?
│   └─ Dockerfile only
├─ Multi-service, local dev?
│   └─ Docker Compose
├─ Production deployment?
│   ├─ Simple (1-3 services)?
│   │   └─ Docker Compose + managed hosting (Azure Container Apps, ECS)
│   └─ Complex (many services, scaling)?
│       └─ Kubernetes (AKS, EKS, GKE)
└─ CI/CD pipeline?
    └─ Multi-stage Dockerfile + registry push

Quick Start

bash
# Build image
docker build -t myapp:1.0 .

# Run container
docker run -d -p 3000:3000 myapp:1.0

# Multi-service (Docker Compose)
docker compose up -d

# Scan for vulnerabilities
docker scout quickview myapp:1.0

Dockerfile Best Practices

Multi-Stage Builds (Recommended)

dockerfile
# Stage 1: Build
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci --production=false
COPY . .
RUN npm run build

# Stage 2: Production
FROM node:20-alpine AS production
WORKDIR /app
RUN addgroup -g 1001 appgroup && adduser -u 1001 -G appgroup -s /bin/sh -D appuser
COPY --from=build /app/dist ./dist
COPY --from=build /app/node_modules ./node_modules
COPY --from=build /app/package.json ./
USER appuser
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s CMD wget -qO- http://localhost:3000/health || exit 1
CMD ["node", "dist/server.js"]

.NET Multi-Stage

dockerfile
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /src
COPY *.csproj ./
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app/publish --no-restore

FROM mcr.microsoft.com/dotnet/aspnet:9.0
WORKDIR /app
RUN adduser --disabled-password --gecos '' appuser
COPY --from=build /app/publish .
USER appuser
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s CMD curl -f http://localhost:8080/health || exit 1
ENTRYPOINT ["dotnet", "MyApp.dll"]

Python Multi-Stage

dockerfile
FROM python:3.12-slim AS build
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --target=/app/deps -r requirements.txt

FROM python:3.12-slim
WORKDIR /app
RUN useradd --create-home appuser
COPY --from=build /app/deps /usr/local/lib/python3.12/site-packages/
COPY . .
USER appuser
EXPOSE 8000
HEALTHCHECK --interval=30s --timeout=3s CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"
CMD ["python", "-m", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

Core Rules

1. Image Security

  • Non-root user: Always USER appuser — never run as root
  • Minimal base: Use -alpine or -slim variants
  • No secrets in images: Use build args for build-time, env vars for runtime
  • Pin versions: FROM node:20.11-alpine, not FROM node:latest
  • Scan images: docker scout quickview or trivy image <name>

2. Layer Optimization

  • Copy dependency files first: COPY package*.json ./RUN npm ciCOPY . .
  • Combine RUN commands: Reduce layers with &&
  • Use .dockerignore: Exclude node_modules, .git, dist, test files
  • Multi-stage builds: Build stage with dev deps, production stage with runtime only

3. Docker Compose

yaml
# docker-compose.yml
services:
  api:
    build:
      context: .
      dockerfile: Dockerfile
      target: production
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgres://user:pass@db:5432/app
    depends_on:
      db:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://localhost:3000/health"]
      interval: 10s
      retries: 3

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: app
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U user"]
      interval: 5s
      retries: 5

volumes:
  pgdata:

4. Kubernetes Essentials

yaml
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: my-app
          image: myregistry.azurecr.io/my-app:1.0.0
          ports:
            - containerPort: 3000
          resources:
            requests:
              cpu: "100m"
              memory: "128Mi"
            limits:
              cpu: "500m"
              memory: "512Mi"
          readinessProbe:
            httpGet:
              path: /health
              port: 3000
            initialDelaySeconds: 5
            periodSeconds: 10
          livenessProbe:
            httpGet:
              path: /health
              port: 3000
            initialDelaySeconds: 15
            periodSeconds: 20

5. .dockerignore

code
node_modules
.git
.github
dist
*.md
.env*
.vscode
__pycache__
*.pyc
bin/
obj/

Anti-Patterns

  • Running as root: Security risk — always add and switch to non-root user
  • latest tags: Non-reproducible builds — pin specific versions
  • Secrets in ENV/ARG: Use Docker secrets or mounted files for sensitive data
  • Single-stage builds: Bloated images with build tools — use multi-stage
  • No healthchecks: Orchestrators can't determine container health
  • bind-mounting in production: Use volumes or copy files into the image
  • Ignoring .dockerignore: Huge build contexts slow down builds

Scripts

ScriptPurposeUsage
generate-dockerfile.ps1Generate production Dockerfile (multi-stage, non-root)./scripts/generate-dockerfile.ps1 [-Port 8080]
generate-compose.ps1Scaffold docker-compose.yml with common services./scripts/generate-compose.ps1 -Services postgres,redis

Quick Commands

TaskCommand
Build imagedocker build -t myapp:1.0 .
Run containerdocker run -d -p 3000:3000 myapp:1.0
Compose updocker compose up -d
Compose downdocker compose down -v
View logsdocker logs -f <container>
Shell into containerdocker exec -it <container> sh
Scan imagedocker scout quickview myapp:1.0
Push to registrydocker push myregistry.azurecr.io/myapp:1.0