docker-deployment

Docker Deployment Skill

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "docker-deployment" with this command: npx skills add pfangueiro/claude-code-agents/pfangueiro-claude-code-agents-docker-deployment

Docker Deployment Skill

Provides production-ready Docker configurations, multi-stage builds, and deployment best practices.

Purpose

This skill provides:

  • Optimized Dockerfile patterns for different tech stacks

  • Multi-stage build strategies

  • Docker Compose configurations

  • Container security best practices

  • Docker registry integration

  • Health checks and monitoring

When to Use

  • "Create a Dockerfile for Node.js app"

  • "Optimize Docker image size"

  • "Set up Docker Compose for microservices"

  • "Implement Docker health checks"

  • "Deploy with Docker Swarm/Kubernetes"

Node.js Dockerfile (Multi-Stage Build)

Build stage

FROM node:20-alpine AS builder

WORKDIR /app

Copy package files

COPY package*.json ./

Install dependencies (including dev dependencies for build)

RUN npm ci

Copy source code

COPY . .

Build the application

RUN npm run build

Prune dev dependencies

RUN npm prune --production

Production stage

FROM node:20-alpine AS production

Add non-root user for security

RUN addgroup -g 1001 -S nodejs &&
adduser -S nodejs -u 1001

WORKDIR /app

Copy built artifacts and production dependencies

COPY --from=builder --chown=nodejs:nodejs /app/dist ./dist COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules COPY --from=builder --chown=nodejs:nodejs /app/package*.json ./

Use non-root user

USER nodejs

Expose port

EXPOSE 3000

Health check

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3
CMD node -e "require('http').get('http://localhost:3000/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"

Start application

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

Next.js Dockerfile

FROM node:20-alpine AS deps WORKDIR /app COPY package*.json ./ RUN npm ci

FROM node:20-alpine AS builder WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY . .

ENV NEXT_TELEMETRY_DISABLED 1 RUN npm run build

FROM node:20-alpine AS runner WORKDIR /app

ENV NODE_ENV production ENV NEXT_TELEMETRY_DISABLED 1

RUN addgroup -g 1001 -S nodejs &&
adduser -S nextjs -u 1001

COPY --from=builder /app/public ./public COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs

EXPOSE 3000 ENV PORT 3000

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

Python FastAPI Dockerfile

FROM python:3.11-slim AS builder

WORKDIR /app

Install build dependencies

RUN apt-get update &&
apt-get install -y --no-install-recommends gcc &&
rm -rf /var/lib/apt/lists/*

Copy requirements

COPY requirements.txt .

Install Python dependencies

RUN pip install --user --no-cache-dir -r requirements.txt

Production stage

FROM python:3.11-slim

WORKDIR /app

Copy Python dependencies from builder

COPY --from=builder /root/.local /root/.local

Copy application code

COPY . .

Add local bin to PATH

ENV PATH=/root/.local/bin:$PATH

Create non-root user

RUN useradd -m -u 1001 appuser &&
chown -R appuser:appuser /app

USER appuser

EXPOSE 8000

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health').read()"

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

Docker Compose - Full Stack Application

version: '3.9'

services:

Frontend (Next.js)

frontend: build: context: ./frontend dockerfile: Dockerfile ports: - "3000:3000" environment: - NEXT_PUBLIC_API_URL=http://api:4000 depends_on: api: condition: service_healthy networks: - app-network restart: unless-stopped

Backend API (Node.js)

api: build: context: ./api dockerfile: Dockerfile ports: - "4000:4000" environment: - DATABASE_URL=postgresql://postgres:password@postgres:5432/myapp - REDIS_URL=redis://redis:6379 - NODE_ENV=production depends_on: postgres: condition: service_healthy redis: condition: service_healthy healthcheck: test: ["CMD", "node", "-e", "require('http').get('http://localhost:4000/health')"] interval: 10s timeout: 3s retries: 3 start_period: 30s networks: - app-network restart: unless-stopped volumes: - ./api/uploads:/app/uploads

PostgreSQL Database

postgres: image: postgres:16-alpine environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=password - POSTGRES_DB=myapp volumes: - postgres-data:/var/lib/postgresql/data - ./init-db.sql:/docker-entrypoint-initdb.d/init.sql healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 5s timeout: 3s retries: 5 networks: - app-network restart: unless-stopped

Redis Cache

redis: image: redis:7-alpine command: redis-server --appendonly yes volumes: - redis-data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 3s retries: 5 networks: - app-network restart: unless-stopped

Nginx Reverse Proxy

nginx: image: nginx:alpine ports: - "80:80" - "443:443" volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro - ./ssl:/etc/nginx/ssl:ro depends_on: - frontend - api networks: - app-network restart: unless-stopped

networks: app-network: driver: bridge

volumes: postgres-data: redis-data:

Docker Security Best Practices

Minimal Base Image

Use distroless for minimal attack surface

FROM gcr.io/distroless/nodejs20-debian12

WORKDIR /app

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

CMD ["dist/index.js"]

Multi-Layer Security

FROM node:20-alpine

Security: Run as non-root

RUN addgroup -g 1001 app &&
adduser -D -u 1001 -G app app

WORKDIR /app

Security: Use specific versions

COPY package*.json ./ RUN npm ci --only=production &&
npm cache clean --force

Security: Set file permissions

COPY --chown=app:app . .

Security: Drop capabilities

USER app

Security: Read-only filesystem

(mount volumes for writable areas)

VOLUME ["/app/data"]

EXPOSE 3000

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

.dockerignore

Dependencies

node_modules npm-debug.log

Testing

coverage .jest *.test.js

Environment

.env .env.local .env.*.local

Git

.git .gitignore

CI/CD

.github .gitlab-ci.yml

Documentation

README.md docs/

Build artifacts

dist build *.log

IDE

.vscode .idea *.swp

Docker Registry & CI/CD

GitHub Container Registry

.github/workflows/docker-publish.yml

name: Docker Build & Push

on: push: branches: [ main ] tags: [ 'v*' ]

env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }}

jobs: build-and-push: runs-on: ubuntu-latest permissions: contents: read packages: write

steps:
  - uses: actions/checkout@v4

  - name: Log in to Container Registry
    uses: docker/login-action@v3
    with:
      registry: ${{ env.REGISTRY }}
      username: ${{ github.actor }}
      password: ${{ secrets.GITHUB_TOKEN }}

  - name: Extract metadata
    id: meta
    uses: docker/metadata-action@v5
    with:
      images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
      tags: |
        type=ref,event=branch
        type=ref,event=pr
        type=semver,pattern={{version}}
        type=semver,pattern={{major}}.{{minor}}
        type=sha

  - name: Build and push
    uses: docker/build-push-action@v5
    with:
      context: .
      push: true
      tags: ${{ steps.meta.outputs.tags }}
      labels: ${{ steps.meta.outputs.labels }}
      cache-from: type=gha
      cache-to: type=gha,mode=max

Health Checks

Node.js Health Endpoint

// health.ts export function setupHealthCheck(app: Express) { app.get('/health', async (req, res) => { const checks = { uptime: process.uptime(), timestamp: Date.now(), database: await checkDatabase(), redis: await checkRedis(), memory: process.memoryUsage(), }

const isHealthy = checks.database && checks.redis

res.status(isHealthy ? 200 : 503).json(checks)

}) }

async function checkDatabase(): Promise<boolean> { try { await db.raw('SELECT 1') return true } catch { return false } }

async function checkRedis(): Promise<boolean> { try { await redis.ping() return true } catch { return false } }

Monitoring & Logging

Docker Compose with Logging

services: app: image: myapp:latest logging: driver: "json-file" options: max-size: "10m" max-file: "3" labels: - "prometheus.scrape=true" - "prometheus.port=9090"

Prometheus Metrics Endpoint

// metrics.ts import promClient from 'prom-client'

const register = new promClient.Registry()

promClient.collectDefaultMetrics({ register })

const httpRequestDuration = new promClient.Histogram({ name: 'http_request_duration_ms', help: 'Duration of HTTP requests in ms', labelNames: ['method', 'route', 'status_code'], buckets: [10, 50, 100, 500, 1000, 5000], })

register.registerMetric(httpRequestDuration)

export function setupMetrics(app: Express) { app.get('/metrics', async (req, res) => { res.set('Content-Type', register.contentType) res.end(await register.metrics()) }) }

Best Practices Checklist

  • ✅ Use multi-stage builds to minimize image size

  • ✅ Run containers as non-root user

  • ✅ Use specific base image versions (not latest )

  • ✅ Implement health checks

  • ✅ Set resource limits (CPU/memory)

  • ✅ Use .dockerignore to exclude unnecessary files

  • ✅ Scan images for vulnerabilities (Snyk, Trivy)

  • ✅ Use secrets management (not env vars for sensitive data)

  • ✅ Implement proper logging

  • ✅ Add monitoring and metrics

Integration with Agents

Works best with:

  • devops-automation agent - Generates Docker configs

  • security-auditor agent - Scans for container vulnerabilities

  • performance-optimizer agent - Optimizes image size and startup time

Tools & Resources

  • Docker: Official container platform

  • Docker Compose: Multi-container orchestration

  • Trivy: Vulnerability scanner

  • Dive: Image layer analyzer

  • Hadolint: Dockerfile linter

References

  • Docker Best Practices

  • Node.js Docker Guide

  • Docker Security

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

deep-read

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

git-workflow

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

ci-cd-templates

No summary provided by upstream source.

Repository SourceNeeds Review