oh-my-customcode 0.1.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/LICENSE +21 -0
- package/README.md +287 -0
- package/dist/cli/index.js +13299 -0
- package/dist/index.js +927 -0
- package/package.json +74 -0
- package/templates/.claude/contexts/dev.md +20 -0
- package/templates/.claude/contexts/ecomode.md +63 -0
- package/templates/.claude/contexts/index.yaml +41 -0
- package/templates/.claude/contexts/research.md +28 -0
- package/templates/.claude/contexts/review.md +23 -0
- package/templates/.claude/hooks/hooks.json +185 -0
- package/templates/.claude/hooks/hud/index.yaml +27 -0
- package/templates/.claude/hooks/hud/update-status.sh +32 -0
- package/templates/.claude/hooks/index.yaml +46 -0
- package/templates/.claude/hooks/memory-persistence/pre-compact.sh +37 -0
- package/templates/.claude/hooks/memory-persistence/session-end.sh +64 -0
- package/templates/.claude/hooks/memory-persistence/session-start.sh +41 -0
- package/templates/.claude/hooks/strategic-compact/suggest-compact.sh +50 -0
- package/templates/.claude/install-hooks.sh +100 -0
- package/templates/.claude/rules/MAY-optimization.md +93 -0
- package/templates/.claude/rules/MUST-agent-design.md +107 -0
- package/templates/.claude/rules/MUST-agent-identification.md +108 -0
- package/templates/.claude/rules/MUST-continuous-improvement.md +132 -0
- package/templates/.claude/rules/MUST-intent-transparency.md +199 -0
- package/templates/.claude/rules/MUST-language-policy.md +62 -0
- package/templates/.claude/rules/MUST-orchestrator-coordination.md +266 -0
- package/templates/.claude/rules/MUST-parallel-execution.md +341 -0
- package/templates/.claude/rules/MUST-permissions.md +84 -0
- package/templates/.claude/rules/MUST-safety.md +69 -0
- package/templates/.claude/rules/MUST-sync-verification.md +219 -0
- package/templates/.claude/rules/MUST-tool-identification.md +112 -0
- package/templates/.claude/rules/SHOULD-ecomode.md +145 -0
- package/templates/.claude/rules/SHOULD-error-handling.md +102 -0
- package/templates/.claude/rules/SHOULD-hud-statusline.md +89 -0
- package/templates/.claude/rules/SHOULD-interaction.md +103 -0
- package/templates/.claude/rules/SHOULD-memory-integration.md +114 -0
- package/templates/.claude/rules/SHOULD-pipeline-mode.md +165 -0
- package/templates/.claude/rules/index.yaml +125 -0
- package/templates/.claude/uninstall-hooks.sh +52 -0
- package/templates/CLAUDE.md.en +259 -0
- package/templates/CLAUDE.md.ko +259 -0
- package/templates/agents/index.yaml +237 -0
- package/templates/agents/infra-engineer/aws-expert/AGENT.md +47 -0
- package/templates/agents/infra-engineer/aws-expert/index.yaml +27 -0
- package/templates/agents/infra-engineer/docker-expert/AGENT.md +47 -0
- package/templates/agents/infra-engineer/docker-expert/index.yaml +27 -0
- package/templates/agents/manager/creator/AGENT.md +274 -0
- package/templates/agents/manager/creator/index.yaml +66 -0
- package/templates/agents/manager/gitnerd/AGENT.md +91 -0
- package/templates/agents/manager/gitnerd/index.yaml +55 -0
- package/templates/agents/manager/sauron/AGENT.md +153 -0
- package/templates/agents/manager/sauron/index.yaml +52 -0
- package/templates/agents/manager/supplier/AGENT.md +142 -0
- package/templates/agents/manager/supplier/index.yaml +31 -0
- package/templates/agents/manager/sync-checker/AGENT.md +34 -0
- package/templates/agents/manager/sync-checker/index.yaml +32 -0
- package/templates/agents/manager/updater/AGENT.md +125 -0
- package/templates/agents/manager/updater/index.yaml +31 -0
- package/templates/agents/orchestrator/dev-lead/AGENT.md +116 -0
- package/templates/agents/orchestrator/dev-lead/index.yaml +73 -0
- package/templates/agents/orchestrator/planner/AGENT.md +102 -0
- package/templates/agents/orchestrator/planner/index.yaml +38 -0
- package/templates/agents/orchestrator/qa-lead/AGENT.md +92 -0
- package/templates/agents/orchestrator/qa-lead/index.yaml +40 -0
- package/templates/agents/orchestrator/secretary/AGENT.md +132 -0
- package/templates/agents/orchestrator/secretary/index.yaml +55 -0
- package/templates/agents/qa-team/qa-engineer/AGENT.md +98 -0
- package/templates/agents/qa-team/qa-engineer/index.yaml +59 -0
- package/templates/agents/qa-team/qa-planner/AGENT.md +75 -0
- package/templates/agents/qa-team/qa-planner/index.yaml +47 -0
- package/templates/agents/qa-team/qa-writer/AGENT.md +98 -0
- package/templates/agents/qa-team/qa-writer/index.yaml +44 -0
- package/templates/agents/sw-architect/documenter/AGENT.md +120 -0
- package/templates/agents/sw-architect/documenter/index.yaml +39 -0
- package/templates/agents/sw-architect/speckit-agent/AGENT.md +127 -0
- package/templates/agents/sw-architect/speckit-agent/index.yaml +78 -0
- package/templates/agents/sw-engineer/backend/express-expert/AGENT.md +132 -0
- package/templates/agents/sw-engineer/backend/express-expert/index.yaml +36 -0
- package/templates/agents/sw-engineer/backend/fastapi-expert/AGENT.md +47 -0
- package/templates/agents/sw-engineer/backend/fastapi-expert/index.yaml +27 -0
- package/templates/agents/sw-engineer/backend/go-backend-expert/AGENT.md +47 -0
- package/templates/agents/sw-engineer/backend/go-backend-expert/index.yaml +27 -0
- package/templates/agents/sw-engineer/backend/nestjs-expert/AGENT.md +107 -0
- package/templates/agents/sw-engineer/backend/nestjs-expert/index.yaml +43 -0
- package/templates/agents/sw-engineer/backend/springboot-expert/AGENT.md +103 -0
- package/templates/agents/sw-engineer/backend/springboot-expert/index.yaml +69 -0
- package/templates/agents/sw-engineer/frontend/svelte-agent/AGENT.md +71 -0
- package/templates/agents/sw-engineer/frontend/svelte-agent/index.yaml +41 -0
- package/templates/agents/sw-engineer/frontend/vercel-agent/AGENT.md +67 -0
- package/templates/agents/sw-engineer/frontend/vercel-agent/index.yaml +43 -0
- package/templates/agents/sw-engineer/frontend/vuejs-agent/AGENT.md +71 -0
- package/templates/agents/sw-engineer/frontend/vuejs-agent/index.yaml +48 -0
- package/templates/agents/sw-engineer/language/golang-expert/AGENT.md +47 -0
- package/templates/agents/sw-engineer/language/golang-expert/index.yaml +27 -0
- package/templates/agents/sw-engineer/language/java21-expert/AGENT.md +122 -0
- package/templates/agents/sw-engineer/language/java21-expert/index.yaml +51 -0
- package/templates/agents/sw-engineer/language/kotlin-expert/AGENT.md +47 -0
- package/templates/agents/sw-engineer/language/kotlin-expert/index.yaml +27 -0
- package/templates/agents/sw-engineer/language/python-expert/AGENT.md +47 -0
- package/templates/agents/sw-engineer/language/python-expert/index.yaml +27 -0
- package/templates/agents/sw-engineer/language/rust-expert/AGENT.md +47 -0
- package/templates/agents/sw-engineer/language/rust-expert/index.yaml +27 -0
- package/templates/agents/sw-engineer/language/typescript-expert/AGENT.md +47 -0
- package/templates/agents/sw-engineer/language/typescript-expert/index.yaml +27 -0
- package/templates/agents/sw-engineer/tooling/bun-expert/AGENT.md +73 -0
- package/templates/agents/sw-engineer/tooling/bun-expert/index.yaml +46 -0
- package/templates/agents/sw-engineer/tooling/npm-expert/AGENT.md +160 -0
- package/templates/agents/sw-engineer/tooling/npm-expert/index.yaml +45 -0
- package/templates/agents/sw-engineer/tooling/optimizer/AGENT.md +170 -0
- package/templates/agents/sw-engineer/tooling/optimizer/index.yaml +45 -0
- package/templates/agents/system/memory-keeper/AGENT.md +126 -0
- package/templates/agents/system/memory-keeper/index.yaml +45 -0
- package/templates/agents/system/naggy/AGENT.md +72 -0
- package/templates/agents/system/naggy/index.yaml +35 -0
- package/templates/commands/COMMANDS.md +136 -0
- package/templates/commands/creator/agent.md +121 -0
- package/templates/commands/dev/refactor.md +126 -0
- package/templates/commands/dev/review.md +82 -0
- package/templates/commands/git/branch.yaml +8 -0
- package/templates/commands/git/commit.yaml +4 -0
- package/templates/commands/git/pr.yaml +4 -0
- package/templates/commands/git/status.yaml +4 -0
- package/templates/commands/git/sync.yaml +4 -0
- package/templates/commands/index.yaml +225 -0
- package/templates/commands/intent/explain.md +144 -0
- package/templates/commands/memory/recall.md +164 -0
- package/templates/commands/memory/save.md +128 -0
- package/templates/commands/naggy/add.yaml +8 -0
- package/templates/commands/naggy/done.yaml +8 -0
- package/templates/commands/naggy/list.yaml +4 -0
- package/templates/commands/naggy/priority.yaml +11 -0
- package/templates/commands/naggy/remind.yaml +4 -0
- package/templates/commands/npm/audit.yaml +62 -0
- package/templates/commands/npm/publish.yaml +52 -0
- package/templates/commands/npm/version.yaml +62 -0
- package/templates/commands/optimize/analyze.yaml +34 -0
- package/templates/commands/optimize/bundle.yaml +50 -0
- package/templates/commands/optimize/report.yaml +56 -0
- package/templates/commands/pipeline/list.md +81 -0
- package/templates/commands/pipeline/run.md +127 -0
- package/templates/commands/sauron/quick.yaml +4 -0
- package/templates/commands/sauron/report.yaml +4 -0
- package/templates/commands/sauron/watch.yaml +4 -0
- package/templates/commands/supplier/audit.md +133 -0
- package/templates/commands/supplier/fix.md +121 -0
- package/templates/commands/sync/agents.yaml +4 -0
- package/templates/commands/sync/check.yaml +4 -0
- package/templates/commands/sync/commands.yaml +4 -0
- package/templates/commands/sync/docs.yaml +4 -0
- package/templates/commands/sync/fix.yaml +4 -0
- package/templates/commands/system/help.md +137 -0
- package/templates/commands/system/lists.md +86 -0
- package/templates/commands/system/status.md +163 -0
- package/templates/commands/updater/docs.md +165 -0
- package/templates/commands/updater/external.md +214 -0
- package/templates/guides/aws/common-patterns.md +169 -0
- package/templates/guides/aws/index.yaml +26 -0
- package/templates/guides/aws/well-architected.md +143 -0
- package/templates/guides/claude-code/01-overview.md +42 -0
- package/templates/guides/claude-code/03-tools.md +107 -0
- package/templates/guides/claude-code/04-agent-skills.md +90 -0
- package/templates/guides/claude-code/05-agent-sdk.md +129 -0
- package/templates/guides/claude-code/06-mcp.md +165 -0
- package/templates/guides/claude-code/07-prompt-engineering.md +100 -0
- package/templates/guides/claude-code/08-testing.md +58 -0
- package/templates/guides/claude-code/09-guardrails.md +80 -0
- package/templates/guides/claude-code/10-monitoring.md +89 -0
- package/templates/guides/claude-code/index.yaml +51 -0
- package/templates/guides/docker/compose-best-practices.md +284 -0
- package/templates/guides/docker/dockerfile-best-practices.md +262 -0
- package/templates/guides/docker/index.yaml +26 -0
- package/templates/guides/fastapi/best-practices.md +232 -0
- package/templates/guides/fastapi/index.yaml +21 -0
- package/templates/guides/go-backend/index.yaml +26 -0
- package/templates/guides/go-backend/project-layout.md +243 -0
- package/templates/guides/go-backend/uber-style.md +212 -0
- package/templates/guides/golang/concurrency.md +282 -0
- package/templates/guides/golang/effective-go.md +309 -0
- package/templates/guides/golang/error-handling.md +250 -0
- package/templates/guides/golang/index.yaml +27 -0
- package/templates/guides/index.yaml +101 -0
- package/templates/guides/kotlin/coding-conventions.md +247 -0
- package/templates/guides/kotlin/idioms.md +234 -0
- package/templates/guides/kotlin/index.yaml +26 -0
- package/templates/guides/python/index.yaml +26 -0
- package/templates/guides/python/pep8-style-guide.md +202 -0
- package/templates/guides/python/zen-of-python.md +79 -0
- package/templates/guides/rust/error-handling.md +262 -0
- package/templates/guides/rust/index.yaml +26 -0
- package/templates/guides/rust/ownership.md +180 -0
- package/templates/guides/springboot/best-practices.md +361 -0
- package/templates/guides/springboot/index.yaml +22 -0
- package/templates/guides/typescript/advanced-types.md +225 -0
- package/templates/guides/typescript/index.yaml +26 -0
- package/templates/guides/typescript/type-system.md +219 -0
- package/templates/guides/web-design/accessibility.md +66 -0
- package/templates/guides/web-design/index.yaml +20 -0
- package/templates/guides/web-design/performance.md +102 -0
- package/templates/pipelines/examples/code-review.yaml +66 -0
- package/templates/pipelines/index.yaml +18 -0
- package/templates/pipelines/templates/pipeline-template.yaml +50 -0
- package/templates/skills/backend/fastapi-best-practices/SKILL.md +269 -0
- package/templates/skills/backend/fastapi-best-practices/index.yaml +25 -0
- package/templates/skills/backend/go-backend-best-practices/SKILL.md +337 -0
- package/templates/skills/backend/go-backend-best-practices/index.yaml +26 -0
- package/templates/skills/backend/springboot-best-practices/SKILL.md +356 -0
- package/templates/skills/backend/springboot-best-practices/index.yaml +27 -0
- package/templates/skills/development/go-best-practices/SKILL.md +202 -0
- package/templates/skills/development/go-best-practices/index.yaml +25 -0
- package/templates/skills/development/kotlin-best-practices/SKILL.md +255 -0
- package/templates/skills/development/kotlin-best-practices/index.yaml +27 -0
- package/templates/skills/development/python-best-practices/SKILL.md +221 -0
- package/templates/skills/development/python-best-practices/index.yaml +25 -0
- package/templates/skills/development/react-best-practices/SKILL.md +100 -0
- package/templates/skills/development/react-best-practices/index.yaml +39 -0
- package/templates/skills/development/rust-best-practices/SKILL.md +266 -0
- package/templates/skills/development/rust-best-practices/index.yaml +26 -0
- package/templates/skills/development/typescript-best-practices/SKILL.md +320 -0
- package/templates/skills/development/typescript-best-practices/index.yaml +28 -0
- package/templates/skills/development/vercel-deploy/SKILL.md +73 -0
- package/templates/skills/development/vercel-deploy/index.yaml +30 -0
- package/templates/skills/development/web-design-guidelines/SKILL.md +117 -0
- package/templates/skills/development/web-design-guidelines/index.yaml +34 -0
- package/templates/skills/index.yaml +129 -0
- package/templates/skills/infrastructure/aws-best-practices/SKILL.md +279 -0
- package/templates/skills/infrastructure/aws-best-practices/index.yaml +27 -0
- package/templates/skills/infrastructure/docker-best-practices/SKILL.md +274 -0
- package/templates/skills/infrastructure/docker-best-practices/index.yaml +26 -0
- package/templates/skills/orchestration/intent-detection/SKILL.md +214 -0
- package/templates/skills/orchestration/intent-detection/index.yaml +30 -0
- package/templates/skills/orchestration/intent-detection/patterns/agent-triggers.yaml +333 -0
- package/templates/skills/orchestration/pipeline-execution/SKILL.md +188 -0
- package/templates/skills/orchestration/pipeline-execution/index.yaml +27 -0
- package/templates/skills/system/memory-management/SKILL.md +194 -0
- package/templates/skills/system/memory-management/index.yaml +30 -0
- package/templates/skills/system/result-aggregation/SKILL.md +163 -0
- package/templates/skills/system/result-aggregation/index.yaml +36 -0
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
# Dockerfile Best Practices
|
|
2
|
+
|
|
3
|
+
> Source: https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
|
|
4
|
+
|
|
5
|
+
## General Guidelines
|
|
6
|
+
|
|
7
|
+
### Create Ephemeral Containers
|
|
8
|
+
|
|
9
|
+
Containers should be ephemeral - can be stopped, destroyed, and rebuilt with minimal setup.
|
|
10
|
+
|
|
11
|
+
### Understand Build Context
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Entire directory sent to daemon
|
|
15
|
+
docker build .
|
|
16
|
+
|
|
17
|
+
# Use .dockerignore to exclude files
|
|
18
|
+
# .dockerignore
|
|
19
|
+
.git
|
|
20
|
+
node_modules
|
|
21
|
+
*.md
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Use Multi-Stage Builds
|
|
25
|
+
|
|
26
|
+
```dockerfile
|
|
27
|
+
# Build stage
|
|
28
|
+
FROM golang:1.21 AS builder
|
|
29
|
+
WORKDIR /app
|
|
30
|
+
COPY . .
|
|
31
|
+
RUN go build -o myapp
|
|
32
|
+
|
|
33
|
+
# Runtime stage
|
|
34
|
+
FROM alpine:3.19
|
|
35
|
+
COPY --from=builder /app/myapp /usr/local/bin/
|
|
36
|
+
CMD ["myapp"]
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Dockerfile Instructions
|
|
40
|
+
|
|
41
|
+
### FROM
|
|
42
|
+
|
|
43
|
+
```dockerfile
|
|
44
|
+
# Pin versions
|
|
45
|
+
FROM ubuntu:22.04
|
|
46
|
+
|
|
47
|
+
# Use digest for reproducibility
|
|
48
|
+
FROM node:20@sha256:abc123...
|
|
49
|
+
|
|
50
|
+
# Use official images
|
|
51
|
+
FROM python:3.12-slim
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### RUN
|
|
55
|
+
|
|
56
|
+
```dockerfile
|
|
57
|
+
# Combine commands
|
|
58
|
+
RUN apt-get update && apt-get install -y \
|
|
59
|
+
curl \
|
|
60
|
+
git \
|
|
61
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
62
|
+
|
|
63
|
+
# Use BuildKit cache
|
|
64
|
+
RUN --mount=type=cache,target=/root/.cache/pip \
|
|
65
|
+
pip install -r requirements.txt
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### CMD vs ENTRYPOINT
|
|
69
|
+
|
|
70
|
+
```dockerfile
|
|
71
|
+
# CMD: Default command (can be overridden)
|
|
72
|
+
CMD ["python", "app.py"]
|
|
73
|
+
|
|
74
|
+
# ENTRYPOINT: Fixed command
|
|
75
|
+
ENTRYPOINT ["python"]
|
|
76
|
+
CMD ["app.py"]
|
|
77
|
+
|
|
78
|
+
# Combined
|
|
79
|
+
ENTRYPOINT ["/docker-entrypoint.sh"]
|
|
80
|
+
CMD ["postgres"]
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### COPY vs ADD
|
|
84
|
+
|
|
85
|
+
```dockerfile
|
|
86
|
+
# Prefer COPY (more explicit)
|
|
87
|
+
COPY requirements.txt .
|
|
88
|
+
|
|
89
|
+
# ADD only for tar extraction or URLs
|
|
90
|
+
ADD archive.tar.gz /app/
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### EXPOSE
|
|
94
|
+
|
|
95
|
+
```dockerfile
|
|
96
|
+
# Documentation only
|
|
97
|
+
EXPOSE 8080
|
|
98
|
+
EXPOSE 443/tcp
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### ENV
|
|
102
|
+
|
|
103
|
+
```dockerfile
|
|
104
|
+
ENV APP_HOME=/app \
|
|
105
|
+
PATH=$APP_HOME/bin:$PATH
|
|
106
|
+
|
|
107
|
+
WORKDIR $APP_HOME
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### VOLUME
|
|
111
|
+
|
|
112
|
+
```dockerfile
|
|
113
|
+
# Named mount point
|
|
114
|
+
VOLUME /data
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### USER
|
|
118
|
+
|
|
119
|
+
```dockerfile
|
|
120
|
+
# Create non-root user
|
|
121
|
+
RUN groupadd -r app && useradd -r -g app app
|
|
122
|
+
USER app
|
|
123
|
+
|
|
124
|
+
# Or use existing
|
|
125
|
+
USER nobody
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### WORKDIR
|
|
129
|
+
|
|
130
|
+
```dockerfile
|
|
131
|
+
# Always use absolute paths
|
|
132
|
+
WORKDIR /app
|
|
133
|
+
WORKDIR /app/src
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### HEALTHCHECK
|
|
137
|
+
|
|
138
|
+
```dockerfile
|
|
139
|
+
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
|
140
|
+
CMD curl -f http://localhost/ || exit 1
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Layer Optimization
|
|
144
|
+
|
|
145
|
+
### Order Matters
|
|
146
|
+
|
|
147
|
+
```dockerfile
|
|
148
|
+
# 1. Install dependencies (changes rarely)
|
|
149
|
+
COPY package.json package-lock.json ./
|
|
150
|
+
RUN npm ci
|
|
151
|
+
|
|
152
|
+
# 2. Copy source (changes often)
|
|
153
|
+
COPY . .
|
|
154
|
+
|
|
155
|
+
# 3. Build
|
|
156
|
+
RUN npm run build
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Combine RUN Commands
|
|
160
|
+
|
|
161
|
+
```dockerfile
|
|
162
|
+
# Good: Single layer
|
|
163
|
+
RUN apt-get update && \
|
|
164
|
+
apt-get install -y python3 && \
|
|
165
|
+
rm -rf /var/lib/apt/lists/*
|
|
166
|
+
|
|
167
|
+
# Bad: Multiple layers
|
|
168
|
+
RUN apt-get update
|
|
169
|
+
RUN apt-get install -y python3
|
|
170
|
+
RUN rm -rf /var/lib/apt/lists/*
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Security Best Practices
|
|
174
|
+
|
|
175
|
+
### Don't Run as Root
|
|
176
|
+
|
|
177
|
+
```dockerfile
|
|
178
|
+
FROM node:20
|
|
179
|
+
|
|
180
|
+
RUN groupadd -r nodejs && useradd -r -g nodejs nodejs
|
|
181
|
+
USER nodejs
|
|
182
|
+
|
|
183
|
+
COPY --chown=nodejs:nodejs . .
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Don't Store Secrets
|
|
187
|
+
|
|
188
|
+
```dockerfile
|
|
189
|
+
# Bad: Secret in image
|
|
190
|
+
ENV API_KEY=secret123
|
|
191
|
+
|
|
192
|
+
# Good: Pass at runtime
|
|
193
|
+
# docker run -e API_KEY=secret123 myapp
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Use Official Images
|
|
197
|
+
|
|
198
|
+
```dockerfile
|
|
199
|
+
# Official and verified
|
|
200
|
+
FROM nginx:1.25
|
|
201
|
+
FROM postgres:16
|
|
202
|
+
|
|
203
|
+
# Minimal images
|
|
204
|
+
FROM gcr.io/distroless/static
|
|
205
|
+
FROM alpine:3.19
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Example Dockerfiles
|
|
209
|
+
|
|
210
|
+
### Node.js
|
|
211
|
+
|
|
212
|
+
```dockerfile
|
|
213
|
+
FROM node:20-slim AS builder
|
|
214
|
+
WORKDIR /app
|
|
215
|
+
COPY package*.json ./
|
|
216
|
+
RUN npm ci
|
|
217
|
+
COPY . .
|
|
218
|
+
RUN npm run build
|
|
219
|
+
|
|
220
|
+
FROM node:20-slim
|
|
221
|
+
WORKDIR /app
|
|
222
|
+
COPY --from=builder /app/dist ./dist
|
|
223
|
+
COPY --from=builder /app/node_modules ./node_modules
|
|
224
|
+
USER node
|
|
225
|
+
EXPOSE 3000
|
|
226
|
+
CMD ["node", "dist/server.js"]
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Python
|
|
230
|
+
|
|
231
|
+
```dockerfile
|
|
232
|
+
FROM python:3.12-slim AS builder
|
|
233
|
+
WORKDIR /app
|
|
234
|
+
RUN pip install --user pipenv
|
|
235
|
+
COPY Pipfile Pipfile.lock ./
|
|
236
|
+
RUN pipenv install --system --deploy
|
|
237
|
+
|
|
238
|
+
FROM python:3.12-slim
|
|
239
|
+
WORKDIR /app
|
|
240
|
+
COPY --from=builder /root/.local /root/.local
|
|
241
|
+
COPY . .
|
|
242
|
+
ENV PATH=/root/.local/bin:$PATH
|
|
243
|
+
USER nobody
|
|
244
|
+
EXPOSE 8000
|
|
245
|
+
CMD ["gunicorn", "-b", "0.0.0.0:8000", "app:app"]
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Go
|
|
249
|
+
|
|
250
|
+
```dockerfile
|
|
251
|
+
FROM golang:1.21-alpine AS builder
|
|
252
|
+
WORKDIR /app
|
|
253
|
+
COPY go.mod go.sum ./
|
|
254
|
+
RUN go mod download
|
|
255
|
+
COPY . .
|
|
256
|
+
RUN CGO_ENABLED=0 GOOS=linux go build -o /app/server
|
|
257
|
+
|
|
258
|
+
FROM scratch
|
|
259
|
+
COPY --from=builder /app/server /server
|
|
260
|
+
EXPOSE 8080
|
|
261
|
+
ENTRYPOINT ["/server"]
|
|
262
|
+
```
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Docker Guide
|
|
2
|
+
|
|
3
|
+
metadata:
|
|
4
|
+
name: docker
|
|
5
|
+
description: Docker containerization reference documentation
|
|
6
|
+
|
|
7
|
+
source:
|
|
8
|
+
type: external
|
|
9
|
+
origin: docker.com
|
|
10
|
+
urls:
|
|
11
|
+
- https://docs.docker.com/
|
|
12
|
+
- https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
|
|
13
|
+
- https://docs.docker.com/compose/compose-file/best-practices/
|
|
14
|
+
last_fetched: "2026-01-22"
|
|
15
|
+
|
|
16
|
+
documents:
|
|
17
|
+
- name: dockerfile-best-practices
|
|
18
|
+
path: ./dockerfile-best-practices.md
|
|
19
|
+
description: Dockerfile best practices
|
|
20
|
+
|
|
21
|
+
- name: compose-best-practices
|
|
22
|
+
path: ./compose-best-practices.md
|
|
23
|
+
description: Docker Compose best practices
|
|
24
|
+
|
|
25
|
+
used_by:
|
|
26
|
+
- docker-expert
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# FastAPI Best Practices
|
|
2
|
+
|
|
3
|
+
> Source: https://fastapi.tiangolo.com/ and community patterns
|
|
4
|
+
|
|
5
|
+
## Project Structure
|
|
6
|
+
|
|
7
|
+
Organize by domain, not by file type:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
src/
|
|
11
|
+
├── auth/
|
|
12
|
+
│ ├── router.py # API endpoints
|
|
13
|
+
│ ├── schemas.py # Pydantic models
|
|
14
|
+
│ ├── models.py # Database models
|
|
15
|
+
│ ├── service.py # Business logic
|
|
16
|
+
│ ├── dependencies.py # Route validators
|
|
17
|
+
│ └── exceptions.py # Custom exceptions
|
|
18
|
+
├── users/
|
|
19
|
+
│ └── ...
|
|
20
|
+
├── config.py
|
|
21
|
+
└── main.py
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Async Best Practices
|
|
25
|
+
|
|
26
|
+
### I/O-Intensive Tasks
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
# Use async def with await for non-blocking I/O
|
|
30
|
+
async def fetch_user(user_id: int) -> User:
|
|
31
|
+
async with httpx.AsyncClient() as client:
|
|
32
|
+
response = await client.get(f"/api/users/{user_id}")
|
|
33
|
+
return User(**response.json())
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Sync I/O Operations
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
# Use regular def - FastAPI offloads to threadpool
|
|
40
|
+
def read_config() -> dict:
|
|
41
|
+
with open("config.yaml") as f:
|
|
42
|
+
return yaml.safe_load(f)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### CPU-Intensive Tasks
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
# Use separate worker processes
|
|
49
|
+
from celery import Celery
|
|
50
|
+
|
|
51
|
+
celery_app = Celery("tasks", broker="redis://localhost")
|
|
52
|
+
|
|
53
|
+
@celery_app.task
|
|
54
|
+
def process_data(data: dict) -> dict:
|
|
55
|
+
# Heavy computation
|
|
56
|
+
return result
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Never Do This
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
# WRONG: Blocks event loop
|
|
63
|
+
async def bad_example():
|
|
64
|
+
time.sleep(5) # Never use time.sleep in async!
|
|
65
|
+
|
|
66
|
+
# CORRECT: Use asyncio.sleep
|
|
67
|
+
async def good_example():
|
|
68
|
+
await asyncio.sleep(5)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Pydantic Models
|
|
72
|
+
|
|
73
|
+
### Custom Base Model
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from pydantic import BaseModel
|
|
77
|
+
from datetime import datetime
|
|
78
|
+
|
|
79
|
+
class AppBaseModel(BaseModel):
|
|
80
|
+
class Config:
|
|
81
|
+
from_attributes = True
|
|
82
|
+
json_encoders = {
|
|
83
|
+
datetime: lambda v: v.isoformat()
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
class UserResponse(AppBaseModel):
|
|
87
|
+
id: int
|
|
88
|
+
email: str
|
|
89
|
+
created_at: datetime
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Validation
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
from pydantic import BaseModel, EmailStr, Field, validator
|
|
96
|
+
|
|
97
|
+
class UserCreate(BaseModel):
|
|
98
|
+
email: EmailStr
|
|
99
|
+
password: str = Field(..., min_length=8)
|
|
100
|
+
age: int = Field(..., ge=18, le=120)
|
|
101
|
+
|
|
102
|
+
@validator("password")
|
|
103
|
+
def password_strength(cls, v):
|
|
104
|
+
if not any(c.isupper() for c in v):
|
|
105
|
+
raise ValueError("Password must contain uppercase")
|
|
106
|
+
return v
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Dependencies
|
|
110
|
+
|
|
111
|
+
### Authentication
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
from fastapi import Depends, HTTPException
|
|
115
|
+
from fastapi.security import OAuth2PasswordBearer
|
|
116
|
+
|
|
117
|
+
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
|
|
118
|
+
|
|
119
|
+
async def get_current_user(
|
|
120
|
+
token: str = Depends(oauth2_scheme),
|
|
121
|
+
db: AsyncSession = Depends(get_db)
|
|
122
|
+
) -> User:
|
|
123
|
+
user = await verify_token(token, db)
|
|
124
|
+
if not user:
|
|
125
|
+
raise HTTPException(status_code=401)
|
|
126
|
+
return user
|
|
127
|
+
|
|
128
|
+
async def get_active_user(
|
|
129
|
+
user: User = Depends(get_current_user)
|
|
130
|
+
) -> User:
|
|
131
|
+
if not user.is_active:
|
|
132
|
+
raise HTTPException(status_code=403)
|
|
133
|
+
return user
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Database Session
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
from sqlalchemy.ext.asyncio import AsyncSession
|
|
140
|
+
|
|
141
|
+
async def get_db() -> AsyncGenerator[AsyncSession, None]:
|
|
142
|
+
async with async_session() as session:
|
|
143
|
+
try:
|
|
144
|
+
yield session
|
|
145
|
+
await session.commit()
|
|
146
|
+
except Exception:
|
|
147
|
+
await session.rollback()
|
|
148
|
+
raise
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Error Handling
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
# Custom exceptions
|
|
155
|
+
class AuthException(Exception):
|
|
156
|
+
pass
|
|
157
|
+
|
|
158
|
+
class InvalidCredentials(AuthException):
|
|
159
|
+
pass
|
|
160
|
+
|
|
161
|
+
# Exception handler
|
|
162
|
+
@app.exception_handler(AuthException)
|
|
163
|
+
async def auth_exception_handler(request, exc):
|
|
164
|
+
return JSONResponse(
|
|
165
|
+
status_code=401,
|
|
166
|
+
content={"detail": str(exc)}
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
# In router
|
|
170
|
+
@router.post("/login")
|
|
171
|
+
async def login(credentials: LoginSchema):
|
|
172
|
+
try:
|
|
173
|
+
return await auth_service.login(credentials)
|
|
174
|
+
except InvalidCredentials:
|
|
175
|
+
raise HTTPException(status_code=401, detail="Invalid credentials")
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## API Design
|
|
179
|
+
|
|
180
|
+
```python
|
|
181
|
+
from fastapi import APIRouter
|
|
182
|
+
|
|
183
|
+
router = APIRouter(
|
|
184
|
+
prefix="/users",
|
|
185
|
+
tags=["users"]
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
@router.get(
|
|
189
|
+
"/{user_id}",
|
|
190
|
+
response_model=UserResponse,
|
|
191
|
+
summary="Get user by ID",
|
|
192
|
+
responses={
|
|
193
|
+
404: {"model": ErrorResponse, "description": "User not found"}
|
|
194
|
+
}
|
|
195
|
+
)
|
|
196
|
+
async def get_user(
|
|
197
|
+
user_id: int,
|
|
198
|
+
db: AsyncSession = Depends(get_db),
|
|
199
|
+
current_user: User = Depends(get_current_user)
|
|
200
|
+
) -> UserResponse:
|
|
201
|
+
"""
|
|
202
|
+
Get a specific user by their ID.
|
|
203
|
+
|
|
204
|
+
- **user_id**: The unique identifier of the user
|
|
205
|
+
"""
|
|
206
|
+
user = await user_service.get(db, user_id)
|
|
207
|
+
if not user:
|
|
208
|
+
raise HTTPException(status_code=404, detail="User not found")
|
|
209
|
+
return user
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Testing
|
|
213
|
+
|
|
214
|
+
```python
|
|
215
|
+
import pytest
|
|
216
|
+
from httpx import AsyncClient
|
|
217
|
+
from main import app
|
|
218
|
+
|
|
219
|
+
@pytest.fixture
|
|
220
|
+
async def client():
|
|
221
|
+
async with AsyncClient(app=app, base_url="http://test") as ac:
|
|
222
|
+
yield ac
|
|
223
|
+
|
|
224
|
+
@pytest.mark.asyncio
|
|
225
|
+
async def test_create_user(client: AsyncClient):
|
|
226
|
+
response = await client.post(
|
|
227
|
+
"/users/",
|
|
228
|
+
json={"email": "test@example.com", "password": "Password123"}
|
|
229
|
+
)
|
|
230
|
+
assert response.status_code == 201
|
|
231
|
+
assert response.json()["email"] == "test@example.com"
|
|
232
|
+
```
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# FastAPI Guide
|
|
2
|
+
|
|
3
|
+
metadata:
|
|
4
|
+
name: fastapi
|
|
5
|
+
description: FastAPI framework reference documentation
|
|
6
|
+
|
|
7
|
+
source:
|
|
8
|
+
type: external
|
|
9
|
+
origin: fastapi.tiangolo.com
|
|
10
|
+
urls:
|
|
11
|
+
- https://fastapi.tiangolo.com/
|
|
12
|
+
- https://github.com/zhanymkanov/fastapi-best-practices
|
|
13
|
+
last_fetched: "2026-01-22"
|
|
14
|
+
|
|
15
|
+
documents:
|
|
16
|
+
- name: best-practices
|
|
17
|
+
path: ./best-practices.md
|
|
18
|
+
description: FastAPI best practices and patterns
|
|
19
|
+
|
|
20
|
+
used_by:
|
|
21
|
+
- fastapi-expert
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Go Backend Guide
|
|
2
|
+
|
|
3
|
+
metadata:
|
|
4
|
+
name: go-backend
|
|
5
|
+
description: Go backend development reference documentation
|
|
6
|
+
|
|
7
|
+
source:
|
|
8
|
+
type: external
|
|
9
|
+
origin: various
|
|
10
|
+
urls:
|
|
11
|
+
- https://go.dev/doc/effective_go
|
|
12
|
+
- https://github.com/golang-standards/project-layout
|
|
13
|
+
- https://github.com/uber-go/guide/blob/master/style.md
|
|
14
|
+
last_fetched: "2026-01-22"
|
|
15
|
+
|
|
16
|
+
documents:
|
|
17
|
+
- name: uber-style
|
|
18
|
+
path: ./uber-style.md
|
|
19
|
+
description: Uber Go style guide
|
|
20
|
+
|
|
21
|
+
- name: project-layout
|
|
22
|
+
path: ./project-layout.md
|
|
23
|
+
description: Standard Go project layout
|
|
24
|
+
|
|
25
|
+
used_by:
|
|
26
|
+
- go-backend-expert
|