AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL unreviewed MIT Self-run

Docker

skill-kid-sid-claude-spellbook-docker · by kid-sid

Use when writing or optimizing a Dockerfile or docker-compose.yml for local dev, debugging containers that behave differently from local, or reducing image size for Python and Node.js apps. Not for Kubernetes resources or Helm — use containerization.

No reviews yet
0 installs
37 views
0.0% view→install

Install

$ agentstack add skill-kid-sid-claude-spellbook-docker

Open-source listing, not yet scanned by AgentStack. Follow the source repository for install instructions.

Security review

⚠ Flagged

1 finding(s); flagged for manual review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures
  • high Destructive filesystem operation.

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Reliability & compatibility

Not yet reviewed
0 installs to date
no reviews yet
3mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Docker? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Docker Patterns

Production-ready Docker patterns for Python and Node.js services.

When to Activate

  • Writing or optimizing a Dockerfile (multi-stage, layer caching)
  • Configuring Docker Compose services, networking, or volumes
  • Adding health checks or startup dependencies
  • Passing secrets and environment variables safely
  • Debugging a container that won't start or behaves differently in Docker vs local
  • Reducing image size

Dockerfile — Python (FastAPI / uv)

# syntax=docker/dockerfile:1

# --- Build stage ---
FROM python:3.12-slim AS builder

WORKDIR /app

# Install uv
RUN pip install uv --no-cache-dir

# Copy dependency files first — cached unless they change
COPY pyproject.toml uv.lock ./

# Install deps into a prefix (not system), no dev deps
RUN uv sync --frozen --no-dev --prefix /install

# --- Runtime stage ---
FROM python:3.12-slim AS runtime

WORKDIR /app

# Copy installed packages from builder
COPY --from=builder /install /usr/local

# Copy application code last (changes most often)
COPY src/ ./src/

# Non-root user — security best practice
RUN adduser --disabled-password --gecos "" appuser
USER appuser

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

Dockerfile — Node.js (Next.js)

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

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

FROM node:20-alpine AS runtime
WORKDIR /app
ENV NODE_ENV=production

# Only copy what's needed to run
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./public

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

Enable standalone output in next.config.js:

output: "standalone"

.dockerignore

# Always include these
.git
.gitignore
**/.env
**/.env.*
**/node_modules
**/__pycache__
**/*.pyc
**/*.pyo
.venv
dist
build
.next
coverage
*.log
.DS_Store

Layer Caching Rules

Order files from least-changed to most-changed:

# ✅ GOOD — deps cached unless pyproject.toml changes
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen
COPY src/ ./src/           # code changes don't bust dep layer

# ❌ BAD — any code change busts the dep install layer
COPY . .
RUN uv sync --frozen

Cache mounts (BuildKit) — don't write pip/uv cache to image:

RUN --mount=type=cache,target=/root/.cache/uv \
    uv sync --frozen --no-dev

Docker Compose

# docker-compose.yml
services:
  api:
    build:
      context: .
      target: runtime          # use a specific stage
    ports:
      - "5003:8000"
    environment:
      DATABASE_URL: postgresql+asyncpg://user:pass@db:5432/app
      REDIS_URL: redis://redis:6379
    depends_on:
      db:
        condition: service_healthy   # wait for health check, not just start
      redis:
        condition: service_started
    restart: unless-stopped
    networks:
      - backend

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: app
    volumes:
      - pg_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U user -d app"]
      interval: 5s
      timeout: 3s
      retries: 5
      start_period: 10s
    networks:
      - backend

  redis:
    image: redis:7-alpine
    command: redis-server --appendonly yes   # persist to disk
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 3
    networks:
      - backend

volumes:
  pg_data:
  redis_data:

networks:
  backend:
    driver: bridge

Health Checks

# Standard health check pattern
healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
  interval: 30s       # how often to check
  timeout: 10s        # max time per check
  retries: 3          # failures before unhealthy
  start_period: 30s   # grace period before first check counts

FastAPI health endpoint:

@app.get("/health")
async def health():
    return {"status": "ok"}

Environment Variables and Secrets

services:
  api:
    # Option 1: inline (dev only — visible in docker inspect)
    environment:
      SECRET_KEY: dev-secret

    # Option 2: reference host env var (no value = pass-through)
    environment:
      SECRET_KEY: ${SECRET_KEY}

    # Option 3: .env file (dev only — don't commit secrets)
    env_file:
      - .env

    # Option 4: Docker secrets (production / Swarm)
    secrets:
      - db_password

secrets:
  db_password:
    file: ./secrets/db_password.txt

Access secret in container at /run/secrets/db_password.


Networking

networks:
  frontend:   # API + nginx
  backend:    # API + DB + Redis (not exposed to frontend network)

services:
  nginx:
    networks: [frontend]
  api:
    networks: [frontend, backend]   # bridge between networks
  db:
    networks: [backend]             # only reachable from backend

Service DNS: containers on the same network reach each other by service name.

# From api container, reach db:
postgresql://db:5432/mydb       # "db" resolves to the db container IP
redis://redis:6379

Common Commands

# Build
docker build -t myapp .
docker build --target builder -t myapp:builder .   # build specific stage
docker build --no-cache -t myapp .                  # force rebuild

# Compose
docker compose up -d                   # start in background
docker compose up --build              # rebuild before starting
docker compose down -v                 # stop + remove volumes
docker compose logs -f api             # follow logs for one service
docker compose exec api bash           # shell into running container
docker compose ps                      # status of all services

# Inspect
docker inspect              # full config, env vars, mounts
docker stats                           # live resource usage
docker system df                       # disk usage by layer/image/volume

# Cleanup
docker system prune -f                 # remove stopped containers + dangling images
docker volume prune -f                 # remove unused volumes
docker image prune -a -f               # remove all unused images

Debugging

# Container exits immediately — run it interactively
docker run -it --entrypoint bash myapp

# Check environment inside container
docker exec  env

# Copy files out of container
docker cp :/app/logs ./local-logs

# Run with host network (skip Docker networking)
docker run --network host myapp

# Override CMD for one-off
docker compose run --rm api python manage.py migrate

Image Size Reduction

| Technique | Savings | |---|---| | Use slim/alpine base (python:3.12-slim) | 60–80% vs full image | | Multi-stage build — don't ship build tools | varies | | --no-install-recommends on apt-get | 20–40% | | Remove apt cache: rm -rf /var/lib/apt/lists/* | small | | --no-cache-dir on pip | small | | .dockerignore to skip test/docs | small |

# Minimal apt install pattern
RUN apt-get update && apt-get install -y --no-install-recommends \
    curl \
    && rm -rf /var/lib/apt/lists/*

Red Flags

  • COPY . . before installing dependencies — copying all source code first busts the dependency layer on every code change; always COPY pyproject.toml uv.lock ./ → install → COPY src/ ./ so deps are cached unless manifests change
  • Running the container as root — the default user is root inside a container; a process escape gives the attacker full host access; always add RUN adduser --disabled-password appuser && USER appuser in the runtime stage
  • No health check on services others depends_ondepends_on without condition: service_healthy starts the dependent service immediately, before the dependency is actually ready; always define a healthcheck and use service_healthy
  • Secrets in environment: as plaintext — environment variables are visible in docker inspect, CI logs, and image layers if baked in; use Docker secrets, a secrets manager, or pass via host env refs (SECRET_KEY: ${SECRET_KEY})
  • No .dockerignore — without it, COPY . . sends the entire repo (.git, node_modules, __pycache__, .env) into the build context, bloating image size and potentially leaking secrets
  • Single-stage build shipping build tools to production — compilers, dev headers, and test dependencies included in the runtime image increase attack surface and image size; use multi-stage builds so the runtime stage starts fresh from a slim base
  • Anonymous volumes for data that must persistvolumes: ["/var/lib/postgresql/data"] (without a named volume) is recreated on docker compose down; use named volumes (pg_data:/var/lib/postgresql/data) to persist data across restarts

Checklist

  • [ ] Multi-stage build used — builder installs, runtime only has what's needed
  • [ ] .dockerignore excludes .git, node_modules, .env, __pycache__
  • [ ] Dependencies copied before source code (layer cache)
  • [ ] Non-root user for runtime stage
  • [ ] Health check defined for services that others depends_on
  • [ ] depends_on uses condition: service_healthy not just service_started
  • [ ] Secrets not hardcoded in Dockerfile or committed .env
  • [ ] Volumes named (not anonymous) for data you want to persist

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.