Docker Local Development
Run this skill in the main conversation. Do not spawn subagents, agent teams, or
delegated parallel workers unless the user explicitly approves the proposed
count and scope after being told that doing so can increase usage. Ask again
before expanding an approved scope.
Guardrails
- Design for local development. Keep production images, secrets, deployment, certificates, and runtime topology separate.
- Inspect before asking questions or proposing services. Treat detection as evidence, not authority.
- Ask only about unresolved choices that materially change the result. Group related questions and recommend a default; do not force a fixed questionnaire.
- Preserve existing Docker files and unrelated working-tree changes. Show a semantic diff before replacing or materially restructuring a working stack. Never commit, reset, delete volumes, run migrations or seeds, or overwrite files unless the user authorized that action.
- Generate only services the project uses or the user explicitly requests. A database is not mandatory when the project uses SQLite, a host service, or an external database.
- Prefer direct foreground commands and one concern per service. Add Supervisor or PM2 only when the project already requires it or production-parity testing justifies it.
- Prefer a stable top-level Compose
name: and role-based service names. Do not set container_name by default because it prevents service scaling and creates cross-project collisions.
- Select images by project constraints, team or production compatibility, trusted publisher, supported version, and architecture. Treat an already-downloaded image only as a tie-breaker. Avoid floating
latest tags in generated files.
- Publish only ports needed by the host. Bind local-only ports to
127.0.0.1 by default; keep databases, caches, SMTP, PHP-FPM, and internal APIs unexposed when possible.
- Keep secrets out of committed files, generated documentation, command output, and frontend or proxy containers. Generate an ignored local env file plus a safe example when configuration is needed.
Workflow
1. Inspect the project
Check Docker and Compose capabilities before selecting syntax:
docker version
docker compose version
Inspect, when present:
compose.yaml, compose.yml, docker-compose*.yml, and override files
Dockerfile*, .dockerignore, .devcontainer/, Makefiles, and package scripts
- application manifests, lockfiles, runtime-version files, env examples, and monorepo/workspace files
- existing local proxy conventions, Compose project names, networks, volumes, and host port mappings
- Git status and repository instructions before editing tracked files
Run stack detection from this skill directory, passing the project root:
./scripts/detect-stack.sh "<project-root>"
The script emits JSON on stdout and diagnostics on stderr. Confirm uncertain findings from source files without printing secret values.
When Docker is available, optionally inspect local images and networks:
./scripts/detect-images.sh
./scripts/detect-network.sh
Do not let cached images or a detected network override project compatibility or isolation requirements.
2. Resolve the design
Infer and summarize:
- apps in scope, dev commands, internal ports, shared packages, and live-reload needs
- runtime and package-manager versions from constraints and lockfiles
- database, cache, queue, scheduler, mail, and debugging services actually used
- existing reverse proxy, explicit
.localhost hostnames, same-origin /api routing, and required host exposure
- bind mounts versus Compose Watch; use Watch only when supported by the installed Compose version
- merge versus focused repair versus replacement of existing Docker files
Ask for confirmation only where evidence is absent or conflicting. Typical high-impact questions are the apps to run, database parity, reverse-proxy integration, externally reachable ports, and whether an existing stack may be restructured.
3. Load only relevant references
| Need |
Read |
| Detection rules and monorepo discovery |
references/tech-stack-detection.md |
| Images, processes, dependencies, mounts, environment, Dockerfiles |
references/service-configuration-guide.md |
| WordPress, Drupal, or Joomla |
references/cms-configuration-guide.md |
| Ports, proxies, domains, networks, host access |
references/networking-ports-guide.md |
| Existing Compose or Dockerfile changes |
references/merge-backup-strategy.md |
| Readiness checks and smoke tests |
references/health-check-patterns.md |
Use assets as starting points, not immutable output. Remove unselected services and adapt placeholders, healthchecks, commands, paths, users, and versions to the detected project.
4. Preview and generate
Before writing, present:
- files to create or modify
- inferred services and versions
- host ports and domains
- source/dependency mount strategy
- important changes to an existing stack
After approval where required, generate the smallest coherent setup:
- local env example and ignored local env file when needed
- dev Dockerfile or dev build target
.dockerignore
compose.yaml without the obsolete top-level version
- selected proxy, process, and helper configuration
- concise usage notes only when useful or requested
Prefer:
- bind-mounted source with named dependency volumes for straightforward active development
- Compose Watch with
sync, sync+restart, or rebuild rules for large trees, native dependencies, or projects that benefit from granular sync
- one-shot dependency installers only when they solve a real bind-mount or monorepo problem; mark them as expected to exit successfully
- separate worker and scheduler services using the same image as the app
- Compose profiles for optional debugging and administration tools
- health-gated dependencies only when the dependency defines a valid healthcheck
Do not automatically run migrations, seeds, CMS installers, destructive cleanup, or database write tests.
5. Verify
Run static checks first:
docker compose config --quiet
docker build --check .
Use docker build --check only when the installed Docker version supports it. Then build and start after the user has approved container execution:
docker compose build
docker compose up -d --wait
docker compose ps -a
If --wait is unavailable, start detached and poll declared healthchecks with a bounded timeout. Inspect logs for failed or restarting services.
Run the bundled checks when applicable:
./scripts/health-check.sh
./scripts/db-test.sh # connection/read-only query
./scripts/db-test.sh --crud # explicit temporary-table CRUD check
Also run a stack-specific smoke check such as php artisan about, wp core version, drush status, python manage.py check, or the application's health endpoint. Verify hot reload by changing a harmless source file only when the user authorized runtime testing.
6. Report
Report:
- generated or modified files
- selected services, versions, local URLs, and explicit host exposure
- exact verification commands and results
- expected stopped one-shot services
- assumptions, skipped checks, and platform-specific limitations
Never include secret values in the report.
Host Port Registry
Persistent host-port tracking is optional. First check:
PORT_REGISTRY_FILE="${DOCKER_LOCAL_DEV_PORT_REGISTRY:-${XDG_STATE_HOME:-$HOME/.local/state}/docker-local-dev/HOST_PORT_REGISTRY.md}"
test -f "$PORT_REGISTRY_FILE" && sed -n '1,220p' "$PORT_REGISTRY_FILE"
Before creating or refreshing the registry, explain the exact output path and scan root and obtain confirmation because the report may contain local project names and paths. Then run:
node ./scripts/scan-host-ports.mjs --root "<approved-root>" --out "$PORT_REGISTRY_FILE" --yes
Treat registered ports as reserved even when no process is currently listening. For a single project without a registry, a live port check is sufficient.
Acceptance Criteria
- Generated Compose configuration parses without unresolved placeholders.
- Selected images and commands match project constraints and contain no unreviewed floating tags.
- App containers reach dependencies by Compose service name, not
localhost.
- Optional services are absent or profile-gated.
- Host ports are minimal, conflict-free, and loopback-bound unless broader access was requested.
- Healthchecks invoke commands available in their images and test readiness rather than process presence alone.
- Source changes reload as intended; lockfile changes follow the documented install or rebuild path.
- No secrets, production data, private domains, or unauthorized mutations appear in generated files or reports.
1---2name: docker-local-dev3description: Coordinator-routed specialist for creating, repairing, or materially extending local-development Docker Compose, Dockerfiles, databases, and supporting services. Use after project-development-mindset makes local container topology the primary work, or directly when explicitly invoked or installed standalone. Do not use merely to run existing container commands, or for production deployment and VPS operations.4---5
6# Docker Local Development
7
8Run this skill in the main conversation. Do not spawn subagents, agent teams, or
9delegated parallel workers unless the user explicitly approves the proposed
10count and scope after being told that doing so can increase usage. Ask again
11before expanding an approved scope.
12
13## Guardrails
14
15- Design for local development. Keep production images, secrets, deployment, certificates, and runtime topology separate.
16- Inspect before asking questions or proposing services. Treat detection as evidence, not authority.
17- Ask only about unresolved choices that materially change the result. Group related questions and recommend a default; do not force a fixed questionnaire.
18- Preserve existing Docker files and unrelated working-tree changes. Show a semantic diff before replacing or materially restructuring a working stack. Never commit, reset, delete volumes, run migrations or seeds, or overwrite files unless the user authorized that action.
19- Generate only services the project uses or the user explicitly requests. A database is not mandatory when the project uses SQLite, a host service, or an external database.
20- Prefer direct foreground commands and one concern per service. Add Supervisor or PM2 only when the project already requires it or production-parity testing justifies it.
21- Prefer a stable top-level Compose `name:` and role-based service names. Do not set `container_name` by default because it prevents service scaling and creates cross-project collisions.
22- Select images by project constraints, team or production compatibility, trusted publisher, supported version, and architecture. Treat an already-downloaded image only as a tie-breaker. Avoid floating `latest` tags in generated files.
23- Publish only ports needed by the host. Bind local-only ports to `127.0.0.1` by default; keep databases, caches, SMTP, PHP-FPM, and internal APIs unexposed when possible.
24- Keep secrets out of committed files, generated documentation, command output, and frontend or proxy containers. Generate an ignored local env file plus a safe example when configuration is needed.
25
26## Workflow
27
28### 1. Inspect the project
29
30Check Docker and Compose capabilities before selecting syntax:
31
32```bash
33docker version
34docker compose version
35```
36
37Inspect, when present:
38
39- `compose.yaml`, `compose.yml`, `docker-compose*.yml`, and override files
40- `Dockerfile*`, `.dockerignore`, `.devcontainer/`, Makefiles, and package scripts
41- application manifests, lockfiles, runtime-version files, env examples, and monorepo/workspace files
42- existing local proxy conventions, Compose project names, networks, volumes, and host port mappings
43- Git status and repository instructions before editing tracked files
44
45Run stack detection from this skill directory, passing the project root:
46
47```bash
48./scripts/detect-stack.sh "<project-root>"
49```
50
51The script emits JSON on stdout and diagnostics on stderr. Confirm uncertain findings from source files without printing secret values.
52
53When Docker is available, optionally inspect local images and networks:
54
55```bash
56./scripts/detect-images.sh
57./scripts/detect-network.sh
58```
59
60Do not let cached images or a detected network override project compatibility or isolation requirements.
61
62### 2. Resolve the design
63
64Infer and summarize:
65
66- apps in scope, dev commands, internal ports, shared packages, and live-reload needs
67- runtime and package-manager versions from constraints and lockfiles
68- database, cache, queue, scheduler, mail, and debugging services actually used
69- existing reverse proxy, explicit `.localhost` hostnames, same-origin `/api` routing, and required host exposure
70- bind mounts versus Compose Watch; use Watch only when supported by the installed Compose version
71- merge versus focused repair versus replacement of existing Docker files
72
73Ask for confirmation only where evidence is absent or conflicting. Typical high-impact questions are the apps to run, database parity, reverse-proxy integration, externally reachable ports, and whether an existing stack may be restructured.
74
75### 3. Load only relevant references
76
77| Need | Read |
78|---|---|
79| Detection rules and monorepo discovery | `references/tech-stack-detection.md` |
80| Images, processes, dependencies, mounts, environment, Dockerfiles | `references/service-configuration-guide.md` |
81| WordPress, Drupal, or Joomla | `references/cms-configuration-guide.md` |
82| Ports, proxies, domains, networks, host access | `references/networking-ports-guide.md` |
83| Existing Compose or Dockerfile changes | `references/merge-backup-strategy.md` |
84| Readiness checks and smoke tests | `references/health-check-patterns.md` |
85
86Use assets as starting points, not immutable output. Remove unselected services and adapt placeholders, healthchecks, commands, paths, users, and versions to the detected project.
87
88### 4. Preview and generate
89
90Before writing, present:
91
92- files to create or modify
93- inferred services and versions
94- host ports and domains
95- source/dependency mount strategy
96- important changes to an existing stack
97
98After approval where required, generate the smallest coherent setup:
99
1001. local env example and ignored local env file when needed
1012. dev Dockerfile or dev build target
1023. `.dockerignore`
1034. `compose.yaml` without the obsolete top-level `version`
1045. selected proxy, process, and helper configuration
1056. concise usage notes only when useful or requested
106
107Prefer:
108
109- bind-mounted source with named dependency volumes for straightforward active development
110- Compose Watch with `sync`, `sync+restart`, or `rebuild` rules for large trees, native dependencies, or projects that benefit from granular sync
111- one-shot dependency installers only when they solve a real bind-mount or monorepo problem; mark them as expected to exit successfully
112- separate worker and scheduler services using the same image as the app
113- Compose profiles for optional debugging and administration tools
114- health-gated dependencies only when the dependency defines a valid healthcheck
115
116Do not automatically run migrations, seeds, CMS installers, destructive cleanup, or database write tests.
117
118### 5. Verify
119
120Run static checks first:
121
122```bash
123docker compose config --quiet
124docker build --check .
125```
126
127Use `docker build --check` only when the installed Docker version supports it. Then build and start after the user has approved container execution:
128
129```bash
130docker compose build
131docker compose up -d --wait
132docker compose ps -a
133```
134
135If `--wait` is unavailable, start detached and poll declared healthchecks with a bounded timeout. Inspect logs for failed or restarting services.
136
137Run the bundled checks when applicable:
138
139```bash
140./scripts/health-check.sh
141./scripts/db-test.sh # connection/read-only query
142./scripts/db-test.sh --crud # explicit temporary-table CRUD check
143```
144
145Also run a stack-specific smoke check such as `php artisan about`, `wp core version`, `drush status`, `python manage.py check`, or the application's health endpoint. Verify hot reload by changing a harmless source file only when the user authorized runtime testing.
146
147### 6. Report
148
149Report:
150
151- generated or modified files
152- selected services, versions, local URLs, and explicit host exposure
153- exact verification commands and results
154- expected stopped one-shot services
155- assumptions, skipped checks, and platform-specific limitations
156
157Never include secret values in the report.
158
159## Host Port Registry
160
161Persistent host-port tracking is optional. First check:
162
163```bash
164PORT_REGISTRY_FILE="${DOCKER_LOCAL_DEV_PORT_REGISTRY:-${XDG_STATE_HOME:-$HOME/.local/state}/docker-local-dev/HOST_PORT_REGISTRY.md}"
165test -f "$PORT_REGISTRY_FILE" && sed -n '1,220p' "$PORT_REGISTRY_FILE"
166```
167
168Before creating or refreshing the registry, explain the exact output path and scan root and obtain confirmation because the report may contain local project names and paths. Then run:
169
170```bash
171node ./scripts/scan-host-ports.mjs --root "<approved-root>" --out "$PORT_REGISTRY_FILE" --yes
172```
173
174Treat registered ports as reserved even when no process is currently listening. For a single project without a registry, a live port check is sufficient.
175
176## Acceptance Criteria
177
178- Generated Compose configuration parses without unresolved placeholders.
179- Selected images and commands match project constraints and contain no unreviewed floating tags.
180- App containers reach dependencies by Compose service name, not `localhost`.
181- Optional services are absent or profile-gated.
182- Host ports are minimal, conflict-free, and loopback-bound unless broader access was requested.
183- Healthchecks invoke commands available in their images and test readiness rather than process presence alone.
184- Source changes reload as intended; lockfile changes follow the documented install or rebuild path.
185- No secrets, production data, private domains, or unauthorized mutations appear in generated files or reports.