SPB Git

spb/ultra-sharp-agent-skills Public

Ultra-Sharp Agent Skills — a research-first skill-authoring system + 72 production-ready skills for AI agents.

Python 100%

# name: containerizing-services description: Containerizes backend services with production-grade Dockerfiles — multi-stage builds, pinned base images, non-root users, healthchecks, and small images. Use when the user asks to write or review a Dockerfile, dockerize or containerize a service or app, shrink a Docker image, or fix container build or security issues. Do not use for Kubernetes manifests or orchestration, docker-compose service topology, or CI pipeline design (shipping-with-ci-cd).

# Containerizing Services

# When to use / when NOT to use

  • Use for: writing or reviewing Dockerfiles, image size/security hardening, build-cache problems.
  • Do NOT use for: Kubernetes/orchestration, compose topology, CI pipelines (shipping-with-ci-cd), or app code changes.

# Core rules

  1. Multi-stage: build heavy, run slim. Compile/install in a build stage; copy only artifacts into the runtime stage.
    • FROM node:22.4-slim AS buildFROM node:22.4-slim + COPY --from=build /app/dist ./dist
    • ❌ One stage that ships compilers, dev deps, and source history.
  2. Pin base images. Exact tag minimum; digest for production.
    • FROM python:3.12.4-slim@sha256:…
    • FROM python:latest
  3. Run as non-root. Create a user and switch: USER app. Root-only containers fail most cluster policies and widen every exploit.
  4. Order layers for cache. Copy dependency manifests and install BEFORE copying source, so code edits don't bust the dependency layer.
    • COPY package*.json ./RUN npm ciCOPY . .
    • COPY . . first (every commit reinstalls everything).
  5. One process per container. No supervisord bundles; sidecars belong to the orchestrator. Logs go to stdout/stderr only — never files inside the container.
  6. Ship a .dockerignore. At minimum: .git, node_modules/venvs, .env*, secrets, test fixtures. Never COPY a secret; pass at runtime.
  7. Define HEALTHCHECK (or document the orchestrator probe) hitting a real readiness endpoint, not /.
  8. Default slim/distroless; alpine only knowingly. musl breaks some native wheels/binaries — use alpine only after the app is verified on it.

# Workflow

  1. Pick runtime base (<lang>:<exact-version>-slim default; distroless escape hatch for static binaries).
  2. Write .dockerignore before the Dockerfile.
  3. Write multi-stage Dockerfile per rules 1–8.
  4. Build: docker build -t svc:dev . — rebuild after touching one source file and confirm the dependency layer is cached (CACHED in output).
  5. Validate: docker run --rm svc:dev id -u returns non-zero UID; docker inspect --format='{{.Config.Healthcheck}}' svc:dev is set; docker run --rm --read-only svc:dev starts (add tmpfs mounts if the app needs scratch dirs).
  6. Check size: docker images svc:dev — if the runtime image exceeds ~2× the artifact size, find what leaked in (docker history svc:dev).

# Edge cases & failure modes

  • Native deps fail on slim → install build tools in the build stage only (apt-get install -y --no-install-recommends build-essential), never in runtime.
  • Secrets needed at build timeRUN --mount=type=secret,id=npm_token … (BuildKit); never ARG a secret (it persists in history).
  • Image works locally, fails in cluster as non-root → files owned by root; COPY --chown=app:app.
  • Timezone/CA errors in distroless → use the :debug or cc variant, or copy ca-certificates from the build stage.

# References

Deeper recipes and gotchas: see references/patterns.md.