AgentSkillsCN

devops-docker

Next.js 前端开发规范。适用于在 Next.js/React 项目中使用 App Router 进行开发时使用。

SKILL.md
--- frontmatter
name: devops-docker
description: Docker containerization best practices. Use when creating Dockerfiles or docker-compose configurations.

DevOps Docker Standards

This skill provides Docker containerization best practices.

When to Use

  • Use this skill when creating or modifying Dockerfiles
  • Use this skill when setting up docker-compose configurations
  • Use this skill when optimizing container images

Instructions

1. Dockerfile Best Practices

Multi-Stage Builds (Mandatory)

ALWAYS use multi-stage builds to minimize final image size.

dockerfile
# Stage 1: Builder
FROM node:20-alpine AS builder

WORKDIR /app

COPY package*.json ./
RUN npm ci

COPY . .
RUN npm run build

# Stage 2: Runner
FROM node:20-alpine AS runner

WORKDIR /app

ENV NODE_ENV=production

# Create non-root user
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 appuser

COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules

USER appuser

EXPOSE 3000

CMD ["node", "dist/main.js"]

Base Images

  • Use alpine or slim versions (e.g., node:20-alpine).
  • NEVER use :latest tag.
  • Pin specific versions for reproducibility.
dockerfile
# Good
FROM node:20.10.0-alpine

# Bad
FROM node:latest

User Permissions

Implement a non-root user for security.

dockerfile
RUN addgroup --system --gid 1001 appgroup
RUN adduser --system --uid 1001 appuser
USER appuser

2. Layer Optimization

Order instructions from least to most frequently changed.

dockerfile
# Good order (least changed first)
FROM node:20-alpine

WORKDIR /app

# Dependencies change less often
COPY package*.json ./
RUN npm ci --only=production

# Source changes more often
COPY . .

CMD ["node", "index.js"]

3. .dockerignore (Mandatory)

Create .dockerignore to exclude unnecessary files.

code
# .dockerignore
.git
.gitignore
node_modules
npm-debug.log
Dockerfile
docker-compose*.yml
.env
.env.*
*.md
.vscode
.idea
coverage
dist
.next

4. Docker Compose

yaml
# docker-compose.yml
version: '3.8'

services:
  api:
    container_name: myapp-api
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=${DATABASE_URL}
    depends_on:
      db:
        condition: service_healthy
    networks:
      - app-network
    restart: unless-stopped

  db:
    container_name: myapp-db
    image: postgres:15-alpine
    environment:
      POSTGRES_USER: ${DB_USER}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_DB: ${DB_NAME}
    volumes:
      - postgres-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USER}"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

volumes:
  postgres-data:

5. Key Docker Compose Rules

  • Naming: Explicitly name containers (container_name: my-app-api).
  • Networks: Define a custom bridge network; do not use the default.
  • Healthchecks: Define for dependent services.
  • Volumes: Use named volumes for data persistence.
  • Restart Policy: Use unless-stopped or always.

6. Environment Variables

Never hardcode secrets. Use .env file passing.

yaml
# docker-compose.yml
services:
  api:
    env_file:
      - .env
    environment:
      # Override or add specific vars
      - NODE_ENV=production

Create .env.example for documentation:

code
# .env.example
DATABASE_URL=postgresql://user:pass@localhost:5432/mydb
JWT_SECRET=your-secret-here

7. Production Checklist

  • Multi-stage build used
  • Non-root user configured
  • Specific image versions (no :latest)
  • .dockerignore present
  • Health checks defined
  • Resource limits set (optional but recommended)
  • Secrets not hardcoded