@martinffx/atelier 1.4.0 → 3.0.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/CHANGELOG.md +38 -0
- package/README.md +95 -220
- package/agents/architect.md +6 -6
- package/agents/oracle.md +1 -1
- package/agents/{recon.md → sentinel.md} +3 -3
- package/dist/atelier.js +167 -26
- package/package.json +2 -1
- package/skills/atelier-orchestrator/SKILL.md +180 -0
- package/skills/atelier-setup/SKILL.md +80 -0
- package/skills/code-review/SKILL.md +2 -2
- package/skills/code-review/references/reviewers.md +3 -3
- package/skills/code-review/references/rq.md +9 -9
- package/skills/code-subagents/SKILL.md +44 -75
- package/skills/code-subagents/references/batch-reviewer-prompt.md +44 -0
- package/skills/code-subagents/references/implementor-prompt.md +10 -11
- package/skills/spec-brainstorm/SKILL.md +21 -16
- package/skills/spec-finish/SKILL.md +14 -14
- package/skills/spec-implement/SKILL.md +42 -42
- package/skills/spec-plan/SKILL.md +72 -26
- package/skills/spec-plan/references/plan_template.md +77 -0
- package/skills/code-subagents/references/code-quality-reviewer-prompt.md +0 -48
- package/skills/code-subagents/references/spec-reviewer-prompt.md +0 -62
- package/skills/python-architecture/SKILL.md +0 -148
- package/skills/python-architecture/references/data-modeling.md +0 -558
- package/skills/python-architecture/references/ddd.md +0 -569
- package/skills/python-architecture/references/functional-core.md +0 -337
- package/skills/python-build-tools/SKILL.md +0 -153
- package/skills/python-build-tools/references/basedpyright.md +0 -321
- package/skills/python-build-tools/references/ruff.md +0 -225
- package/skills/python-build-tools/references/uv.md +0 -257
- package/skills/python-fastapi/SKILL.md +0 -184
- package/skills/python-fastapi/references/api-design.md +0 -563
- package/skills/python-fastapi/references/dependencies.md +0 -479
- package/skills/python-fastapi/references/middleware.md +0 -475
- package/skills/python-fastapi/references/validation.md +0 -497
- package/skills/python-modern-python/SKILL.md +0 -201
- package/skills/python-modern-python/references/async.md +0 -76
- package/skills/python-modern-python/references/pattern-matching.md +0 -89
- package/skills/python-modern-python/references/typing.md +0 -96
- package/skills/python-monorepo/SKILL.md +0 -146
- package/skills/python-monorepo/references/docker.md +0 -515
- package/skills/python-monorepo/references/namespace-packages.md +0 -426
- package/skills/python-monorepo/references/workspace-config.md +0 -341
- package/skills/python-sqlalchemy/SKILL.md +0 -119
- package/skills/python-sqlalchemy/references/async.md +0 -51
- package/skills/python-sqlalchemy/references/models.md +0 -67
- package/skills/python-sqlalchemy/references/queries.md +0 -57
- package/skills/python-temporal/SKILL.md +0 -128
- package/skills/python-temporal/references/patterns.md +0 -87
- package/skills/python-temporal/references/testing.md +0 -54
- package/skills/python-testing/SKILL.md +0 -161
- package/skills/python-testing/references/boundaries.md +0 -449
- package/skills/python-testing/references/mocking.md +0 -449
- package/skills/python-testing/references/pytest.md +0 -524
- package/skills/spec-orchestrator/SKILL.md +0 -145
- package/skills/typescript-api-design/SKILL.md +0 -396
- package/skills/typescript-api-design/references/error-responses.md +0 -469
- package/skills/typescript-build-tools/SKILL.md +0 -447
- package/skills/typescript-build-tools/references/biome.md +0 -436
- package/skills/typescript-build-tools/references/bun.md +0 -432
- package/skills/typescript-build-tools/references/turborepo.md +0 -426
- package/skills/typescript-build-tools/references/vitest.md +0 -518
- package/skills/typescript-drizzle-orm/SKILL.md +0 -398
- package/skills/typescript-drizzle-orm/references/cloudflare.md +0 -392
- package/skills/typescript-drizzle-orm/references/entity-pattern.md +0 -412
- package/skills/typescript-drizzle-orm/references/postgresql.md +0 -191
- package/skills/typescript-drizzle-orm/references/repository-pattern.md +0 -479
- package/skills/typescript-drizzle-orm/references/sqlite.md +0 -291
- package/skills/typescript-dynamodb-toolbox/SKILL.md +0 -370
- package/skills/typescript-dynamodb-toolbox/references/entity-layer.md +0 -574
- package/skills/typescript-dynamodb-toolbox/references/error-handling.md +0 -495
- package/skills/typescript-dynamodb-toolbox/references/modeling.md +0 -332
- package/skills/typescript-dynamodb-toolbox/references/repository-layer.md +0 -631
- package/skills/typescript-dynamodb-toolbox/references/testing.md +0 -718
- package/skills/typescript-dynamodb-toolbox/references/transactions.md +0 -423
- package/skills/typescript-effect-ts/SKILL.md +0 -341
- package/skills/typescript-effect-ts/references/core.md +0 -412
- package/skills/typescript-effect-ts/references/error-handling.md +0 -468
- package/skills/typescript-effect-ts/references/resources.md +0 -476
- package/skills/typescript-effect-ts/references/schema.md +0 -536
- package/skills/typescript-effect-ts/references/services.md +0 -461
- package/skills/typescript-fastify/SKILL.md +0 -405
- package/skills/typescript-fastify/references/plugins.md +0 -329
- package/skills/typescript-fastify/references/typeid.md +0 -315
- package/skills/typescript-functional-patterns/SKILL.md +0 -402
- package/skills/typescript-functional-patterns/references/adts.md +0 -497
- package/skills/typescript-functional-patterns/references/branded-types.md +0 -542
- package/skills/typescript-functional-patterns/references/migration-guide.md +0 -695
- package/skills/typescript-functional-patterns/references/option-result.md +0 -585
- package/skills/typescript-testing/SKILL.md +0 -353
- package/skills/typescript-testing/references/mocking.md +0 -675
- package/skills/typescript-testing/references/msw.md +0 -852
- package/skills/typescript-testing/references/snapshot-testing.md +0 -774
|
@@ -1,515 +0,0 @@
|
|
|
1
|
-
# Docker Builds for Python Workspaces
|
|
2
|
-
|
|
3
|
-
Optimized Docker builds for Python monorepos using uv workspaces.
|
|
4
|
-
|
|
5
|
-
## Basic Multi-Stage Build
|
|
6
|
-
|
|
7
|
-
**apps/api/Dockerfile:**
|
|
8
|
-
|
|
9
|
-
```dockerfile
|
|
10
|
-
# Build stage - install dependencies
|
|
11
|
-
FROM python:3.12-slim AS builder
|
|
12
|
-
|
|
13
|
-
# Install uv
|
|
14
|
-
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
|
|
15
|
-
|
|
16
|
-
WORKDIR /app
|
|
17
|
-
|
|
18
|
-
# Copy workspace configuration
|
|
19
|
-
COPY pyproject.toml uv.lock ./
|
|
20
|
-
|
|
21
|
-
# Copy all packages (needed for workspace dependencies)
|
|
22
|
-
COPY packages/ ./packages/
|
|
23
|
-
|
|
24
|
-
# Copy this app
|
|
25
|
-
COPY apps/api/ ./apps/api/
|
|
26
|
-
|
|
27
|
-
# Install dependencies into .venv
|
|
28
|
-
RUN uv sync --frozen --no-dev --package my-api
|
|
29
|
-
|
|
30
|
-
# Runtime stage - minimal image
|
|
31
|
-
FROM python:3.12-slim
|
|
32
|
-
|
|
33
|
-
WORKDIR /app
|
|
34
|
-
|
|
35
|
-
# Copy virtual environment from builder
|
|
36
|
-
COPY --from=builder /app/.venv /app/.venv
|
|
37
|
-
|
|
38
|
-
# Copy source code
|
|
39
|
-
COPY --from=builder /app/apps/api /app/apps/api
|
|
40
|
-
COPY --from=builder /app/packages /app/packages
|
|
41
|
-
|
|
42
|
-
# Add .venv to PATH
|
|
43
|
-
ENV PATH="/app/.venv/bin:$PATH"
|
|
44
|
-
ENV PYTHONPATH="/app"
|
|
45
|
-
|
|
46
|
-
# Run application
|
|
47
|
-
CMD ["python", "-m", "my_api.main"]
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
**Benefits:**
|
|
51
|
-
- Multi-stage: build stage separate from runtime
|
|
52
|
-
- Smaller final image (no build tools)
|
|
53
|
-
- Cached layers (dependencies cached separately)
|
|
54
|
-
|
|
55
|
-
## Layer Caching Optimization
|
|
56
|
-
|
|
57
|
-
Optimize Docker layer caching by copying files in dependency order:
|
|
58
|
-
|
|
59
|
-
```dockerfile
|
|
60
|
-
FROM python:3.12-slim AS builder
|
|
61
|
-
|
|
62
|
-
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
|
|
63
|
-
|
|
64
|
-
WORKDIR /app
|
|
65
|
-
|
|
66
|
-
# Step 1: Copy lock files (changes rarely)
|
|
67
|
-
COPY pyproject.toml uv.lock ./
|
|
68
|
-
|
|
69
|
-
# Step 2: Copy package metadata only (for dependency resolution)
|
|
70
|
-
COPY packages/core/pyproject.toml ./packages/core/
|
|
71
|
-
COPY packages/utils/pyproject.toml ./packages/utils/
|
|
72
|
-
COPY apps/api/pyproject.toml ./apps/api/
|
|
73
|
-
|
|
74
|
-
# Step 3: Install dependencies (cached if pyproject.toml unchanged)
|
|
75
|
-
RUN uv sync --frozen --no-dev --package my-api
|
|
76
|
-
|
|
77
|
-
# Step 4: Copy source code (changes frequently)
|
|
78
|
-
COPY packages/ ./packages/
|
|
79
|
-
COPY apps/api/ ./apps/api/
|
|
80
|
-
|
|
81
|
-
# Runtime stage
|
|
82
|
-
FROM python:3.12-slim
|
|
83
|
-
|
|
84
|
-
WORKDIR /app
|
|
85
|
-
|
|
86
|
-
COPY --from=builder /app/.venv /app/.venv
|
|
87
|
-
COPY --from=builder /app/apps/api /app/apps/api
|
|
88
|
-
COPY --from=builder /app/packages /app/packages
|
|
89
|
-
|
|
90
|
-
ENV PATH="/app/.venv/bin:$PATH"
|
|
91
|
-
ENV PYTHONPATH="/app"
|
|
92
|
-
|
|
93
|
-
CMD ["python", "-m", "my_api.main"]
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
**Why this works:**
|
|
97
|
-
- Dependencies change less frequently than code
|
|
98
|
-
- Docker caches layers from top to bottom
|
|
99
|
-
- Copying `pyproject.toml` before source code means dependency install is cached
|
|
100
|
-
|
|
101
|
-
## Build from Monorepo Root
|
|
102
|
-
|
|
103
|
-
Build all apps from root with build context:
|
|
104
|
-
|
|
105
|
-
**Root docker-compose.yml:**
|
|
106
|
-
|
|
107
|
-
```yaml
|
|
108
|
-
version: '3.8'
|
|
109
|
-
|
|
110
|
-
services:
|
|
111
|
-
api:
|
|
112
|
-
build:
|
|
113
|
-
context: .
|
|
114
|
-
dockerfile: apps/api/Dockerfile
|
|
115
|
-
ports:
|
|
116
|
-
- "8000:8000"
|
|
117
|
-
environment:
|
|
118
|
-
- DATABASE_URL=postgresql://postgres:postgres@db:5432/mydb
|
|
119
|
-
|
|
120
|
-
worker:
|
|
121
|
-
build:
|
|
122
|
-
context: .
|
|
123
|
-
dockerfile: apps/worker/Dockerfile
|
|
124
|
-
environment:
|
|
125
|
-
- REDIS_URL=redis://redis:6379
|
|
126
|
-
|
|
127
|
-
db:
|
|
128
|
-
image: postgres:15
|
|
129
|
-
environment:
|
|
130
|
-
- POSTGRES_PASSWORD=postgres
|
|
131
|
-
|
|
132
|
-
redis:
|
|
133
|
-
image: redis:7
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
**Key points:**
|
|
137
|
-
- `context: .` - Build from monorepo root
|
|
138
|
-
- `dockerfile: apps/api/Dockerfile` - Dockerfile location
|
|
139
|
-
- All apps can access packages/
|
|
140
|
-
|
|
141
|
-
## Development vs Production Builds
|
|
142
|
-
|
|
143
|
-
### Development Build
|
|
144
|
-
|
|
145
|
-
Include dev dependencies and enable hot reload:
|
|
146
|
-
|
|
147
|
-
```dockerfile
|
|
148
|
-
FROM python:3.12-slim
|
|
149
|
-
|
|
150
|
-
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
|
|
151
|
-
|
|
152
|
-
WORKDIR /app
|
|
153
|
-
|
|
154
|
-
COPY pyproject.toml uv.lock ./
|
|
155
|
-
COPY packages/ ./packages/
|
|
156
|
-
COPY apps/api/ ./apps/api/
|
|
157
|
-
|
|
158
|
-
# Install with dev dependencies
|
|
159
|
-
RUN uv sync --frozen --package my-api
|
|
160
|
-
|
|
161
|
-
ENV PATH="/app/.venv/bin:$PATH"
|
|
162
|
-
ENV PYTHONPATH="/app"
|
|
163
|
-
|
|
164
|
-
# Development server with reload
|
|
165
|
-
CMD ["uvicorn", "my_api.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
**docker-compose.dev.yml:**
|
|
169
|
-
|
|
170
|
-
```yaml
|
|
171
|
-
services:
|
|
172
|
-
api:
|
|
173
|
-
build:
|
|
174
|
-
context: .
|
|
175
|
-
dockerfile: apps/api/Dockerfile.dev
|
|
176
|
-
volumes:
|
|
177
|
-
- ./apps/api:/app/apps/api # Mount source for hot reload
|
|
178
|
-
- ./packages:/app/packages
|
|
179
|
-
ports:
|
|
180
|
-
- "8000:8000"
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### Production Build
|
|
184
|
-
|
|
185
|
-
Multi-stage, no dev dependencies, optimized:
|
|
186
|
-
|
|
187
|
-
```dockerfile
|
|
188
|
-
FROM python:3.12-slim AS builder
|
|
189
|
-
|
|
190
|
-
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
|
|
191
|
-
|
|
192
|
-
WORKDIR /app
|
|
193
|
-
|
|
194
|
-
COPY pyproject.toml uv.lock ./
|
|
195
|
-
COPY packages/ ./packages/
|
|
196
|
-
COPY apps/api/ ./apps/api/
|
|
197
|
-
|
|
198
|
-
# Production: no dev dependencies
|
|
199
|
-
RUN uv sync --frozen --no-dev --package my-api
|
|
200
|
-
|
|
201
|
-
FROM python:3.12-slim
|
|
202
|
-
|
|
203
|
-
WORKDIR /app
|
|
204
|
-
|
|
205
|
-
COPY --from=builder /app/.venv /app/.venv
|
|
206
|
-
COPY --from=builder /app/apps/api /app/apps/api
|
|
207
|
-
COPY --from=builder /app/packages /app/packages
|
|
208
|
-
|
|
209
|
-
ENV PATH="/app/.venv/bin:$PATH"
|
|
210
|
-
ENV PYTHONPATH="/app"
|
|
211
|
-
|
|
212
|
-
# Production server
|
|
213
|
-
CMD ["uvicorn", "my_api.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
## Building Specific Packages Only
|
|
217
|
-
|
|
218
|
-
If app only needs subset of workspace packages:
|
|
219
|
-
|
|
220
|
-
```dockerfile
|
|
221
|
-
FROM python:3.12-slim AS builder
|
|
222
|
-
|
|
223
|
-
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
|
|
224
|
-
|
|
225
|
-
WORKDIR /app
|
|
226
|
-
|
|
227
|
-
COPY pyproject.toml uv.lock ./
|
|
228
|
-
|
|
229
|
-
# Copy only required packages
|
|
230
|
-
COPY packages/core/ ./packages/core/
|
|
231
|
-
COPY packages/utils/ ./packages/utils/
|
|
232
|
-
# Don't copy packages/other (not needed)
|
|
233
|
-
|
|
234
|
-
COPY apps/api/ ./apps/api/
|
|
235
|
-
|
|
236
|
-
RUN uv sync --frozen --no-dev --package my-api
|
|
237
|
-
|
|
238
|
-
FROM python:3.12-slim
|
|
239
|
-
|
|
240
|
-
WORKDIR /app
|
|
241
|
-
|
|
242
|
-
COPY --from=builder /app/.venv /app/.venv
|
|
243
|
-
COPY --from=builder /app/apps/api /app/apps/api
|
|
244
|
-
COPY --from=builder /app/packages/core /app/packages/core
|
|
245
|
-
COPY --from=builder /app/packages/utils /app/packages/utils
|
|
246
|
-
|
|
247
|
-
ENV PATH="/app/.venv/bin:$PATH"
|
|
248
|
-
ENV PYTHONPATH="/app"
|
|
249
|
-
|
|
250
|
-
CMD ["python", "-m", "my_api.main"]
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
## .dockerignore
|
|
254
|
-
|
|
255
|
-
Create `.dockerignore` at root to exclude unnecessary files:
|
|
256
|
-
|
|
257
|
-
```
|
|
258
|
-
# Python
|
|
259
|
-
__pycache__/
|
|
260
|
-
*.py[cod]
|
|
261
|
-
*$py.class
|
|
262
|
-
*.so
|
|
263
|
-
.Python
|
|
264
|
-
.venv/
|
|
265
|
-
*.egg-info/
|
|
266
|
-
|
|
267
|
-
# IDEs
|
|
268
|
-
.vscode/
|
|
269
|
-
.idea/
|
|
270
|
-
*.swp
|
|
271
|
-
*.swo
|
|
272
|
-
|
|
273
|
-
# Testing
|
|
274
|
-
.pytest_cache/
|
|
275
|
-
.coverage
|
|
276
|
-
htmlcov/
|
|
277
|
-
|
|
278
|
-
# Build
|
|
279
|
-
dist/
|
|
280
|
-
build/
|
|
281
|
-
|
|
282
|
-
# Git
|
|
283
|
-
.git/
|
|
284
|
-
.gitignore
|
|
285
|
-
|
|
286
|
-
# Documentation
|
|
287
|
-
docs/
|
|
288
|
-
*.md
|
|
289
|
-
|
|
290
|
-
# CI/CD
|
|
291
|
-
.github/
|
|
292
|
-
.gitlab-ci.yml
|
|
293
|
-
|
|
294
|
-
# Environment
|
|
295
|
-
.env
|
|
296
|
-
.env.*
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
## Health Checks
|
|
300
|
-
|
|
301
|
-
Add health check to Dockerfile:
|
|
302
|
-
|
|
303
|
-
```dockerfile
|
|
304
|
-
FROM python:3.12-slim
|
|
305
|
-
|
|
306
|
-
# ... (previous steps)
|
|
307
|
-
|
|
308
|
-
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
|
309
|
-
CMD python -c "import requests; requests.get('http://localhost:8000/health')"
|
|
310
|
-
|
|
311
|
-
CMD ["uvicorn", "my_api.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
Or in docker-compose:
|
|
315
|
-
|
|
316
|
-
```yaml
|
|
317
|
-
services:
|
|
318
|
-
api:
|
|
319
|
-
healthcheck:
|
|
320
|
-
test: ["CMD", "python", "-c", "import requests; requests.get('http://localhost:8000/health')"]
|
|
321
|
-
interval: 30s
|
|
322
|
-
timeout: 10s
|
|
323
|
-
retries: 3
|
|
324
|
-
start_period: 5s
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
## Non-Root User
|
|
328
|
-
|
|
329
|
-
Run container as non-root for security:
|
|
330
|
-
|
|
331
|
-
```dockerfile
|
|
332
|
-
FROM python:3.12-slim
|
|
333
|
-
|
|
334
|
-
# ... (builder stage)
|
|
335
|
-
|
|
336
|
-
FROM python:3.12-slim
|
|
337
|
-
|
|
338
|
-
# Create non-root user
|
|
339
|
-
RUN useradd -m -u 1000 appuser
|
|
340
|
-
|
|
341
|
-
WORKDIR /app
|
|
342
|
-
|
|
343
|
-
COPY --from=builder --chown=appuser:appuser /app/.venv /app/.venv
|
|
344
|
-
COPY --from=builder --chown=appuser:appuser /app/apps/api /app/apps/api
|
|
345
|
-
COPY --from=builder --chown=appuser:appuser /app/packages /app/packages
|
|
346
|
-
|
|
347
|
-
# Switch to non-root user
|
|
348
|
-
USER appuser
|
|
349
|
-
|
|
350
|
-
ENV PATH="/app/.venv/bin:$PATH"
|
|
351
|
-
ENV PYTHONPATH="/app"
|
|
352
|
-
|
|
353
|
-
CMD ["uvicorn", "my_api.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
|
354
|
-
```
|
|
355
|
-
|
|
356
|
-
## Build Arguments
|
|
357
|
-
|
|
358
|
-
Parameterize builds with ARG:
|
|
359
|
-
|
|
360
|
-
```dockerfile
|
|
361
|
-
FROM python:3.12-slim AS builder
|
|
362
|
-
|
|
363
|
-
ARG APP_NAME=my-api
|
|
364
|
-
ARG APP_VERSION=0.1.0
|
|
365
|
-
|
|
366
|
-
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
|
|
367
|
-
|
|
368
|
-
WORKDIR /app
|
|
369
|
-
|
|
370
|
-
COPY pyproject.toml uv.lock ./
|
|
371
|
-
COPY packages/ ./packages/
|
|
372
|
-
COPY apps/${APP_NAME}/ ./apps/${APP_NAME}/
|
|
373
|
-
|
|
374
|
-
RUN uv sync --frozen --no-dev --package ${APP_NAME}
|
|
375
|
-
|
|
376
|
-
FROM python:3.12-slim
|
|
377
|
-
|
|
378
|
-
ARG APP_NAME=my-api
|
|
379
|
-
|
|
380
|
-
WORKDIR /app
|
|
381
|
-
|
|
382
|
-
COPY --from=builder /app/.venv /app/.venv
|
|
383
|
-
COPY --from=builder /app/apps/${APP_NAME} /app/apps/${APP_NAME}
|
|
384
|
-
COPY --from=builder /app/packages /app/packages
|
|
385
|
-
|
|
386
|
-
ENV PATH="/app/.venv/bin:$PATH"
|
|
387
|
-
ENV PYTHONPATH="/app"
|
|
388
|
-
|
|
389
|
-
CMD ["python", "-m", "${APP_NAME}.main"]
|
|
390
|
-
```
|
|
391
|
-
|
|
392
|
-
Build with:
|
|
393
|
-
|
|
394
|
-
```bash
|
|
395
|
-
docker build --build-arg APP_NAME=my-api -t my-api:latest -f apps/my-api/Dockerfile .
|
|
396
|
-
```
|
|
397
|
-
|
|
398
|
-
## Shared Dockerfile
|
|
399
|
-
|
|
400
|
-
Single Dockerfile for all apps:
|
|
401
|
-
|
|
402
|
-
**Dockerfile.workspace:**
|
|
403
|
-
|
|
404
|
-
```dockerfile
|
|
405
|
-
ARG PYTHON_VERSION=3.12
|
|
406
|
-
|
|
407
|
-
FROM python:${PYTHON_VERSION}-slim AS builder
|
|
408
|
-
|
|
409
|
-
ARG APP_NAME
|
|
410
|
-
ARG APP_PATH=apps/${APP_NAME}
|
|
411
|
-
|
|
412
|
-
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
|
|
413
|
-
|
|
414
|
-
WORKDIR /app
|
|
415
|
-
|
|
416
|
-
COPY pyproject.toml uv.lock ./
|
|
417
|
-
COPY packages/ ./packages/
|
|
418
|
-
COPY ${APP_PATH}/ ./${APP_PATH}/
|
|
419
|
-
|
|
420
|
-
RUN uv sync --frozen --no-dev --package ${APP_NAME}
|
|
421
|
-
|
|
422
|
-
FROM python:${PYTHON_VERSION}-slim
|
|
423
|
-
|
|
424
|
-
ARG APP_NAME
|
|
425
|
-
ARG APP_PATH=apps/${APP_NAME}
|
|
426
|
-
|
|
427
|
-
WORKDIR /app
|
|
428
|
-
|
|
429
|
-
COPY --from=builder /app/.venv /app/.venv
|
|
430
|
-
COPY --from=builder /app/${APP_PATH} /app/${APP_PATH}
|
|
431
|
-
COPY --from=builder /app/packages /app/packages
|
|
432
|
-
|
|
433
|
-
RUN useradd -m -u 1000 appuser && chown -R appuser:appuser /app
|
|
434
|
-
USER appuser
|
|
435
|
-
|
|
436
|
-
ENV PATH="/app/.venv/bin:$PATH"
|
|
437
|
-
ENV PYTHONPATH="/app"
|
|
438
|
-
|
|
439
|
-
CMD ["python", "-m", "${APP_NAME}.main"]
|
|
440
|
-
```
|
|
441
|
-
|
|
442
|
-
**docker-compose.yml:**
|
|
443
|
-
|
|
444
|
-
```yaml
|
|
445
|
-
services:
|
|
446
|
-
api:
|
|
447
|
-
build:
|
|
448
|
-
context: .
|
|
449
|
-
dockerfile: Dockerfile.workspace
|
|
450
|
-
args:
|
|
451
|
-
APP_NAME: my-api
|
|
452
|
-
ports:
|
|
453
|
-
- "8000:8000"
|
|
454
|
-
|
|
455
|
-
worker:
|
|
456
|
-
build:
|
|
457
|
-
context: .
|
|
458
|
-
dockerfile: Dockerfile.workspace
|
|
459
|
-
args:
|
|
460
|
-
APP_NAME: my-worker
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
## CI/CD Build Example
|
|
464
|
-
|
|
465
|
-
**GitHub Actions:**
|
|
466
|
-
|
|
467
|
-
```yaml
|
|
468
|
-
name: Build and Push
|
|
469
|
-
|
|
470
|
-
on:
|
|
471
|
-
push:
|
|
472
|
-
branches: [main]
|
|
473
|
-
|
|
474
|
-
jobs:
|
|
475
|
-
build:
|
|
476
|
-
runs-on: ubuntu-latest
|
|
477
|
-
strategy:
|
|
478
|
-
matrix:
|
|
479
|
-
app: [api, worker]
|
|
480
|
-
|
|
481
|
-
steps:
|
|
482
|
-
- uses: actions/checkout@v4
|
|
483
|
-
|
|
484
|
-
- name: Build image
|
|
485
|
-
run: |
|
|
486
|
-
docker build \
|
|
487
|
-
--build-arg APP_NAME=my-${{ matrix.app }} \
|
|
488
|
-
-t myregistry/my-${{ matrix.app }}:${{ github.sha }} \
|
|
489
|
-
-t myregistry/my-${{ matrix.app }}:latest \
|
|
490
|
-
-f apps/my-${{ matrix.app }}/Dockerfile \
|
|
491
|
-
.
|
|
492
|
-
|
|
493
|
-
- name: Push image
|
|
494
|
-
run: |
|
|
495
|
-
docker push myregistry/my-${{ matrix.app }}:${{ github.sha }}
|
|
496
|
-
docker push myregistry/my-${{ matrix.app }}:latest
|
|
497
|
-
```
|
|
498
|
-
|
|
499
|
-
## Summary
|
|
500
|
-
|
|
501
|
-
**Best practices:**
|
|
502
|
-
- Multi-stage builds for smaller images
|
|
503
|
-
- Layer caching (copy lock files before source)
|
|
504
|
-
- Build from monorepo root
|
|
505
|
-
- Use .dockerignore
|
|
506
|
-
- Run as non-root user
|
|
507
|
-
- Add health checks
|
|
508
|
-
- Separate dev and prod Dockerfiles
|
|
509
|
-
- Use build args for flexibility
|
|
510
|
-
|
|
511
|
-
**Key patterns:**
|
|
512
|
-
- Copy workspace packages for dependencies
|
|
513
|
-
- Use `uv sync --frozen --no-dev --package <name>`
|
|
514
|
-
- Set PYTHONPATH for workspace imports
|
|
515
|
-
- Include .venv in PATH
|