zee-solution/docs/docker_rule.md

3.9 KiB

Docker Best Practices for ZEE Quiz Application

1. Multi-stage Builds

# Builder stage
FROM golang:1.24.3-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o /zee-app

# Final stage
FROM alpine:3.18
WORKDIR /app
COPY --from=builder /zee-app /app/

# Add non-root user
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

# Health check
HEALTHCHECK --interval=30s --timeout=3s \
  CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1

EXPOSE 8080
ENTRYPOINT ["/app/zee-app"]

2. Security Best Practices

  • Non-root User: Always run containers as non-root user
  • Minimal Base Images: Use alpine or distroless for smaller attack surface
  • Multi-stage Builds: Reduce final image size and remove build tools
  • .dockerignore: Exclude unnecessary files from build context
  • Image Scanning: Use trivy or docker scan for vulnerability scanning

3. Docker Compose Configuration

version: '3.8'

services:
  app:
    build:
      context: .
      target: production
    ports:
      - "8080:8080"
    environment:
      - DATABASE_URL=postgres://user:pass@db:5432/zeedb
    depends_on:
      db:
        condition: service_healthy
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 1G
    healthcheck:
      test: ["CMD", "wget", "--spider", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  db:
    image: postgres:14-alpine
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: zeedb
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./migrations:/docker-entrypoint-initdb.d
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U user -d zeedb"]
      interval: 5s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    command: redis-server --requirepass your_secure_password
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 5

volumes:
  postgres_data:
  redis_data:

4. Development vs Production

Development

  • Mount source code as volume for live reload
  • Enable debug mode
  • Include development tools

Production

  • Use multi-stage builds
  • Remove debug tools
  • Set appropriate resource limits
  • Enable health checks
  • Configure logging drivers

5. Environment Variables

# Application
APP_ENV=production
PORT=8080

# Database
DB_HOST=db
DB_PORT=5432
DB_NAME=zeedb
DB_USER=user
DB_PASSWORD=pass
DB_SSLMODE=disable

# Redis
REDIS_ADDR=redis:6379
REDIS_PASSWORD=your_secure_password

# JWT
JWT_SECRET=your_jwt_secret_key
JWT_EXPIRATION=24h

6. Volume Management

  • Use named volumes for persistent data
  • Set appropriate volume permissions
  • Backup volumes regularly
  • Consider volume encryption for sensitive data

7. Network Configuration

  • Use custom bridge networks
  • Isolate services in dedicated networks
  • Configure proper DNS resolution
  • Set up network policies

8. Logging & Monitoring

  • Configure log rotation
  • Use structured logging
  • Forward logs to centralized system
  • Monitor container metrics

9. CI/CD Integration

# .drone.yml
kind: pipeline
type: docker
name: build-and-push

steps:
  - name: test
    image: golang:1.24
    commands:
      - go test -v ./...

  - name: build
    image: plugins/docker
    settings:
      repo: your-registry/zee-app
      tags: ${DRONE_COMMIT_SHA:0:8}
      dockerfile: Dockerfile
      target: production
    when:
      event: push
      branch: main

10. Security Scanning

# Scan for vulnerabilities
docker scan zee-app

# Check for secrets in code
docker run --rm -v $(pwd):/src/ -v /var/run/docker.sock:/var/run/docker.sock zricethezav/gitleaks:latest detect --source=/src --report=/src/gitleaks.json

# Scan Dockerfile
docker run --rm -i hadolint/hadolint < Dockerfile