$npx -y skills add neuromechanist/research-skills --skill docker-packagingThis skill should be used when the user says \"create Dockerfile\", \"dockerize project\", \"Docker packaging\", \"container setup\", \"multi-stage build\", \"Docker Compose\", \"containerize application\", \"create docker-compose.yml\", \"create .dockerignore\", \"optimize Docke
| 1 | # Docker Packaging |
| 2 | |
| 3 | Generate Docker configurations following project conventions. Supports multi-stage builds, uv-based Python images, and health checks. |
| 4 | |
| 5 | ## When to Use |
| 6 | |
| 7 | - Containerizing a new project |
| 8 | - Optimizing existing Docker images |
| 9 | - Setting up Docker Compose for development |
| 10 | - Adding health checks to containers |
| 11 | - Creating production-ready Docker configurations |
| 12 | |
| 13 | ## Python Project Dockerfile |
| 14 | |
| 15 | Multi-stage build with uv for dependency management: |
| 16 | |
| 17 | ```dockerfile |
| 18 | # Stage 1: Build dependencies |
| 19 | FROM python:3.12-slim AS builder |
| 20 | |
| 21 | COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv |
| 22 | |
| 23 | WORKDIR /app |
| 24 | COPY pyproject.toml uv.lock ./ |
| 25 | RUN uv sync --frozen --no-dev --no-install-project |
| 26 | |
| 27 | COPY . . |
| 28 | RUN uv sync --frozen --no-dev |
| 29 | |
| 30 | # Stage 2: Runtime |
| 31 | FROM python:3.12-slim AS runtime |
| 32 | |
| 33 | RUN addgroup --system app && adduser --system --ingroup app app |
| 34 | |
| 35 | COPY --from=builder /app /app |
| 36 | WORKDIR /app |
| 37 | ENV PATH="/app/.venv/bin:$PATH" |
| 38 | |
| 39 | USER app |
| 40 | EXPOSE 8000 |
| 41 | HEALTHCHECK --interval=30s --timeout=5s --retries=3 \ |
| 42 | CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')" || exit 1 |
| 43 | |
| 44 | CMD ["python", "-m", "app"] |
| 45 | ``` |
| 46 | |
| 47 | Key conventions: |
| 48 | - Always multi-stage (build vs runtime) |
| 49 | - Use uv, never pip |
| 50 | - Copy `pyproject.toml` and `uv.lock` first for layer caching |
| 51 | - Slim base images |
| 52 | - Non-root user for production |
| 53 | - Health checks included |
| 54 | |
| 55 | ## TypeScript/Bun Project Dockerfile |
| 56 | |
| 57 | ```dockerfile |
| 58 | FROM oven/bun:1 AS builder |
| 59 | |
| 60 | WORKDIR /app |
| 61 | COPY package.json bun.lockb ./ |
| 62 | RUN bun install --frozen-lockfile |
| 63 | |
| 64 | COPY . . |
| 65 | RUN bun run build |
| 66 | |
| 67 | FROM oven/bun:1-slim AS runtime |
| 68 | |
| 69 | WORKDIR /app |
| 70 | COPY --from=builder /app/dist ./dist |
| 71 | COPY --from=builder /app/node_modules ./node_modules |
| 72 | COPY --from=builder /app/package.json ./ |
| 73 | |
| 74 | EXPOSE 3000 |
| 75 | HEALTHCHECK --interval=30s --timeout=5s --retries=3 \ |
| 76 | CMD curl -f http://localhost:3000/health || exit 1 |
| 77 | |
| 78 | CMD ["bun", "run", "start"] |
| 79 | ``` |
| 80 | |
| 81 | ## Go Project Dockerfile |
| 82 | |
| 83 | ```dockerfile |
| 84 | FROM golang:1.22-alpine AS builder |
| 85 | |
| 86 | WORKDIR /app |
| 87 | COPY go.mod go.sum ./ |
| 88 | RUN go mod download |
| 89 | |
| 90 | COPY . . |
| 91 | RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /app/server ./cmd/server |
| 92 | |
| 93 | FROM scratch AS runtime |
| 94 | |
| 95 | COPY --from=builder /app/server /server |
| 96 | COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ |
| 97 | |
| 98 | EXPOSE 8080 |
| 99 | ENTRYPOINT ["/server"] |
| 100 | ``` |
| 101 | |
| 102 | ## Docker Compose (Development) |
| 103 | |
| 104 | ```yaml |
| 105 | # docker-compose.yml |
| 106 | services: |
| 107 | app: |
| 108 | build: . |
| 109 | ports: |
| 110 | - "8000:8000" |
| 111 | volumes: |
| 112 | - .:/app |
| 113 | environment: |
| 114 | - DEBUG=1 |
| 115 | depends_on: |
| 116 | db: |
| 117 | condition: service_healthy |
| 118 | |
| 119 | db: |
| 120 | image: postgres:16-alpine |
| 121 | environment: |
| 122 | POSTGRES_DB: app |
| 123 | POSTGRES_USER: app |
| 124 | POSTGRES_PASSWORD: dev-only |
| 125 | ports: |
| 126 | - "5432:5432" |
| 127 | healthcheck: |
| 128 | test: ["CMD-SHELL", "pg_isready -U app"] |
| 129 | interval: 5s |
| 130 | timeout: 5s |
| 131 | retries: 5 |
| 132 | volumes: |
| 133 | - pgdata:/var/lib/postgresql/data |
| 134 | |
| 135 | volumes: |
| 136 | pgdata: |
| 137 | ``` |
| 138 | |
| 139 | ## .dockerignore |
| 140 | |
| 141 | Always create alongside Dockerfile: |
| 142 | |
| 143 | ``` |
| 144 | .git |
| 145 | .github |
| 146 | .context |
| 147 | .rules |
| 148 | .claude |
| 149 | __pycache__ |
| 150 | *.pyc |
| 151 | .venv |
| 152 | node_modules |
| 153 | .env |
| 154 | *.md |
| 155 | !README.md |
| 156 | ``` |
| 157 | |
| 158 | ## Workflow |
| 159 | |
| 160 | ### Step 1: Detect stack and entry point |
| 161 | |
| 162 | Identify the application type, main entry point, exposed ports, and any services it depends on. |
| 163 | |
| 164 | ### Step 2: Generate Dockerfile |
| 165 | |
| 166 | Use the appropriate template. Add security hardening for production (non-root user, read-only filesystem). |
| 167 | |
| 168 | ### Step 3: Generate .dockerignore |
| 169 | |
| 170 | Exclude development files, secrets, and unnecessary build context. |
| 171 | |
| 172 | ### Step 4: Generate docker-compose.yml (if needed) |
| 173 | |
| 174 | Add dependent services (databases, caches, message queues) with health checks. |
| 175 | |
| 176 | ### Step 5: Test |
| 177 | |
| 178 | ```bash |
| 179 | docker build -t app:test . |
| 180 | docker run --rm app:test |
| 181 | ``` |
| 182 | |
| 183 | ## Additional Resources |
| 184 | |
| 185 | - Reference: [references/docker-security.md](references/docker-security.md) - Non-root users, secrets management, image scanning |
| 186 | - Reference: [references/docker-optimization.md](references/docker-optimization.md) - Layer caching, image size reduction, BuildKit |