@hybridlabor-api/aos 4.8.0 → 4.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/{agents.md → AGENTS.md} +3 -1
- package/.agents/nodes.json +3 -1
- package/.agents/vendor-manifest.json +23 -1
- package/.claude/agents/godmode-media-eventtech.md +1 -1
- package/.claude/hooks/conventional-commits.mjs +125 -0
- package/.claude/hooks/env-file-protection.mjs +105 -0
- package/.claude/hooks/go-gate.mjs +101 -81
- package/.claude/hooks/memb-inject.mjs +29 -1
- package/.claude/settings.json +13 -0
- package/.claude/workflows/startcycle-dispatch.mjs +23 -1
- package/.opencode/agents/godmode-media-eventtech.md +1 -1
- package/.opencode/plugins/bdb-aos.js +31 -4
- package/CLAUDE.md +0 -571
- package/README.de.md +1 -1
- package/README.md +1 -1
- package/README.pt.md +1 -1
- package/THIRD_PARTY_NOTICES.md +126 -0
- package/bin/aos-doctor.mjs +1 -1
- package/docs/skills_table.md +1 -1
- package/installer.js +187 -55
- package/package.json +7 -3
- package/packages/aos-cli/README.md +80 -0
- package/packages/aos-cli/bin/aos-cli.mjs +134 -0
- package/packages/aos-cli/core-skills.json +12 -0
- package/packages/aos-cli/extensions/aos.ts +321 -0
- package/packages/aos-cli/package-lock.json +1923 -0
- package/packages/aos-cli/package.json +29 -0
- package/packages/aos-cli/scripts/check-theme.mjs +63 -0
- package/packages/aos-cli/themes/aos.json +97 -0
- package/scripts/build-plugin-manifest.mjs +131 -0
- package/scripts/validate-skills.mjs +81 -6
- package/skills/basic/ao-orchestrator/SKILL.md +116 -0
- package/skills/basic/bdb-eventagency-skill/SKILL.md +252 -0
- package/skills/basic/bdb-shipping-skill/SKILL.md +161 -0
- package/skills/basic/godmode-eventtech/SKILL.md +4 -1
- package/skills/global_config/agenttrail/SKILL.md +6 -1
- package/skills/global_config/aos-project-init/SKILL.md +2 -0
- package/skills/global_config/aos-project-init/assets/AGENTS.template.md +1 -1
- package/skills/global_config/aos-project-init/scripts/aos-project-doctor.mjs +1 -1
- package/skills/global_config/aos-setup/SKILL.md +1 -1
- package/skills/global_config/aos-setup/scripts/aos-doctor.mjs +1 -1
- package/skills/global_config/ask-tim/SKILL.md +7 -7
- package/skills/global_config/bash-script-generator/SKILL.md +201 -0
- package/skills/global_config/bash-script-generator/assets/templates/standard-template.sh +96 -0
- package/skills/global_config/bash-script-generator/docs/bash-scripting-guide.md +729 -0
- package/skills/global_config/bash-script-generator/docs/generation-best-practices.md +193 -0
- package/skills/global_config/bash-script-generator/docs/script-patterns.md +566 -0
- package/skills/global_config/bash-script-generator/docs/text-processing-guide.md +437 -0
- package/skills/global_config/bash-script-generator/examples/log-analyzer.sh +92 -0
- package/skills/global_config/bash-script-generator/scripts/generate_script_template.sh +123 -0
- package/skills/global_config/bash-script-generator/scripts/run_ci_checks.sh +172 -0
- package/skills/global_config/bash-script-generator/scripts/test_generator.sh +413 -0
- package/skills/global_config/bash-script-validator/SKILL.md +249 -0
- package/skills/global_config/bash-script-validator/docs/awk-reference.md +449 -0
- package/skills/global_config/bash-script-validator/docs/bash-reference.md +468 -0
- package/skills/global_config/bash-script-validator/docs/common-mistakes.md +623 -0
- package/skills/global_config/bash-script-validator/docs/grep-reference.md +395 -0
- package/skills/global_config/bash-script-validator/docs/regex-reference.md +391 -0
- package/skills/global_config/bash-script-validator/docs/sed-reference.md +454 -0
- package/skills/global_config/bash-script-validator/docs/shell-reference.md +463 -0
- package/skills/global_config/bash-script-validator/docs/shellcheck-reference.md +399 -0
- package/skills/global_config/bash-script-validator/examples/bad-bash.sh +55 -0
- package/skills/global_config/bash-script-validator/examples/bad-shell.sh +54 -0
- package/skills/global_config/bash-script-validator/examples/good-bash.sh +71 -0
- package/skills/global_config/bash-script-validator/examples/good-shell.sh +69 -0
- package/skills/global_config/bash-script-validator/scripts/run_ci_checks.sh +23 -0
- package/skills/global_config/bash-script-validator/scripts/shellcheck_wrapper.sh +174 -0
- package/skills/global_config/bash-script-validator/scripts/test_validate.sh +446 -0
- package/skills/global_config/bash-script-validator/scripts/validate.sh +512 -0
- package/skills/global_config/ci-pipeline/SKILL.md +135 -0
- package/skills/global_config/deja-memory/SKILL.md +3 -1
- package/skills/global_config/dispatching-parallel-agents/SKILL.md +170 -0
- package/skills/global_config/dockerfile-generator/SKILL.md +1038 -0
- package/skills/global_config/dockerfile-generator/examples/example.dockerignore +95 -0
- package/skills/global_config/dockerfile-generator/examples/golang-distroless.Dockerfile +34 -0
- package/skills/global_config/dockerfile-generator/examples/java-springboot.Dockerfile +45 -0
- package/skills/global_config/dockerfile-generator/examples/nextjs-production.Dockerfile +49 -0
- package/skills/global_config/dockerfile-generator/examples/nodejs-multistage.Dockerfile +55 -0
- package/skills/global_config/dockerfile-generator/examples/python-fastapi.Dockerfile +48 -0
- package/skills/global_config/dockerfile-generator/references/language_specific_guides.md +510 -0
- package/skills/global_config/dockerfile-generator/references/multistage_builds.md +570 -0
- package/skills/global_config/dockerfile-generator/references/optimization_patterns.md +492 -0
- package/skills/global_config/dockerfile-generator/references/security_best_practices.md +375 -0
- package/skills/global_config/dockerfile-generator/scripts/generate_dockerignore.sh +199 -0
- package/skills/global_config/dockerfile-generator/scripts/generate_golang.sh +172 -0
- package/skills/global_config/dockerfile-generator/scripts/generate_java.sh +185 -0
- package/skills/global_config/dockerfile-generator/scripts/generate_nodejs.sh +279 -0
- package/skills/global_config/dockerfile-generator/scripts/generate_python.sh +218 -0
- package/skills/global_config/dockerfile-generator/scripts/test_generator.sh +210 -0
- package/skills/global_config/dockerfile-validator/SKILL.md +300 -0
- package/skills/global_config/dockerfile-validator/examples/.dockerignore.example +34 -0
- package/skills/global_config/dockerfile-validator/examples/bad-example.Dockerfile +37 -0
- package/skills/global_config/dockerfile-validator/examples/golang-distroless.Dockerfile +50 -0
- package/skills/global_config/dockerfile-validator/examples/good-example.Dockerfile +52 -0
- package/skills/global_config/dockerfile-validator/examples/python-optimized.Dockerfile +53 -0
- package/skills/global_config/dockerfile-validator/examples/security-issues.Dockerfile +42 -0
- package/skills/global_config/dockerfile-validator/references/docker_best_practices.md +348 -0
- package/skills/global_config/dockerfile-validator/references/optimization_guide.md +473 -0
- package/skills/global_config/dockerfile-validator/references/security_checklist.md +208 -0
- package/skills/global_config/dockerfile-validator/scripts/dockerfile-validate.sh +699 -0
- package/skills/global_config/dockerfile-validator/scripts/test_validate.sh +35 -0
- package/skills/global_config/dockerfile-validator/tests/fixtures/copy-before-yarn-lock-read.Dockerfile +6 -0
- package/skills/global_config/dockerfile-validator/tests/fixtures/copy-before-yarn.Dockerfile +6 -0
- package/skills/global_config/dockerfile-validator/tests/fixtures/from-platform-nonroot.Dockerfile +7 -0
- package/skills/global_config/dockerfile-validator/tests/test_regression.sh +164 -0
- package/skills/global_config/finishing-a-development-branch/SKILL.md +228 -0
- package/skills/global_config/github-actions-generator/SKILL.md +353 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/composite/action.yml +82 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/docker/Dockerfile +25 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/docker/action.yml +42 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/docker/entrypoint.sh +27 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/javascript/action.yml +33 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/javascript/index.js +50 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/javascript/package.json +27 -0
- package/skills/global_config/github-actions-generator/assets/templates/workflow/basic_workflow.yml +242 -0
- package/skills/global_config/github-actions-generator/assets/templates/workflow/reusable_workflow.yml +106 -0
- package/skills/global_config/github-actions-generator/examples/README.md +147 -0
- package/skills/global_config/github-actions-generator/examples/actions/setup-node-cached/action.yml +93 -0
- package/skills/global_config/github-actions-generator/examples/caching/docker-buildkit.yml +256 -0
- package/skills/global_config/github-actions-generator/examples/security/dependency-review.yml +62 -0
- package/skills/global_config/github-actions-generator/examples/security/sbom-attestation.yml +119 -0
- package/skills/global_config/github-actions-generator/examples/triggers/chatops-commands.yml +475 -0
- package/skills/global_config/github-actions-generator/examples/triggers/repository-dispatch.yml +418 -0
- package/skills/global_config/github-actions-generator/examples/triggers/workflow-orchestration.yml +404 -0
- package/skills/global_config/github-actions-generator/examples/workflows/docker-build-push.yml +68 -0
- package/skills/global_config/github-actions-generator/examples/workflows/go-ci.yml +161 -0
- package/skills/global_config/github-actions-generator/examples/workflows/monorepo-ci.yml +340 -0
- package/skills/global_config/github-actions-generator/examples/workflows/multi-environment-deploy.yml +406 -0
- package/skills/global_config/github-actions-generator/examples/workflows/nodejs-ci.yml +122 -0
- package/skills/global_config/github-actions-generator/examples/workflows/python-ci.yml +157 -0
- package/skills/global_config/github-actions-generator/examples/workflows/scheduled-tasks.yml +376 -0
- package/skills/global_config/github-actions-generator/references/advanced-triggers.md +917 -0
- package/skills/global_config/github-actions-generator/references/best-practices.md +755 -0
- package/skills/global_config/github-actions-generator/references/common-actions.md +715 -0
- package/skills/global_config/github-actions-generator/references/custom-actions.md +320 -0
- package/skills/global_config/github-actions-generator/references/expressions-and-contexts.md +688 -0
- package/skills/global_config/github-actions-generator/references/modern-features.md +421 -0
- package/skills/global_config/github-actions-generator/scripts/test_generator.sh +344 -0
- package/skills/global_config/github-actions-templates/SKILL.md +7 -0
- package/skills/global_config/github-actions-validator/SKILL.md +576 -0
- package/skills/global_config/github-actions-validator/examples/README.md +88 -0
- package/skills/global_config/github-actions-validator/examples/outdated-versions.yml +76 -0
- package/skills/global_config/github-actions-validator/examples/valid-ci.yml +79 -0
- package/skills/global_config/github-actions-validator/examples/with-errors.yml +47 -0
- package/skills/global_config/github-actions-validator/references/act_usage.md +233 -0
- package/skills/global_config/github-actions-validator/references/action_versions.md +122 -0
- package/skills/global_config/github-actions-validator/references/actionlint_usage.md +343 -0
- package/skills/global_config/github-actions-validator/references/common_errors.md +512 -0
- package/skills/global_config/github-actions-validator/references/modern_features.md +384 -0
- package/skills/global_config/github-actions-validator/references/runners.md +317 -0
- package/skills/global_config/github-actions-validator/scripts/install_tools.sh +113 -0
- package/skills/global_config/github-actions-validator/scripts/validate_workflow.sh +910 -0
- package/skills/global_config/github-actions-validator/tests/test_validate_workflow.sh +237 -0
- package/skills/global_config/makefile-generator/SKILL.md +614 -0
- package/skills/global_config/makefile-generator/assets/templates/.gitkeep +1 -0
- package/skills/global_config/makefile-generator/docs/makefile-structure.md +530 -0
- package/skills/global_config/makefile-generator/docs/optimization-guide.md +784 -0
- package/skills/global_config/makefile-generator/docs/patterns-guide.md +642 -0
- package/skills/global_config/makefile-generator/docs/security-guide.md +361 -0
- package/skills/global_config/makefile-generator/docs/targets-guide.md +642 -0
- package/skills/global_config/makefile-generator/docs/variables-guide.md +596 -0
- package/skills/global_config/makefile-generator/scripts/add_standard_targets.sh +539 -0
- package/skills/global_config/makefile-generator/scripts/generate_makefile_template.sh +690 -0
- package/skills/global_config/makefile-generator/test/test_helper_scripts.sh +190 -0
- package/skills/global_config/makefile-validator/SKILL.md +244 -0
- package/skills/global_config/makefile-validator/docs/bake-tool.md +1000 -0
- package/skills/global_config/makefile-validator/docs/best-practices.md +858 -0
- package/skills/global_config/makefile-validator/docs/common-mistakes.md +944 -0
- package/skills/global_config/makefile-validator/examples/bad-makefile.mk +77 -0
- package/skills/global_config/makefile-validator/examples/good-makefile.mk +103 -0
- package/skills/global_config/makefile-validator/scripts/test_validate.sh +382 -0
- package/skills/global_config/makefile-validator/scripts/validate_makefile.sh +712 -0
- package/skills/global_config/{MCP_Manage → mcp-manage}/SKILL.md +3 -3
- package/skills/global_config/plan-canvas/SKILL.md +9 -2
- package/skills/global_config/plan-canvas/scripts/lib/plan-canvas/ui.js +10 -2
- package/skills/global_config/plan-canvas/scripts/plan-canvas.js +1 -1
- package/skills/global_config/read-the-damn-docs/SKILL.md +175 -0
- package/skills/global_config/requesting-code-review/SKILL.md +98 -0
- package/skills/global_config/requesting-code-review/code-reviewer.md +198 -0
- package/skills/global_config/using-git-worktrees/SKILL.md +170 -0
- package/skills/global_config/verification-before-completion/SKILL.md +123 -0
- package/skills/global_config/writing-plans/SKILL.md +126 -46
- package/skills/global_config/writing-plans-legacy/SKILL.md +152 -0
- package/.claude/CLAUDE.md +0 -12
- package/mcps/RhinoMCP/docs/content/docs/getting-started/gemini.md +0 -61
- /package/{GEMINI.md → RULES.md} +0 -0
|
@@ -0,0 +1,570 @@
|
|
|
1
|
+
# Multi-Stage Docker Builds
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Multi-stage builds allow you to use multiple FROM statements in your Dockerfile. Each FROM instruction can use a different base, and each begins a new stage of the build. You can selectively copy artifacts from one stage to another, leaving behind everything you don't want in the final image.
|
|
6
|
+
|
|
7
|
+
**Benefits:**
|
|
8
|
+
- **Smaller images:** 50-85% size reduction
|
|
9
|
+
- **Separation of concerns:** Build vs runtime environments
|
|
10
|
+
- **Better security:** No build tools in production images
|
|
11
|
+
- **Faster deployments:** Smaller images transfer faster
|
|
12
|
+
- **Cleaner builds:** No manual cleanup scripts needed
|
|
13
|
+
|
|
14
|
+
## Basic Syntax
|
|
15
|
+
|
|
16
|
+
```dockerfile
|
|
17
|
+
# syntax=docker/dockerfile:1
|
|
18
|
+
|
|
19
|
+
# Stage 1: Named "builder"
|
|
20
|
+
FROM golang:1.21-alpine AS builder
|
|
21
|
+
WORKDIR /app
|
|
22
|
+
COPY . .
|
|
23
|
+
RUN go build -o myapp
|
|
24
|
+
|
|
25
|
+
# Stage 2: Final production image
|
|
26
|
+
FROM alpine:3.21
|
|
27
|
+
COPY --from=builder /app/myapp /usr/local/bin/
|
|
28
|
+
CMD ["myapp"]
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Stage Naming
|
|
32
|
+
|
|
33
|
+
### Explicit Names (Recommended)
|
|
34
|
+
|
|
35
|
+
```dockerfile
|
|
36
|
+
# Name stages explicitly for clarity
|
|
37
|
+
FROM node:20 AS dependencies
|
|
38
|
+
RUN npm install
|
|
39
|
+
|
|
40
|
+
FROM node:20 AS builder
|
|
41
|
+
COPY --from=dependencies /app/node_modules ./node_modules
|
|
42
|
+
RUN npm run build
|
|
43
|
+
|
|
44
|
+
FROM node:20-alpine AS production
|
|
45
|
+
COPY --from=builder /app/dist ./dist
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Numeric References (Less Clear)
|
|
49
|
+
|
|
50
|
+
```dockerfile
|
|
51
|
+
# Reference previous stages by number (0-indexed)
|
|
52
|
+
FROM node:20
|
|
53
|
+
RUN npm install
|
|
54
|
+
|
|
55
|
+
FROM node:20
|
|
56
|
+
COPY --from=0 /app/node_modules ./node_modules
|
|
57
|
+
RUN npm run build
|
|
58
|
+
|
|
59
|
+
FROM node:20-alpine
|
|
60
|
+
COPY --from=1 /app/dist ./dist
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Common Patterns
|
|
64
|
+
|
|
65
|
+
### Pattern 1: Build and Runtime Separation
|
|
66
|
+
|
|
67
|
+
**Use Case:** Compiled languages (Go, Rust, C++, Java)
|
|
68
|
+
|
|
69
|
+
```dockerfile
|
|
70
|
+
# Build stage
|
|
71
|
+
FROM golang:1.21-alpine AS builder
|
|
72
|
+
WORKDIR /app
|
|
73
|
+
COPY go.mod go.sum ./
|
|
74
|
+
RUN go mod download
|
|
75
|
+
COPY . .
|
|
76
|
+
RUN CGO_ENABLED=0 GOOS=linux go build -a -ldflags="-s -w" -o main .
|
|
77
|
+
|
|
78
|
+
# Runtime stage
|
|
79
|
+
FROM scratch
|
|
80
|
+
COPY --from=builder /app/main /main
|
|
81
|
+
ENTRYPOINT ["/main"]
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Size Impact:**
|
|
85
|
+
- Builder stage: ~300MB
|
|
86
|
+
- Final image: ~8MB
|
|
87
|
+
- **Reduction: 97%**
|
|
88
|
+
|
|
89
|
+
### Pattern 2: Dependency Installation
|
|
90
|
+
|
|
91
|
+
**Use Case:** Separate dependency installation from application code
|
|
92
|
+
|
|
93
|
+
```dockerfile
|
|
94
|
+
# Dependency stage
|
|
95
|
+
FROM node:20-alpine AS deps
|
|
96
|
+
WORKDIR /app
|
|
97
|
+
COPY package*.json ./
|
|
98
|
+
RUN npm ci --only=production
|
|
99
|
+
|
|
100
|
+
# Build stage
|
|
101
|
+
FROM node:20-alpine AS builder
|
|
102
|
+
WORKDIR /app
|
|
103
|
+
COPY --from=deps /app/node_modules ./node_modules
|
|
104
|
+
COPY . .
|
|
105
|
+
RUN npm run build
|
|
106
|
+
|
|
107
|
+
# Production stage
|
|
108
|
+
FROM node:20-alpine AS runner
|
|
109
|
+
WORKDIR /app
|
|
110
|
+
COPY --from=builder /app/dist ./dist
|
|
111
|
+
COPY --from=deps /app/node_modules ./node_modules
|
|
112
|
+
CMD ["node", "dist/index.js"]
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**Benefits:**
|
|
116
|
+
- Cached dependency layer (only rebuilds when package.json changes)
|
|
117
|
+
- Production dependencies only in final image
|
|
118
|
+
- Faster builds with layer caching
|
|
119
|
+
|
|
120
|
+
### Pattern 3: Test Stage
|
|
121
|
+
|
|
122
|
+
**Use Case:** Run tests without including test dependencies in final image
|
|
123
|
+
|
|
124
|
+
```dockerfile
|
|
125
|
+
# Dependency stage
|
|
126
|
+
FROM python:3.12-slim AS deps
|
|
127
|
+
WORKDIR /app
|
|
128
|
+
COPY requirements.txt requirements-dev.txt ./
|
|
129
|
+
RUN pip install --user -r requirements.txt
|
|
130
|
+
|
|
131
|
+
# Test stage
|
|
132
|
+
FROM deps AS test
|
|
133
|
+
RUN pip install --user -r requirements-dev.txt
|
|
134
|
+
COPY . .
|
|
135
|
+
RUN pytest tests/
|
|
136
|
+
|
|
137
|
+
# Production stage
|
|
138
|
+
FROM python:3.12-slim AS production
|
|
139
|
+
WORKDIR /app
|
|
140
|
+
COPY --from=deps /root/.local /root/.local
|
|
141
|
+
COPY . .
|
|
142
|
+
ENV PATH=/root/.local/bin:$PATH
|
|
143
|
+
CMD ["python", "app.py"]
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Build with tests:**
|
|
147
|
+
```bash
|
|
148
|
+
docker build --target test -t myapp:test .
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
**Build production (tests automatically run before this stage):**
|
|
152
|
+
```bash
|
|
153
|
+
docker build -t myapp:latest .
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Pattern 4: Multi-Architecture
|
|
157
|
+
|
|
158
|
+
**Use Case:** Build for different platforms
|
|
159
|
+
|
|
160
|
+
```dockerfile
|
|
161
|
+
FROM --platform=$BUILDPLATFORM golang:1.21-alpine AS builder
|
|
162
|
+
ARG TARGETARCH
|
|
163
|
+
ARG TARGETOS
|
|
164
|
+
WORKDIR /app
|
|
165
|
+
COPY . .
|
|
166
|
+
RUN GOOS=$TARGETOS GOARCH=$TARGETARCH go build -o app
|
|
167
|
+
|
|
168
|
+
FROM alpine:3.21
|
|
169
|
+
COPY --from=builder /app/app /app
|
|
170
|
+
ENTRYPOINT ["/app"]
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
docker buildx build --platform linux/amd64,linux/arm64 -t myapp:latest .
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Pattern 5: Development vs Production
|
|
178
|
+
|
|
179
|
+
**Use Case:** Different images for dev and prod
|
|
180
|
+
|
|
181
|
+
```dockerfile
|
|
182
|
+
# Base stage with common dependencies
|
|
183
|
+
FROM node:20-alpine AS base
|
|
184
|
+
WORKDIR /app
|
|
185
|
+
COPY package*.json ./
|
|
186
|
+
RUN npm ci
|
|
187
|
+
|
|
188
|
+
# Development stage
|
|
189
|
+
FROM base AS development
|
|
190
|
+
ENV NODE_ENV=development
|
|
191
|
+
COPY . .
|
|
192
|
+
CMD ["npm", "run", "dev"]
|
|
193
|
+
|
|
194
|
+
# Build stage
|
|
195
|
+
FROM base AS builder
|
|
196
|
+
COPY . .
|
|
197
|
+
RUN npm run build
|
|
198
|
+
|
|
199
|
+
# Production stage
|
|
200
|
+
FROM node:20-alpine AS production
|
|
201
|
+
ENV NODE_ENV=production
|
|
202
|
+
WORKDIR /app
|
|
203
|
+
COPY --from=builder /app/dist ./dist
|
|
204
|
+
COPY --from=builder /app/node_modules ./node_modules
|
|
205
|
+
CMD ["node", "dist/server.js"]
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**Build for development:**
|
|
209
|
+
```bash
|
|
210
|
+
docker build --target development -t myapp:dev .
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**Build for production:**
|
|
214
|
+
```bash
|
|
215
|
+
docker build --target production -t myapp:prod .
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Language-Specific Examples
|
|
219
|
+
|
|
220
|
+
### Node.js (Next.js)
|
|
221
|
+
|
|
222
|
+
```dockerfile
|
|
223
|
+
# syntax=docker/dockerfile:1
|
|
224
|
+
|
|
225
|
+
# Dependencies stage
|
|
226
|
+
FROM node:20-alpine AS deps
|
|
227
|
+
WORKDIR /app
|
|
228
|
+
COPY package.json package-lock.json ./
|
|
229
|
+
RUN npm ci
|
|
230
|
+
|
|
231
|
+
# Builder stage
|
|
232
|
+
FROM node:20-alpine AS builder
|
|
233
|
+
WORKDIR /app
|
|
234
|
+
COPY --from=deps /app/node_modules ./node_modules
|
|
235
|
+
COPY . .
|
|
236
|
+
RUN npm run build
|
|
237
|
+
|
|
238
|
+
# Runner stage
|
|
239
|
+
FROM node:20-alpine AS runner
|
|
240
|
+
WORKDIR /app
|
|
241
|
+
ENV NODE_ENV=production
|
|
242
|
+
RUN addgroup --system --gid 1001 nodejs
|
|
243
|
+
RUN adduser --system --uid 1001 nextjs
|
|
244
|
+
COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next
|
|
245
|
+
COPY --from=builder /app/node_modules ./node_modules
|
|
246
|
+
COPY --from=builder /app/package.json ./package.json
|
|
247
|
+
COPY --from=builder /app/public ./public
|
|
248
|
+
USER nextjs
|
|
249
|
+
EXPOSE 3000
|
|
250
|
+
CMD ["npm", "start"]
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Python (Django/FastAPI)
|
|
254
|
+
|
|
255
|
+
```dockerfile
|
|
256
|
+
# syntax=docker/dockerfile:1
|
|
257
|
+
|
|
258
|
+
# Builder stage
|
|
259
|
+
FROM python:3.12-slim AS builder
|
|
260
|
+
WORKDIR /app
|
|
261
|
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
262
|
+
gcc \
|
|
263
|
+
postgresql-dev \
|
|
264
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
265
|
+
COPY requirements.txt .
|
|
266
|
+
RUN pip wheel --no-cache-dir --no-deps --wheel-dir /app/wheels -r requirements.txt
|
|
267
|
+
|
|
268
|
+
# Runner stage
|
|
269
|
+
FROM python:3.12-slim AS runner
|
|
270
|
+
WORKDIR /app
|
|
271
|
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
272
|
+
postgresql-client \
|
|
273
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
274
|
+
COPY --from=builder /app/wheels /wheels
|
|
275
|
+
RUN pip install --no-cache /wheels/*
|
|
276
|
+
COPY . .
|
|
277
|
+
RUN useradd -m -u 1001 app
|
|
278
|
+
USER app
|
|
279
|
+
EXPOSE 8000
|
|
280
|
+
CMD ["uvicorn", "main:app", "--host", "0.0.0.0"]
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Go (Minimal)
|
|
284
|
+
|
|
285
|
+
```dockerfile
|
|
286
|
+
# syntax=docker/dockerfile:1
|
|
287
|
+
|
|
288
|
+
# Builder stage
|
|
289
|
+
FROM golang:1.21-alpine AS builder
|
|
290
|
+
WORKDIR /app
|
|
291
|
+
COPY go.mod go.sum ./
|
|
292
|
+
RUN go mod download
|
|
293
|
+
COPY . .
|
|
294
|
+
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags="-s -w" -o main .
|
|
295
|
+
|
|
296
|
+
# Runner stage (scratch = 0 bytes base)
|
|
297
|
+
FROM scratch
|
|
298
|
+
COPY --from=builder /app/main /main
|
|
299
|
+
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
|
|
300
|
+
USER 1001:1001
|
|
301
|
+
ENTRYPOINT ["/main"]
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Java (Spring Boot)
|
|
305
|
+
|
|
306
|
+
```dockerfile
|
|
307
|
+
# syntax=docker/dockerfile:1
|
|
308
|
+
|
|
309
|
+
# Dependencies stage
|
|
310
|
+
FROM eclipse-temurin:21-jdk-jammy AS deps
|
|
311
|
+
WORKDIR /app
|
|
312
|
+
COPY mvnw pom.xml ./
|
|
313
|
+
COPY .mvn .mvn
|
|
314
|
+
RUN ./mvnw dependency:go-offline
|
|
315
|
+
|
|
316
|
+
# Builder stage
|
|
317
|
+
FROM deps AS builder
|
|
318
|
+
COPY src ./src
|
|
319
|
+
RUN ./mvnw clean package -DskipTests
|
|
320
|
+
|
|
321
|
+
# Extractor stage (for layered JAR)
|
|
322
|
+
FROM builder AS extractor
|
|
323
|
+
WORKDIR /app
|
|
324
|
+
RUN java -Djarmode=layertools -jar target/*.jar extract --destination target/extracted
|
|
325
|
+
|
|
326
|
+
# Runner stage
|
|
327
|
+
FROM eclipse-temurin:21-jre-jammy AS runner
|
|
328
|
+
WORKDIR /app
|
|
329
|
+
RUN useradd -m -u 1001 app
|
|
330
|
+
USER app
|
|
331
|
+
COPY --from=extractor /app/target/extracted/dependencies/ ./
|
|
332
|
+
COPY --from=extractor /app/target/extracted/spring-boot-loader/ ./
|
|
333
|
+
COPY --from=extractor /app/target/extracted/snapshot-dependencies/ ./
|
|
334
|
+
COPY --from=extractor /app/target/extracted/application/ ./
|
|
335
|
+
EXPOSE 8080
|
|
336
|
+
ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"]
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
## Advanced Techniques
|
|
340
|
+
|
|
341
|
+
### Copying from External Images
|
|
342
|
+
|
|
343
|
+
```dockerfile
|
|
344
|
+
# Copy from official images
|
|
345
|
+
FROM alpine:3.21 AS production
|
|
346
|
+
COPY --from=nginx:alpine /usr/share/nginx/html /usr/share/nginx/html
|
|
347
|
+
COPY --from=myregistry/common:latest /app/lib /app/lib
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### Conditional Stages (BuildKit)
|
|
351
|
+
|
|
352
|
+
```dockerfile
|
|
353
|
+
# syntax=docker/dockerfile:1
|
|
354
|
+
ARG BUILD_ENV=production
|
|
355
|
+
|
|
356
|
+
FROM node:20 AS development
|
|
357
|
+
ENV NODE_ENV=development
|
|
358
|
+
CMD ["npm", "run", "dev"]
|
|
359
|
+
|
|
360
|
+
FROM node:20-alpine AS production
|
|
361
|
+
ENV NODE_ENV=production
|
|
362
|
+
CMD ["node", "dist/server.js"]
|
|
363
|
+
|
|
364
|
+
FROM ${BUILD_ENV} AS final
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
```bash
|
|
368
|
+
docker build --build-arg BUILD_ENV=development -t myapp:dev .
|
|
369
|
+
docker build --build-arg BUILD_ENV=production -t myapp:prod .
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### Parallel Stages
|
|
373
|
+
|
|
374
|
+
```dockerfile
|
|
375
|
+
# syntax=docker/dockerfile:1
|
|
376
|
+
|
|
377
|
+
# Independent stages run in parallel
|
|
378
|
+
FROM alpine AS fetch-config
|
|
379
|
+
RUN wget https://example.com/config.json -O /config.json
|
|
380
|
+
|
|
381
|
+
FROM alpine AS fetch-data
|
|
382
|
+
RUN wget https://example.com/data.csv -O /data.csv
|
|
383
|
+
|
|
384
|
+
# Final stage waits for both
|
|
385
|
+
FROM alpine AS final
|
|
386
|
+
COPY --from=fetch-config /config.json /app/
|
|
387
|
+
COPY --from=fetch-data /data.csv /app/
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
## Build Optimization
|
|
391
|
+
|
|
392
|
+
### Target Specific Stage
|
|
393
|
+
|
|
394
|
+
```bash
|
|
395
|
+
# Build only up to specific stage
|
|
396
|
+
docker build --target builder -t myapp:builder .
|
|
397
|
+
|
|
398
|
+
# Useful for debugging
|
|
399
|
+
docker run -it myapp:builder /bin/sh
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
### Cache Mounts with Multi-Stage
|
|
403
|
+
|
|
404
|
+
```dockerfile
|
|
405
|
+
# syntax=docker/dockerfile:1
|
|
406
|
+
|
|
407
|
+
FROM golang:1.21-alpine AS builder
|
|
408
|
+
WORKDIR /app
|
|
409
|
+
COPY go.mod go.sum ./
|
|
410
|
+
RUN --mount=type=cache,target=/go/pkg/mod \
|
|
411
|
+
go mod download
|
|
412
|
+
COPY . .
|
|
413
|
+
RUN --mount=type=cache,target=/go/pkg/mod \
|
|
414
|
+
--mount=type=cache,target=/root/.cache/go-build \
|
|
415
|
+
go build -o app
|
|
416
|
+
|
|
417
|
+
FROM alpine:3.21
|
|
418
|
+
COPY --from=builder /app/app /app
|
|
419
|
+
CMD ["/app"]
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
## Best Practices
|
|
423
|
+
|
|
424
|
+
### 1. Order Stages Logically
|
|
425
|
+
|
|
426
|
+
```dockerfile
|
|
427
|
+
# dependencies → builder → test → production
|
|
428
|
+
FROM node:20 AS deps
|
|
429
|
+
# Install dependencies
|
|
430
|
+
|
|
431
|
+
FROM deps AS builder
|
|
432
|
+
# Build application
|
|
433
|
+
|
|
434
|
+
FROM builder AS test
|
|
435
|
+
# Run tests
|
|
436
|
+
|
|
437
|
+
FROM node:20-alpine AS production
|
|
438
|
+
# Minimal runtime
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
### 2. Name Stages Clearly
|
|
442
|
+
|
|
443
|
+
```dockerfile
|
|
444
|
+
# Good
|
|
445
|
+
FROM golang:1.21 AS compiler
|
|
446
|
+
FROM alpine:3.21 AS runtime
|
|
447
|
+
|
|
448
|
+
# Bad
|
|
449
|
+
FROM golang:1.21 AS stage1
|
|
450
|
+
FROM alpine:3.21 AS stage2
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
### 3. Minimize Final Stage
|
|
454
|
+
|
|
455
|
+
```dockerfile
|
|
456
|
+
# Copy only what's needed
|
|
457
|
+
COPY --from=builder /app/binary /app/binary
|
|
458
|
+
|
|
459
|
+
# Don't copy unnecessary files
|
|
460
|
+
# Bad: COPY --from=builder /app /app
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
### 4. Use Specific Base Images per Stage
|
|
464
|
+
|
|
465
|
+
```dockerfile
|
|
466
|
+
# JDK for building
|
|
467
|
+
FROM eclipse-temurin:21-jdk-jammy AS builder
|
|
468
|
+
|
|
469
|
+
# JRE for running (smaller)
|
|
470
|
+
FROM eclipse-temurin:21-jre-jammy AS runner
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
### 5. Document Stages
|
|
474
|
+
|
|
475
|
+
```dockerfile
|
|
476
|
+
# syntax=docker/dockerfile:1
|
|
477
|
+
|
|
478
|
+
# Stage 1: Install and cache dependencies
|
|
479
|
+
FROM node:20-alpine AS deps
|
|
480
|
+
WORKDIR /app
|
|
481
|
+
COPY package*.json ./
|
|
482
|
+
RUN npm ci
|
|
483
|
+
|
|
484
|
+
# Stage 2: Build application with dependencies
|
|
485
|
+
FROM deps AS builder
|
|
486
|
+
COPY . .
|
|
487
|
+
RUN npm run build
|
|
488
|
+
|
|
489
|
+
# Stage 3: Production runtime with minimal footprint
|
|
490
|
+
FROM node:20-alpine AS production
|
|
491
|
+
ENV NODE_ENV=production
|
|
492
|
+
WORKDIR /app
|
|
493
|
+
COPY --from=builder /app/dist ./dist
|
|
494
|
+
CMD ["node", "dist/server.js"]
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
## Common Pitfalls
|
|
498
|
+
|
|
499
|
+
### 1. Not Using Stage Names
|
|
500
|
+
|
|
501
|
+
```dockerfile
|
|
502
|
+
# Hard to maintain
|
|
503
|
+
FROM node:20
|
|
504
|
+
COPY --from=0 /app/node_modules ./node_modules
|
|
505
|
+
|
|
506
|
+
# Better
|
|
507
|
+
FROM node:20 AS deps
|
|
508
|
+
COPY --from=deps /app/node_modules ./node_modules
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
### 2. Copying Entire Stage
|
|
512
|
+
|
|
513
|
+
```dockerfile
|
|
514
|
+
# Bad - copies everything including build tools
|
|
515
|
+
COPY --from=builder /app /app
|
|
516
|
+
|
|
517
|
+
# Good - copy only artifacts
|
|
518
|
+
COPY --from=builder /app/dist /app/dist
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
### 3. Not Leveraging Cache
|
|
522
|
+
|
|
523
|
+
```dockerfile
|
|
524
|
+
# Bad - copy all before installing
|
|
525
|
+
COPY . .
|
|
526
|
+
RUN npm install
|
|
527
|
+
|
|
528
|
+
# Good - install dependencies first (cached)
|
|
529
|
+
COPY package*.json ./
|
|
530
|
+
RUN npm install
|
|
531
|
+
COPY . .
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
## Troubleshooting
|
|
535
|
+
|
|
536
|
+
### Check Stage Sizes
|
|
537
|
+
|
|
538
|
+
```bash
|
|
539
|
+
# Build with specific target
|
|
540
|
+
docker build --target builder -t myapp:builder .
|
|
541
|
+
docker build --target production -t myapp:production .
|
|
542
|
+
|
|
543
|
+
# Compare sizes
|
|
544
|
+
docker images | grep myapp
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
### Debug Intermediate Stages
|
|
548
|
+
|
|
549
|
+
```bash
|
|
550
|
+
# Build up to specific stage
|
|
551
|
+
docker build --target builder -t debug:builder .
|
|
552
|
+
|
|
553
|
+
# Run and inspect
|
|
554
|
+
docker run -it debug:builder /bin/sh
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
### View Build Process
|
|
558
|
+
|
|
559
|
+
```bash
|
|
560
|
+
# Enable BuildKit with progress
|
|
561
|
+
DOCKER_BUILDKIT=1 docker build --progress=plain .
|
|
562
|
+
|
|
563
|
+
# See all stages and their timing
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
## References
|
|
567
|
+
|
|
568
|
+
- [Docker Multi-stage Builds Documentation](https://docs.docker.com/build/building/multi-stage/)
|
|
569
|
+
- [Multi-stage Build Examples](https://docs.docker.com/get-started/docker-concepts/building-images/multi-stage-builds/)
|
|
570
|
+
- [BuildKit Features](https://docs.docker.com/build/buildkit/)
|