Skip to content
Back to skills

Docker

DSecurity

Detect project stack and generate production-ready multi-stage Dockerfiles with compose services, .dockerignore, non-root users, health checks, layer caching, and optional dev hot-reload profiles

  • 15 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added May 29, 2026
ai-agentstypescriptpythonrustgojavarubysqlnextjsnodeexpress

Works with

  • vscode
  • cli
  • api

Security analysis

D42/100
  • mediumUses curl or wget to download content
  • criticalExfiltrates credentials via HTTP — exact pattern from Snyk ToxicSkills study
  • criticalExfiltrates credentials via HTTP — exact pattern from Snyk ToxicSkills study

Pro shows the line behind each finding and how to fix it

Scanned May 29, 2026

npx -y skills add tinh2/skills-hub-registry --skill docker --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Docker?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Docker
[![Security: D — Skills Directory](https://www.skillsdirectory.com/api/skills/tinh2-docker/badge)](https://www.skillsdirectory.com/skills/tinh2-docker)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: docker
description: "Detect project stack and generate production-ready multi-stage Dockerfiles with compose services, .dockerignore, non-root users, health checks, layer caching, and optional dev hot-reload profiles"
version: "2.0.0"
category: deploy
platforms:
  - CLAUDE_CODE
---

You are in AUTONOMOUS MODE. Do NOT ask questions. Do NOT pause for confirmation.
Execute every phase below in sequence, making decisions based on what you find.

============================================================
PHASE 0 — INPUT
============================================================

$ARGUMENTS may contain:
- `--compose` — also generate docker-compose.yml (default: auto-detect need)
- `--dev` — include development compose profile with hot reload
- `--prod` — optimize for production (smaller image, no dev deps)
- `--registry <url>` — target container registry (default: ghcr.io)
- A specific service name to Dockerize (for monorepos)
- `--slim` — use Alpine/distroless base images for minimal size

If no arguments, generate both Dockerfile and docker-compose.yml if the project has dependencies (database, cache, etc.).

============================================================
PHASE 1 — STACK DETECTION
============================================================

Detect the application stack by reading manifest files:

**Node.js**:
- Read `package.json` for: `engines.node`, `scripts.start`, `scripts.build`, framework
- Lock file determines package manager: `package-lock.json` (npm), `yarn.lock` (yarn), `pnpm-lock.yaml` (pnpm)
- Framework detection: Next.js (`next.config.*`), Fastify, Express, NestJS, Remix, Astro
- Check for `tsconfig.json` — TypeScript build step needed

**Python**:
- Read `pyproject.toml`, `requirements.txt`, `Pipfile`, `setup.py`
- Framework: Django (`manage.py`), Flask, FastAPI (`uvicorn`/`gunicorn`)
- Python version from `.python-version`, `pyproject.toml`, or `runtime.txt`

**Go**:
- Read `go.mod` for module name and Go version
- Check for `cmd/main.go` or `main.go` entry point
- Static binary — ideal for scratch/distroless final stage

**Rust**:
- Read `Cargo.toml` for binary name
- Static binary with musl target — ideal for scratch/distroless

**Java**:
- Read `pom.xml` (Maven) or `build.gradle` (Gradle)
- Check for Spring Boot, Quarkus, Micronaut
- JRE-only final stage

**Ruby**:
- Read `Gemfile` for Ruby version and framework (Rails, Sinatra)
- Check for `config.ru` (Rack app)

Also detect dependencies that need compose services:
- **Database**: Prisma schema, SQLAlchemy, GORM, ActiveRecord, TypeORM — note the DB engine
- **Cache**: Redis references in config/code
- **Message queue**: RabbitMQ, Kafka references
- **Search**: Elasticsearch references
- **Object storage**: S3/MinIO references

============================================================
PHASE 2 — GENERATE DOCKERFILE
============================================================

Create a multi-stage `Dockerfile` following these principles:

**Stage 1 — Dependencies** (`deps` or `builder`):
- Use specific version tags, never `latest` (e.g., `node:22-alpine`, `python:3.12-slim`)
- Copy lock file BEFORE source code (layer caching optimization)
- Install only production dependencies first
- Use `--mount=type=cache` for package manager caches where supported

**Stage 2 — Build** (if applicable):
- Copy source code after dependency install
- Run build command (`npm run build`, `go build`, `cargo build --release`)
- For compiled languages, produce a static binary if possible

**Stage 3 — Production**:
- Use smallest appropriate base image:
  - Node.js: `node:22-alpine` (or `distroless` if `--slim`)
  - Python: `python:3.12-slim`
  - Go: `gcr.io/distroless/static-debian12` or `scratch`
  - Rust: `gcr.io/distroless/cc-debian12` or `scratch`
  - Java: `eclipse-temurin:21-jre-alpine`
  - Ruby: `ruby:3.3-slim`
- Copy only built artifacts and production deps from previous stages
- Set `WORKDIR /app`

**Security hardening** (always apply):
- Create non-root user with fixed UID/GID 1001
- `USER appuser` before CMD
- No `apt-get upgrade` — pin base image version instead

**Health check** (always include):
- `HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3`
- Node.js: `wget --no-verbose --tries=1 --spider http://localhost:${PORT}/health || exit 1`
- Python: `curl -f http://localhost:${PORT}/health || exit 1`
- Go: built-in health endpoint check
- For apps without a health endpoint, note that one should be created

**Labels** (OCI standard):
```dockerfile
LABEL org.opencontainers.image.source="https://github.com/OWNER/REPO"
LABEL org.opencontainers.image.description="Description"
```

**Environment**:
- Set `NODE_ENV=production` or equivalent
- Set default `PORT` and `EXPOSE` it
- Never bake secrets into the image

============================================================
PHASE 3 — GENERATE .dockerignore
============================================================

Create `.dockerignore` to minimize build context. Always exclude:
- `.git` directory
- IDE config (`.vscode`, `.idea`)
- Test coverage output (`coverage`, `.nyc_output`, `.pytest_cache`)
- Environment files (`.env*`)
- Build artifacts that will be regenerated in the container
- `node_modules` (rebuilt inside container)
- Documentation files (`*.md`)

Adjust patterns based on detected stack.

============================================================
PHASE 4 — GENERATE DOCKER COMPOSE
============================================================

Create `docker-compose.yml` if the application has external dependencies or `--compose` is set.

**Structure requirements**:
- Omit `version:` field (Docker Compose V2+ does not need it)
- Use `depends_on` with `condition: service_healthy` for startup ordering
- Use named volumes for data persistence
- Use a named bridge network for service communication
- Use environment variable references `${VAR:-default}` for configurable values
- Set `restart: unless-stopped` on all services

**Database services**: Include proper health checks:
- PostgreSQL: `pg_isready -U postgres`
- MySQL: `mysqladmin ping -h localhost`
- MongoDB: `mongosh --eval "db.runCommand('ping')"`

**Cache services**: Include memory limits and eviction policy configuration.

**Development profile** (if `--dev`):
Create a `docker-compose.dev.yml` override with:
- Source code mounted as volume for hot reload
- Development build target in Dockerfile
- Debug ports exposed
- `NODE_ENV=development` or equivalent

============================================================
PHASE 5 — VALIDATION
============================================================

After generating files, verify:

1. **Layer ordering** — dependency install comes before source copy
2. **No secrets** — no hardcoded passwords, API keys, or tokens in Dockerfile or compose
3. **Port consistency** — EXPOSE matches the app's actual listen port
4. **Health check** — endpoint referenced in HEALTHCHECK actually exists (or note to create it)
5. **Base image tags** — all pinned to specific versions, no `latest`
6. **Non-root user** — USER directive is present and set before CMD


============================================================
SELF-HEALING VALIDATION (max 2 iterations)
============================================================

After completing deployment/infrastructure changes, validate:

1. Verify all generated files are syntactically valid (YAML, JSON, HCL, Dockerfile).
2. Run validation commands if available (terraform validate, docker build --check, kubectl dry-run).
3. Verify no secrets, credentials, or sensitive values are hardcoded.
4. If validation fails, diagnose and fix the specific syntax or config error.
5. Repeat up to 2 iterations.

IF STILL FAILING after 2 iterations:
- Document what failed and the exact error
- Include partial output if available

============================================================
OUTPUT
============================================================

Print a summary:

```
## Docker Setup Complete

### Files Created
- Dockerfile — Multi-stage build ({base image}, {final size estimate})
- .dockerignore — {N} patterns to minimize build context
- docker-compose.yml — Services: {list}
- docker-compose.dev.yml — Development overrides (if generated)

### Build Commands
- Production: docker compose up --build -d
- Development: docker compose -f docker-compose.yml -f docker-compose.dev.yml up
- Image only: docker build -t {name}:latest .

### Image Details
- Base: {base image}
- Estimated size: {size estimate}
- User: appuser (non-root, UID 1001)
- Health check: {endpoint}
- Exposed port: {port}

### Services
| Service | Image | Port | Volume |
|---------|-------|------|--------|
| app | built | {port} | -- |
| db | postgres:16 | 5432 | db-data |
```

============================================================
NEXT STEPS
============================================================

1. Build and test locally: `docker compose up --build`
2. Add a `/health` endpoint to the application if one does not exist
3. Configure CI/CD to build and push the Docker image (run `deploy/github-actions`)
4. Set real database credentials via environment variables or secrets manager (run `deploy/secrets`)


============================================================
SELF-EVOLUTION TELEMETRY
============================================================

After producing output, record execution metadata for the /evolve pipeline.

Check if a project memory directory exists:
- Look for the project path in `~/.claude/projects/`
- If found, append to `skill-telemetry.md` in that memory directory

Entry format:
```
### /docker — {{YYYY-MM-DD}}
- Outcome: {{SUCCESS | PARTIAL | FAILED}}
- Self-healed: {{yes — what was healed | no}}
- Iterations used: {{N}} / {{N max}}
- Bottleneck: {{phase that struggled or "none"}}
- Suggestion: {{one-line improvement idea for /evolve, or "none"}}
```

Only log if the memory directory exists. Skip silently if not found.
Keep entries concise — /evolve will parse these for skill improvement signals.

============================================================
DO NOT
============================================================

- Do NOT use `latest` tag for base images — pin to specific versions
- Do NOT run containers as root — always create and switch to a non-root user
- Do NOT copy `.env` files into the image — use environment variables at runtime
- Do NOT install development dependencies in the production stage
- Do NOT use `ADD` when `COPY` suffices (ADD has implicit tar extraction and URL fetch)
- Do NOT include `apt-get upgrade` — use a pinned base image instead
- Do NOT leave package manager caches in final image (use `--mount=type=cache` or clean up)
- Do NOT overwrite an existing Dockerfile without reading it first and preserving custom configuration
- Do NOT hardcode database passwords — use environment variable references

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…