agent-notes 2.0.4__py3-none-any.whl
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.
- agent_notes/VERSION +1 -0
- agent_notes/__init__.py +1 -0
- agent_notes/__main__.py +4 -0
- agent_notes/cli.py +348 -0
- agent_notes/commands/__init__.py +27 -0
- agent_notes/commands/_install_helpers.py +262 -0
- agent_notes/commands/build.py +170 -0
- agent_notes/commands/doctor.py +112 -0
- agent_notes/commands/info.py +95 -0
- agent_notes/commands/install.py +99 -0
- agent_notes/commands/list.py +169 -0
- agent_notes/commands/memory.py +430 -0
- agent_notes/commands/regenerate.py +152 -0
- agent_notes/commands/set_role.py +143 -0
- agent_notes/commands/uninstall.py +26 -0
- agent_notes/commands/update.py +169 -0
- agent_notes/commands/validate.py +199 -0
- agent_notes/commands/wizard.py +720 -0
- agent_notes/config.py +154 -0
- agent_notes/data/agents/agents.yaml +352 -0
- agent_notes/data/agents/analyst.md +45 -0
- agent_notes/data/agents/api-reviewer.md +47 -0
- agent_notes/data/agents/architect.md +46 -0
- agent_notes/data/agents/coder.md +28 -0
- agent_notes/data/agents/database-specialist.md +45 -0
- agent_notes/data/agents/debugger.md +47 -0
- agent_notes/data/agents/devil.md +47 -0
- agent_notes/data/agents/devops.md +38 -0
- agent_notes/data/agents/explorer.md +23 -0
- agent_notes/data/agents/integrations.md +44 -0
- agent_notes/data/agents/lead.md +216 -0
- agent_notes/data/agents/performance-profiler.md +44 -0
- agent_notes/data/agents/refactorer.md +48 -0
- agent_notes/data/agents/reviewer.md +44 -0
- agent_notes/data/agents/security-auditor.md +44 -0
- agent_notes/data/agents/system-auditor.md +38 -0
- agent_notes/data/agents/tech-writer.md +32 -0
- agent_notes/data/agents/test-runner.md +36 -0
- agent_notes/data/agents/test-writer.md +39 -0
- agent_notes/data/cli/claude.yaml +25 -0
- agent_notes/data/cli/copilot.yaml +18 -0
- agent_notes/data/cli/opencode.yaml +22 -0
- agent_notes/data/commands/brainstorm.md +8 -0
- agent_notes/data/commands/debug.md +9 -0
- agent_notes/data/commands/review.md +10 -0
- agent_notes/data/global-claude.md +290 -0
- agent_notes/data/global-copilot.md +27 -0
- agent_notes/data/global-opencode.md +40 -0
- agent_notes/data/hooks/session-context.md.tpl +19 -0
- agent_notes/data/models/claude-haiku-4-5.yaml +15 -0
- agent_notes/data/models/claude-opus-4-1.yaml +16 -0
- agent_notes/data/models/claude-opus-4-5.yaml +16 -0
- agent_notes/data/models/claude-opus-4-6.yaml +16 -0
- agent_notes/data/models/claude-opus-4-7.yaml +15 -0
- agent_notes/data/models/claude-sonnet-4-5.yaml +16 -0
- agent_notes/data/models/claude-sonnet-4-6.yaml +15 -0
- agent_notes/data/models/claude-sonnet-4.yaml +16 -0
- agent_notes/data/pricing.yaml +33 -0
- agent_notes/data/roles/orchestrator.yaml +5 -0
- agent_notes/data/roles/reasoner.yaml +5 -0
- agent_notes/data/roles/scout.yaml +5 -0
- agent_notes/data/roles/worker.yaml +5 -0
- agent_notes/data/rules/code-quality.md +9 -0
- agent_notes/data/rules/safety.md +10 -0
- agent_notes/data/scripts/cost-report +211 -0
- agent_notes/data/skills/brainstorming/SKILL.md +57 -0
- agent_notes/data/skills/code-review/SKILL.md +64 -0
- agent_notes/data/skills/debugging-protocol/SKILL.md +51 -0
- agent_notes/data/skills/docker-compose/SKILL.md +318 -0
- agent_notes/data/skills/docker-compose-advanced/SKILL.md +575 -0
- agent_notes/data/skills/docker-dockerfile/SKILL.md +385 -0
- agent_notes/data/skills/docker-dockerfile-languages/SKILL.md +293 -0
- agent_notes/data/skills/git/SKILL.md +87 -0
- agent_notes/data/skills/rails-active-storage/SKILL.md +321 -0
- agent_notes/data/skills/rails-broadcasting/SKILL.md +374 -0
- agent_notes/data/skills/rails-concerns/SKILL.md +806 -0
- agent_notes/data/skills/rails-controllers/SKILL.md +510 -0
- agent_notes/data/skills/rails-controllers-advanced/SKILL.md +441 -0
- agent_notes/data/skills/rails-helpers/SKILL.md +677 -0
- agent_notes/data/skills/rails-initializers/SKILL.md +79 -0
- agent_notes/data/skills/rails-javascript/SKILL.md +567 -0
- agent_notes/data/skills/rails-jobs/SKILL.md +700 -0
- agent_notes/data/skills/rails-kamal/SKILL.md +483 -0
- agent_notes/data/skills/rails-lib/SKILL.md +101 -0
- agent_notes/data/skills/rails-mailers/SKILL.md +321 -0
- agent_notes/data/skills/rails-migrations/SKILL.md +268 -0
- agent_notes/data/skills/rails-models/SKILL.md +459 -0
- agent_notes/data/skills/rails-models-advanced/SKILL.md +398 -0
- agent_notes/data/skills/rails-routes/SKILL.md +804 -0
- agent_notes/data/skills/rails-style/SKILL.md +538 -0
- agent_notes/data/skills/rails-testing-controllers/SKILL.md +343 -0
- agent_notes/data/skills/rails-testing-models/SKILL.md +296 -0
- agent_notes/data/skills/rails-testing-system/SKILL.md +375 -0
- agent_notes/data/skills/rails-validations/SKILL.md +108 -0
- agent_notes/data/skills/rails-view-components/SKILL.md +511 -0
- agent_notes/data/skills/rails-view-components-advanced/SKILL.md +376 -0
- agent_notes/data/skills/rails-views/SKILL.md +413 -0
- agent_notes/data/skills/rails-views-advanced/SKILL.md +450 -0
- agent_notes/data/skills/refactoring-protocol/SKILL.md +64 -0
- agent_notes/data/skills/tdd/SKILL.md +57 -0
- agent_notes/data/templates/__init__.py +1 -0
- agent_notes/data/templates/__pycache__/__init__.cpython-314.pyc +0 -0
- agent_notes/data/templates/frontmatter/__init__.py +1 -0
- agent_notes/data/templates/frontmatter/__pycache__/__init__.cpython-314.pyc +0 -0
- agent_notes/data/templates/frontmatter/__pycache__/claude.cpython-314.pyc +0 -0
- agent_notes/data/templates/frontmatter/__pycache__/cursor.cpython-314.pyc +0 -0
- agent_notes/data/templates/frontmatter/__pycache__/opencode.cpython-314.pyc +0 -0
- agent_notes/data/templates/frontmatter/claude.py +44 -0
- agent_notes/data/templates/frontmatter/opencode.py +104 -0
- agent_notes/doctor_checks.py +189 -0
- agent_notes/domain/__init__.py +17 -0
- agent_notes/domain/agent.py +34 -0
- agent_notes/domain/cli_backend.py +40 -0
- agent_notes/domain/diagnostics.py +29 -0
- agent_notes/domain/diff.py +44 -0
- agent_notes/domain/model.py +27 -0
- agent_notes/domain/role.py +13 -0
- agent_notes/domain/rule.py +13 -0
- agent_notes/domain/skill.py +15 -0
- agent_notes/domain/state.py +46 -0
- agent_notes/install_state.py +11 -0
- agent_notes/registries/__init__.py +16 -0
- agent_notes/registries/_base.py +46 -0
- agent_notes/registries/agent_registry.py +107 -0
- agent_notes/registries/cli_registry.py +89 -0
- agent_notes/registries/model_registry.py +85 -0
- agent_notes/registries/role_registry.py +64 -0
- agent_notes/registries/rule_registry.py +80 -0
- agent_notes/registries/skill_registry.py +141 -0
- agent_notes/services/__init__.py +8 -0
- agent_notes/services/diagnostics/__init__.py +47 -0
- agent_notes/services/diagnostics/_checks.py +272 -0
- agent_notes/services/diagnostics/_display.py +346 -0
- agent_notes/services/diagnostics/_fix.py +169 -0
- agent_notes/services/diff.py +349 -0
- agent_notes/services/fs.py +195 -0
- agent_notes/services/install_state_builder.py +210 -0
- agent_notes/services/installer.py +293 -0
- agent_notes/services/memory_backend.py +155 -0
- agent_notes/services/rendering.py +329 -0
- agent_notes/services/session_context.py +23 -0
- agent_notes/services/settings_writer.py +79 -0
- agent_notes/services/state_store.py +249 -0
- agent_notes/services/ui.py +419 -0
- agent_notes/services/user_config.py +62 -0
- agent_notes/services/validation.py +67 -0
- agent_notes/state.py +21 -0
- agent_notes-2.0.4.dist-info/METADATA +14 -0
- agent_notes-2.0.4.dist-info/RECORD +162 -0
- agent_notes-2.0.4.dist-info/WHEEL +5 -0
- agent_notes-2.0.4.dist-info/entry_points.txt +2 -0
- agent_notes-2.0.4.dist-info/licenses/LICENSE +21 -0
- agent_notes-2.0.4.dist-info/top_level.txt +2 -0
- tests/conftest.py +20 -0
- tests/functional/__init__.py +0 -0
- tests/functional/test_build_commands.py +88 -0
- tests/functional/test_registries.py +128 -0
- tests/integration/__init__.py +0 -0
- tests/integration/test_build_output.py +129 -0
- tests/plugins/__init__.py +0 -0
- tests/plugins/test_agents.py +93 -0
- tests/plugins/test_skills.py +77 -0
|
@@ -0,0 +1,575 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: docker-compose-advanced
|
|
3
|
+
description: "Docker Compose advanced: database services, caches, proxies, dev/prod configs, and full stack examples"
|
|
4
|
+
group: docker
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Docker Compose (Advanced)
|
|
8
|
+
|
|
9
|
+
## Database Services
|
|
10
|
+
|
|
11
|
+
### PostgreSQL
|
|
12
|
+
|
|
13
|
+
```yaml
|
|
14
|
+
services:
|
|
15
|
+
db:
|
|
16
|
+
image: postgres:16-alpine
|
|
17
|
+
restart: unless-stopped
|
|
18
|
+
environment:
|
|
19
|
+
POSTGRES_USER: ${DB_USER:-postgres}
|
|
20
|
+
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
|
21
|
+
POSTGRES_DB: ${DB_NAME:-myapp}
|
|
22
|
+
# Performance tuning
|
|
23
|
+
POSTGRES_SHARED_BUFFERS: 256MB
|
|
24
|
+
POSTGRES_EFFECTIVE_CACHE_SIZE: 1GB
|
|
25
|
+
volumes:
|
|
26
|
+
# Data persistence
|
|
27
|
+
- postgres_data:/var/lib/postgresql/data
|
|
28
|
+
# Initialization scripts
|
|
29
|
+
- ./db/init:/docker-entrypoint-initdb.d:ro
|
|
30
|
+
# Backups
|
|
31
|
+
- ./backups:/backups
|
|
32
|
+
# SECURITY: Only expose in development, not production
|
|
33
|
+
# ports:
|
|
34
|
+
# - "${DB_PORT:-5432}:5432"
|
|
35
|
+
networks:
|
|
36
|
+
- app_network
|
|
37
|
+
healthcheck:
|
|
38
|
+
test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-postgres}"]
|
|
39
|
+
interval: 10s
|
|
40
|
+
timeout: 5s
|
|
41
|
+
retries: 5
|
|
42
|
+
deploy:
|
|
43
|
+
resources:
|
|
44
|
+
limits:
|
|
45
|
+
cpus: '2'
|
|
46
|
+
memory: 2G
|
|
47
|
+
reservations:
|
|
48
|
+
cpus: '1'
|
|
49
|
+
memory: 1G
|
|
50
|
+
|
|
51
|
+
volumes:
|
|
52
|
+
postgres_data:
|
|
53
|
+
driver: local
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### MySQL
|
|
57
|
+
|
|
58
|
+
```yaml
|
|
59
|
+
services:
|
|
60
|
+
db:
|
|
61
|
+
image: mysql:8.0
|
|
62
|
+
restart: unless-stopped
|
|
63
|
+
command: --default-authentication-plugin=mysql_native_password
|
|
64
|
+
environment:
|
|
65
|
+
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
|
|
66
|
+
MYSQL_DATABASE: ${DB_NAME:-myapp}
|
|
67
|
+
MYSQL_USER: ${DB_USER:-myapp}
|
|
68
|
+
MYSQL_PASSWORD: ${DB_PASSWORD}
|
|
69
|
+
volumes:
|
|
70
|
+
- mysql_data:/var/lib/mysql
|
|
71
|
+
- ./db/init:/docker-entrypoint-initdb.d:ro
|
|
72
|
+
networks:
|
|
73
|
+
- app_network
|
|
74
|
+
healthcheck:
|
|
75
|
+
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
|
|
76
|
+
interval: 10s
|
|
77
|
+
timeout: 5s
|
|
78
|
+
retries: 5
|
|
79
|
+
|
|
80
|
+
volumes:
|
|
81
|
+
mysql_data:
|
|
82
|
+
driver: local
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### MongoDB
|
|
86
|
+
|
|
87
|
+
```yaml
|
|
88
|
+
services:
|
|
89
|
+
mongodb:
|
|
90
|
+
image: mongo:7
|
|
91
|
+
restart: unless-stopped
|
|
92
|
+
environment:
|
|
93
|
+
MONGO_INITDB_ROOT_USERNAME: ${MONGO_USER:-admin}
|
|
94
|
+
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_PASSWORD}
|
|
95
|
+
MONGO_INITDB_DATABASE: ${MONGO_DB:-myapp}
|
|
96
|
+
volumes:
|
|
97
|
+
- mongodb_data:/data/db
|
|
98
|
+
- mongodb_config:/data/configdb
|
|
99
|
+
- ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
|
|
100
|
+
networks:
|
|
101
|
+
- app_network
|
|
102
|
+
healthcheck:
|
|
103
|
+
test: echo 'db.runCommand("ping").ok' | mongosh localhost:27017/test --quiet
|
|
104
|
+
interval: 10s
|
|
105
|
+
timeout: 10s
|
|
106
|
+
retries: 5
|
|
107
|
+
|
|
108
|
+
volumes:
|
|
109
|
+
mongodb_data:
|
|
110
|
+
driver: local
|
|
111
|
+
mongodb_config:
|
|
112
|
+
driver: local
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Cache and Message Queue Services
|
|
118
|
+
|
|
119
|
+
### Redis
|
|
120
|
+
|
|
121
|
+
```yaml
|
|
122
|
+
services:
|
|
123
|
+
redis:
|
|
124
|
+
image: redis:7-alpine
|
|
125
|
+
restart: unless-stopped
|
|
126
|
+
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
|
|
127
|
+
volumes:
|
|
128
|
+
- redis_data:/data
|
|
129
|
+
- ./redis.conf:/usr/local/etc/redis/redis.conf:ro
|
|
130
|
+
networks:
|
|
131
|
+
- app_network
|
|
132
|
+
healthcheck:
|
|
133
|
+
test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
|
|
134
|
+
interval: 10s
|
|
135
|
+
timeout: 5s
|
|
136
|
+
retries: 5
|
|
137
|
+
deploy:
|
|
138
|
+
resources:
|
|
139
|
+
limits:
|
|
140
|
+
memory: 512M
|
|
141
|
+
|
|
142
|
+
volumes:
|
|
143
|
+
redis_data:
|
|
144
|
+
driver: local
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### RabbitMQ
|
|
148
|
+
|
|
149
|
+
```yaml
|
|
150
|
+
services:
|
|
151
|
+
rabbitmq:
|
|
152
|
+
image: rabbitmq:3-management-alpine
|
|
153
|
+
restart: unless-stopped
|
|
154
|
+
environment:
|
|
155
|
+
RABBITMQ_DEFAULT_USER: ${RABBITMQ_USER:-admin}
|
|
156
|
+
RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASSWORD}
|
|
157
|
+
RABBITMQ_DEFAULT_VHOST: ${RABBITMQ_VHOST:-/}
|
|
158
|
+
volumes:
|
|
159
|
+
- rabbitmq_data:/var/lib/rabbitmq
|
|
160
|
+
ports:
|
|
161
|
+
- "5672:5672" # AMQP
|
|
162
|
+
- "15672:15672" # Management UI
|
|
163
|
+
networks:
|
|
164
|
+
- app_network
|
|
165
|
+
healthcheck:
|
|
166
|
+
test: rabbitmq-diagnostics -q ping
|
|
167
|
+
interval: 30s
|
|
168
|
+
timeout: 10s
|
|
169
|
+
retries: 5
|
|
170
|
+
|
|
171
|
+
volumes:
|
|
172
|
+
rabbitmq_data:
|
|
173
|
+
driver: local
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Reverse Proxy
|
|
179
|
+
|
|
180
|
+
### Nginx
|
|
181
|
+
|
|
182
|
+
```yaml
|
|
183
|
+
services:
|
|
184
|
+
nginx:
|
|
185
|
+
image: nginx:alpine
|
|
186
|
+
restart: unless-stopped
|
|
187
|
+
ports:
|
|
188
|
+
- "80:80"
|
|
189
|
+
- "443:443"
|
|
190
|
+
volumes:
|
|
191
|
+
# Configuration
|
|
192
|
+
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
|
193
|
+
- ./nginx/conf.d:/etc/nginx/conf.d:ro
|
|
194
|
+
# Static files
|
|
195
|
+
- ./public:/usr/share/nginx/html:ro
|
|
196
|
+
# SSL certificates
|
|
197
|
+
- ./certs:/etc/nginx/certs:ro
|
|
198
|
+
# Logs
|
|
199
|
+
- nginx_logs:/var/log/nginx
|
|
200
|
+
depends_on:
|
|
201
|
+
- app
|
|
202
|
+
networks:
|
|
203
|
+
- app_network
|
|
204
|
+
healthcheck:
|
|
205
|
+
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/health"]
|
|
206
|
+
interval: 30s
|
|
207
|
+
timeout: 10s
|
|
208
|
+
retries: 3
|
|
209
|
+
|
|
210
|
+
volumes:
|
|
211
|
+
nginx_logs:
|
|
212
|
+
driver: local
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Traefik
|
|
216
|
+
|
|
217
|
+
```yaml
|
|
218
|
+
services:
|
|
219
|
+
traefik:
|
|
220
|
+
image: traefik:v2.10
|
|
221
|
+
restart: unless-stopped
|
|
222
|
+
command:
|
|
223
|
+
- "--api.insecure=false"
|
|
224
|
+
- "--providers.docker=true"
|
|
225
|
+
- "--providers.docker.exposedbydefault=false"
|
|
226
|
+
- "--entrypoints.web.address=:80"
|
|
227
|
+
- "--entrypoints.websecure.address=:443"
|
|
228
|
+
- "--certificatesresolvers.letsencrypt.acme.httpchallenge=true"
|
|
229
|
+
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
|
|
230
|
+
- "--certificatesresolvers.letsencrypt.acme.email=admin@example.com"
|
|
231
|
+
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
|
|
232
|
+
ports:
|
|
233
|
+
- "80:80"
|
|
234
|
+
- "443:443"
|
|
235
|
+
volumes:
|
|
236
|
+
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
237
|
+
- ./letsencrypt:/letsencrypt
|
|
238
|
+
networks:
|
|
239
|
+
- app_network
|
|
240
|
+
|
|
241
|
+
app:
|
|
242
|
+
build: .
|
|
243
|
+
labels:
|
|
244
|
+
- "traefik.enable=true"
|
|
245
|
+
- "traefik.http.routers.app.rule=Host(`example.com`)"
|
|
246
|
+
- "traefik.http.routers.app.entrypoints=websecure"
|
|
247
|
+
- "traefik.http.routers.app.tls.certresolver=letsencrypt"
|
|
248
|
+
networks:
|
|
249
|
+
- app_network
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Development vs Production
|
|
255
|
+
|
|
256
|
+
### Development Configuration
|
|
257
|
+
|
|
258
|
+
```yaml
|
|
259
|
+
# compose.dev.yml
|
|
260
|
+
services:
|
|
261
|
+
app:
|
|
262
|
+
build:
|
|
263
|
+
context: .
|
|
264
|
+
dockerfile: Dockerfile
|
|
265
|
+
target: development
|
|
266
|
+
volumes:
|
|
267
|
+
# Mount source code for hot reload
|
|
268
|
+
- ./src:/app/src
|
|
269
|
+
- ./public:/app/public
|
|
270
|
+
# Don't mount node_modules (use container's version)
|
|
271
|
+
- /app/node_modules
|
|
272
|
+
ports:
|
|
273
|
+
# Expose debugger port
|
|
274
|
+
- "9229:9229"
|
|
275
|
+
environment:
|
|
276
|
+
- NODE_ENV=development
|
|
277
|
+
- DEBUG=app:*
|
|
278
|
+
command: npm run dev
|
|
279
|
+
|
|
280
|
+
db:
|
|
281
|
+
ports:
|
|
282
|
+
# Expose database port for local access in development
|
|
283
|
+
- "5432:5432"
|
|
284
|
+
|
|
285
|
+
# Usage: docker compose -f compose.yml -f compose.dev.yml up
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### Production Configuration
|
|
289
|
+
|
|
290
|
+
```yaml
|
|
291
|
+
# compose.prod.yml
|
|
292
|
+
services:
|
|
293
|
+
app:
|
|
294
|
+
build:
|
|
295
|
+
target: production
|
|
296
|
+
restart: always
|
|
297
|
+
# Don't expose ports directly in production - use reverse proxy
|
|
298
|
+
expose:
|
|
299
|
+
- "3000"
|
|
300
|
+
environment:
|
|
301
|
+
- NODE_ENV=production
|
|
302
|
+
deploy:
|
|
303
|
+
replicas: 3
|
|
304
|
+
resources:
|
|
305
|
+
limits:
|
|
306
|
+
cpus: '1'
|
|
307
|
+
memory: 1G
|
|
308
|
+
reservations:
|
|
309
|
+
cpus: '0.5'
|
|
310
|
+
memory: 512M
|
|
311
|
+
|
|
312
|
+
db:
|
|
313
|
+
# Don't expose database port in production
|
|
314
|
+
expose:
|
|
315
|
+
- "5432"
|
|
316
|
+
deploy:
|
|
317
|
+
resources:
|
|
318
|
+
limits:
|
|
319
|
+
cpus: '2'
|
|
320
|
+
memory: 2G
|
|
321
|
+
|
|
322
|
+
# Usage: docker compose -f compose.yml -f compose.prod.yml up -d
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
## Environment Variables
|
|
328
|
+
|
|
329
|
+
### .env File
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
# .env
|
|
333
|
+
NODE_ENV=production
|
|
334
|
+
APP_PORT=3000
|
|
335
|
+
|
|
336
|
+
# Database
|
|
337
|
+
DB_USER=postgres
|
|
338
|
+
DB_PASSWORD=secure_password_here
|
|
339
|
+
DB_NAME=myapp
|
|
340
|
+
DB_PORT=5432
|
|
341
|
+
|
|
342
|
+
# Redis
|
|
343
|
+
REDIS_PASSWORD=redis_password_here
|
|
344
|
+
|
|
345
|
+
# Application
|
|
346
|
+
JWT_SECRET=your_jwt_secret_here
|
|
347
|
+
API_KEY=your_api_key_here
|
|
348
|
+
|
|
349
|
+
# Version
|
|
350
|
+
VERSION=1.0.0
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### Using Environment Variables
|
|
354
|
+
|
|
355
|
+
```yaml
|
|
356
|
+
services:
|
|
357
|
+
app:
|
|
358
|
+
image: ${APP_NAME:-myapp}:${VERSION:-latest}
|
|
359
|
+
ports:
|
|
360
|
+
- "${APP_PORT:-3000}:3000"
|
|
361
|
+
environment:
|
|
362
|
+
# Use variables from .env
|
|
363
|
+
- DATABASE_URL=postgresql://${DB_USER}:${DB_PASSWORD}@db:${DB_PORT}/${DB_NAME}
|
|
364
|
+
- API_KEY=${API_KEY}
|
|
365
|
+
env_file:
|
|
366
|
+
# Load all variables from .env
|
|
367
|
+
- .env
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## Full Stack Application Example
|
|
373
|
+
|
|
374
|
+
```yaml
|
|
375
|
+
services:
|
|
376
|
+
# Frontend
|
|
377
|
+
frontend:
|
|
378
|
+
build:
|
|
379
|
+
context: ./frontend
|
|
380
|
+
dockerfile: Dockerfile
|
|
381
|
+
target: production
|
|
382
|
+
image: myapp-frontend:latest
|
|
383
|
+
restart: unless-stopped
|
|
384
|
+
depends_on:
|
|
385
|
+
- backend
|
|
386
|
+
networks:
|
|
387
|
+
- app_network
|
|
388
|
+
labels:
|
|
389
|
+
- "traefik.enable=true"
|
|
390
|
+
- "traefik.http.routers.frontend.rule=Host(`myapp.com`)"
|
|
391
|
+
|
|
392
|
+
# Backend API
|
|
393
|
+
backend:
|
|
394
|
+
build:
|
|
395
|
+
context: ./backend
|
|
396
|
+
dockerfile: Dockerfile
|
|
397
|
+
image: myapp-backend:latest
|
|
398
|
+
restart: unless-stopped
|
|
399
|
+
environment:
|
|
400
|
+
- NODE_ENV=production
|
|
401
|
+
- DATABASE_URL=postgresql://postgres:${DB_PASSWORD}@db:5432/myapp
|
|
402
|
+
- REDIS_URL=redis://redis:6379
|
|
403
|
+
- JWT_SECRET=${JWT_SECRET}
|
|
404
|
+
depends_on:
|
|
405
|
+
db:
|
|
406
|
+
condition: service_healthy
|
|
407
|
+
redis:
|
|
408
|
+
condition: service_healthy
|
|
409
|
+
volumes:
|
|
410
|
+
- uploads:/app/uploads
|
|
411
|
+
networks:
|
|
412
|
+
- app_network
|
|
413
|
+
labels:
|
|
414
|
+
- "traefik.enable=true"
|
|
415
|
+
- "traefik.http.routers.backend.rule=Host(`api.myapp.com`)"
|
|
416
|
+
|
|
417
|
+
# Background Worker
|
|
418
|
+
worker:
|
|
419
|
+
build:
|
|
420
|
+
context: ./backend
|
|
421
|
+
dockerfile: Dockerfile
|
|
422
|
+
command: npm run worker
|
|
423
|
+
restart: unless-stopped
|
|
424
|
+
environment:
|
|
425
|
+
- NODE_ENV=production
|
|
426
|
+
- DATABASE_URL=postgresql://postgres:${DB_PASSWORD}@db:5432/myapp
|
|
427
|
+
- REDIS_URL=redis://redis:6379
|
|
428
|
+
depends_on:
|
|
429
|
+
- db
|
|
430
|
+
- redis
|
|
431
|
+
networks:
|
|
432
|
+
- app_network
|
|
433
|
+
|
|
434
|
+
# Database
|
|
435
|
+
db:
|
|
436
|
+
image: postgres:16-alpine
|
|
437
|
+
restart: unless-stopped
|
|
438
|
+
environment:
|
|
439
|
+
- POSTGRES_PASSWORD=${DB_PASSWORD}
|
|
440
|
+
- POSTGRES_DB=myapp
|
|
441
|
+
volumes:
|
|
442
|
+
- postgres_data:/var/lib/postgresql/data
|
|
443
|
+
networks:
|
|
444
|
+
- app_network
|
|
445
|
+
healthcheck:
|
|
446
|
+
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
|
447
|
+
interval: 10s
|
|
448
|
+
timeout: 5s
|
|
449
|
+
retries: 5
|
|
450
|
+
|
|
451
|
+
# Cache
|
|
452
|
+
redis:
|
|
453
|
+
image: redis:7-alpine
|
|
454
|
+
restart: unless-stopped
|
|
455
|
+
command: redis-server --appendonly yes
|
|
456
|
+
volumes:
|
|
457
|
+
- redis_data:/data
|
|
458
|
+
networks:
|
|
459
|
+
- app_network
|
|
460
|
+
healthcheck:
|
|
461
|
+
test: ["CMD", "redis-cli", "ping"]
|
|
462
|
+
interval: 10s
|
|
463
|
+
timeout: 5s
|
|
464
|
+
retries: 5
|
|
465
|
+
|
|
466
|
+
# Reverse Proxy
|
|
467
|
+
traefik:
|
|
468
|
+
image: traefik:v2.10
|
|
469
|
+
restart: unless-stopped
|
|
470
|
+
command:
|
|
471
|
+
- "--providers.docker=true"
|
|
472
|
+
- "--providers.docker.exposedbydefault=false"
|
|
473
|
+
- "--entrypoints.web.address=:80"
|
|
474
|
+
- "--entrypoints.websecure.address=:443"
|
|
475
|
+
ports:
|
|
476
|
+
- "80:80"
|
|
477
|
+
- "443:443"
|
|
478
|
+
volumes:
|
|
479
|
+
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
480
|
+
networks:
|
|
481
|
+
- app_network
|
|
482
|
+
|
|
483
|
+
volumes:
|
|
484
|
+
postgres_data:
|
|
485
|
+
redis_data:
|
|
486
|
+
uploads:
|
|
487
|
+
|
|
488
|
+
networks:
|
|
489
|
+
app_network:
|
|
490
|
+
driver: bridge
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
---
|
|
494
|
+
|
|
495
|
+
## Best Practices
|
|
496
|
+
|
|
497
|
+
### ✅ DO
|
|
498
|
+
|
|
499
|
+
1. **Remove version field** - It's obsolete in Compose v2
|
|
500
|
+
2. **Use health checks** - Essential for orchestration
|
|
501
|
+
3. **Use named volumes** - Data persistence
|
|
502
|
+
4. **Set resource limits** - Prevent resource exhaustion
|
|
503
|
+
5. **Use restart policies** - Automatic recovery
|
|
504
|
+
6. **Isolate with networks** - Security
|
|
505
|
+
7. **Pin image versions** - Use specific tags, not :latest
|
|
506
|
+
8. **Use .env files** - Centralized configuration
|
|
507
|
+
9. **Separate dev/prod configs** - Different requirements
|
|
508
|
+
10. **Use depends_on conditions** - Proper startup order
|
|
509
|
+
|
|
510
|
+
### ❌ DON'T
|
|
511
|
+
|
|
512
|
+
1. **Include version field** - Generates warnings in Compose v2
|
|
513
|
+
2. **Use :latest in production** - Unpredictable
|
|
514
|
+
3. **Expose database ports** - Security risk in production
|
|
515
|
+
4. **Hardcode secrets** - Use environment variables
|
|
516
|
+
5. **Use privileged mode** - Security risk
|
|
517
|
+
6. **Mount sensitive host directories** - Security risk
|
|
518
|
+
7. **Forget resource limits** - Can exhaust host
|
|
519
|
+
8. **Use bridge network for everything** - Proper isolation matters
|
|
520
|
+
|
|
521
|
+
---
|
|
522
|
+
|
|
523
|
+
## Common Commands
|
|
524
|
+
|
|
525
|
+
```bash
|
|
526
|
+
# Start services
|
|
527
|
+
docker compose up -d
|
|
528
|
+
|
|
529
|
+
# Start with specific file
|
|
530
|
+
docker compose -f compose.yml -f compose.prod.yml up -d
|
|
531
|
+
|
|
532
|
+
# View logs
|
|
533
|
+
docker compose logs -f app
|
|
534
|
+
|
|
535
|
+
# Restart service
|
|
536
|
+
docker compose restart app
|
|
537
|
+
|
|
538
|
+
# Stop services
|
|
539
|
+
docker compose down
|
|
540
|
+
|
|
541
|
+
# Stop and remove volumes (CAUTION: deletes data)
|
|
542
|
+
docker compose down -v
|
|
543
|
+
|
|
544
|
+
# Build and start
|
|
545
|
+
docker compose up --build
|
|
546
|
+
|
|
547
|
+
# Scale service
|
|
548
|
+
docker compose up -d --scale worker=3
|
|
549
|
+
|
|
550
|
+
# Execute command in running container
|
|
551
|
+
docker compose exec app sh
|
|
552
|
+
|
|
553
|
+
# Run one-off command
|
|
554
|
+
docker compose run --rm app npm test
|
|
555
|
+
|
|
556
|
+
# View service status
|
|
557
|
+
docker compose ps
|
|
558
|
+
|
|
559
|
+
# View resource usage
|
|
560
|
+
docker compose stats
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
---
|
|
564
|
+
|
|
565
|
+
## References and Sources
|
|
566
|
+
|
|
567
|
+
This guide is based on official Docker Compose documentation:
|
|
568
|
+
|
|
569
|
+
- [Docker Compose Specification](https://docs.docker.com/reference/compose-file/)
|
|
570
|
+
- [Docker Compose Services Reference](https://docs.docker.com/reference/compose-file/services/)
|
|
571
|
+
- [Docker Compose Health Checks](https://docs.docker.com/reference/compose-file/services/#healthcheck)
|
|
572
|
+
- [Docker Compose depends_on](https://docs.docker.com/reference/compose-file/services/#depends_on)
|
|
573
|
+
- [Docker Compose Legacy Versions](https://docs.docker.com/reference/compose-file/legacy-versions/)
|
|
574
|
+
|
|
575
|
+
Last updated: December 2025
|