Docker
Use when working with Docker — Dockerfile edits, docker-compose services, containers, or the dual-container (fast + Xdebug) setup — even when the user just says 'my container won't start'.From its SKILL.md
npx -y skills add event4u-app/agent-config --skill dockerAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 7 stars7 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
10.4 KB, ~2.5k tokens by cl100k_base, as published. Nobody here has run it
docker
When to use
Use this skill when working with Docker configuration, container setup, Dockerfile changes, or docker-compose modifications.
Do NOT use when:
- Production deployment (use
aws-infrastructureskill) - Codespaces setup (use
devcontainerskill)
Procedure: Modify Docker setup
- Gather context — read project Docker docs in
agents/orDocs/, checkMakefile/Taskfile.ymlfor targets, readdocker-compose.yml/compose.yamlfor service layout. - Identify scope — determine which service(s) are affected (PHP, NGINX, worker, scheduler, database).
- Inspect current state — run
docker compose psto see running containers and their health status. - Make the change — edit the relevant file (Dockerfile, compose file, NGINX config, Makefile target). Follow the conventions in the reference sections below.
- Rebuild affected containers —
docker compose build <service>(add--no-cacheif Dockerfile base layers changed). - Verify —
docker compose up -d, checkdocker compose psfor healthy status, run a smoke test (e.g.,make test-quickorcurl localhost).
Project architecture
Dockerfile (.docker/Dockerfile)
Multi-stage build with these targets:
| Stage | Purpose |
|---|---|
base | Alpine + PHP-FPM + system packages + extensions |
dev | Development: Xdebug, dev tools, Composer dev deps |
pro | Production: optimized, no dev deps, New Relic agent |
Key build args:
PHP_VERSION— extracted from Dockerfile, used by CICOMPOSER_AUTH— private registry access (passed as secret)CACHEBUST— weekly cache invalidation (date +%Y-%U)COMPOSER_NO_DEV—1for production,0for dev
Dual-container architecture (PHP projects)
Some projects run two PHP-FPM containers simultaneously (fast + Xdebug):
| Container | Purpose | PHP-FPM mode |
|---|---|---|
{project}-php | Fast execution, no debugger | pm = dynamic |
{project}-php-xdebug | Xdebug enabled, debugging | pm = ondemand |
NGINX routes requests based on HTTP headers:
- No header → fast container
X-Xdebug-Enable: 1orX-Debug-Session: PHPSTORM→ Xdebug container
docker-compose services
Read docker-compose.yml / compose.yaml to discover the actual service names. Common patterns:
| Service type | Description |
|---|---|
| PHP-FPM | Main application server |
| PHP-FPM + Xdebug | Debugging container |
| NGINX | Reverse proxy |
| Queue worker | Background job processing (e.g., Horizon) |
| Scheduler | Cron/task scheduler |
| Database | MariaDB / MySQL / PostgreSQL |
| Cache | Redis / Memcached |
Conventions
Container commands
- Always execute PHP commands inside the container, never on the host.
- Use
docker compose exec -T <service> ...for non-interactive (scripts, CI). - Use
make consolefor interactive shell access. - Use
make console-xdebugfor Xdebug container access.
Image building
- Production images use
target: pro— no dev dependencies. - Check the project's CI/CD config for target platform and registry.
- Docker Hub login may be needed for pulling base images (rate limits).
PHP extensions
Extensions are installed via mlocati/php-extension-installer:
- Check the Dockerfile for the current list.
- Add new extensions in the
basestage so they're available in all targets.
Environment files
.envis NOT baked into the Docker image.- Production:
.envis fetched from AWS Secrets Manager at deploy time. - Development:
.envis mounted via docker-compose volumes.
Makefile targets
Always check the Makefile for available targets before using raw docker commands:
make start # Start all containers
make stop # Stop all containers
make console # Enter PHP container (bash)
make console-xdebug # Enter Xdebug PHP container
make composer-install # Run composer install in container
make migrate # Run migrations
make migrate-and-seed # Run migrations + seed
make test # Run all tests (parallel)
Container orchestration
Environment synchronization
When the development environment is out of sync (missing containers, wrong state):
- Check status —
docker compose psto see which services are running. - Start missing services —
make startordocker compose up -d. - Rebuild if needed —
docker compose build --no-cache <service>after Dockerfile changes. - Reset state —
make migrate-and-seedafter fresh container start.
Common sync issues
| Symptom | Cause | Fix |
|---|---|---|
| "Connection refused" | Container not running | make start |
| "Table not found" | Migrations not run | make migrate-and-seed |
| "Class not found" | Composer not installed | make composer-install |
| Old PHP version | Image not rebuilt | docker compose build <php-service> |
| Extension missing | Dockerfile changed | Rebuild with --no-cache |
Multi-project orchestration
When running multiple projects simultaneously:
- Check for port conflicts — each project needs unique exposed ports.
- Use Traefik (see
traefikskill) for routing by domain instead of port. - Shared services (MariaDB, Redis) can be in a dedicated
docker-compose.shared.yml.
Security hardening checklist
When creating or reviewing Dockerfiles:
- Non-root user — create user with specific UID/GID, use
USERdirective beforeCMD. - No secrets in layers — never
ENVorCOPYsecrets. Use--mount=type=secret(BuildKit) or runtime secrets. - Minimal packages — only install what's needed. Remove package manager cache in the same
RUNlayer. - Read-only root filesystem — use
--read-onlyflag where possible, mount writable dirs explicitly. - No
latesttag — pin base image versions (node:18.19-alpine, notnode:latest). - Scan images — use
docker scout quickviewor Trivy for vulnerability scanning.
# Security pattern
RUN addgroup -g 1001 -S appgroup && \
adduser -S appuser -u 1001 -G appgroup
COPY --chown=appuser:appgroup . .
USER 1001
Health check patterns
Always add health checks to long-running services:
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8080/health || exit 1
In docker-compose, use condition: service_healthy for dependency ordering:
services:
app:
depends_on:
db:
condition: service_healthy
Image size optimization
| Technique | Impact | When |
|---|---|---|
| Multi-stage builds | High | Always — separate build from runtime |
| Alpine base images | High | When compatibility allows |
| Distroless images | High | Production, no shell needed |
.dockerignore | Medium | Always — exclude node_modules, .git, tests, docs |
Combine RUN layers | Medium | When installing packages + cleaning cache |
| Copy only artifacts | Medium | COPY --from=build only what's needed |
Build cache optimization
Use BuildKit cache mounts for package managers:
# Composer (PHP)
RUN --mount=type=cache,target=/root/.composer/cache \
composer install --no-dev --optimize-autoloader
# npm (Node.js)
RUN --mount=type=cache,target=/root/.npm \
npm ci --only=production
Layer ordering for cache efficiency:
- System packages (changes rarely)
- Dependency files (
composer.json,package.json) — changes sometimes RUN install— cached if dependency files unchanged- Source code (
COPY . .) — changes often, last layer
Output format
- Modified Docker configuration files (Dockerfile, docker-compose.yml)
- Updated Makefile targets if applicable
- Rebuild/restart instructions for affected containers
Auto-trigger keywords
- Docker
- docker-compose
- container
- Dockerfile
- PHP container
Known pitfalls
| Symptom | Root cause | Fix |
|---|---|---|
| Every build reinstalls all dependencies (builds are slow) | COPY . . runs before the dependency install, so any source edit busts the dependency layer's cache | Copy only the manifest + lockfile (composer.json+composer.lock / package.json+lock), install deps, THEN COPY . . |
| Image is much larger / slower to push than expected | No .dockerignore, so .git, vendor/, node_modules/, and local env files enter the build context and image | Add a .dockerignore excluding VCS, installed deps, build output, and secrets |
vendor/ or node_modules/ is empty inside the container even though install ran | A bind-mount of the project directory shadows the image's installed-deps directory | Put a named/anonymous volume over the deps dir, or don't bind-mount over it |
Files the container writes are owned by root on the host | The container process runs as UID 0; bind-mounted writes inherit that owner | Run as a non-root USER whose UID matches the host user, or chown on entry |
| Container exits immediately with code 0 | The CMD process daemonizes/backgrounds, so PID 1 has nothing to keep alive | Run the long-lived process in the foreground as PID 1 (no &, no daemonize flag) |
Gotcha
- All PHP commands (artisan, composer, phpunit) must run INSIDE the PHP container — never on the host.
- The fast container and Xdebug container share the same codebase but have different PHP configs — don't confuse them.
docker compose down -vdestroys volumes including the database — usedownwithout-vunless you mean it.- The model forgets to use
docker compose exec -T(no TTY) when running in scripts or CI.
Do NOT
- Do NOT change the base Alpine or PHP version without checking CI compatibility.
- Do NOT add dev-only tools to the
prostage. - Do NOT hardcode secrets in the Dockerfile — use build args or runtime secrets.
- Do NOT change
platformwithout verifying AWS runner architecture.
Related
- Skill:
traefik— local reverse proxy with real domains and HTTPS - Skill:
devcontainer— DevContainer and Codespaces setup - Skill:
php-debugging— Xdebug dual-container architecture - Rule:
docker-commands.md— all PHP commands run inside Docker
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.
Gives 0 of the 12 instructions most containers cloud skills give in ~2.5k tokens
Counted across 607 of the 657 authors here whose files we hold, read 2026-08-07
- Run containers as a non-root userin 66 of 607, across 46 files
- Use multi-stage buildsin 53 of 607, across 44 files
- Use Promise.all for independent operationsin 47 of 607, across 13 files
- Import directly instead of barrel filesin 46 of 607, across 12 files
- Use ternary instead of AND for conditionalsin 45 of 607, across 12 files
- Use Set or Map for O(1) lookupsin 42 of 607, across 10 files
- Create a .dockerignore filein 41 of 607, across 31 files
- Read individual rule files for detailsin 39 of 607, across 9 files
- Copy dependency files before source codein 36 of 607, across 23 files
- Authenticate server actions like API routesin 35 of 607, across 7 files
- Use next/dynamic for heavy componentsin 34 of 607, across 9 files
- Use React.cache for per-request deduplicationin 34 of 607, across 10 files
Said here and by no other author read
- run PHP commands inside the container
- use exec with no TTY in scripts
- check Makefile before using raw docker commands
- run database migrations after a fresh container start
- add new PHP extensions in the base stage
- rebuild containers after modifying Dockerfiles
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.