Skip to content

Operational Playbook

StepCommandWhat it catches
Lint sourcechant lint src/Latest tags (DKRS001)
Buildchant build src --lexicon docker -o docker-compose.ymlPost-synth: unused volumes, SSH exposure, Dockerfile issues
Validate configdocker compose configCompose schema validation

Run lint on every edit. Build + docker compose config before deploying.

Terminal window
# Build
chant build src --lexicon docker -o docker-compose.yml
# Validate
docker compose config --quiet
# Start detached
docker compose up -d
# Watch logs
docker compose logs -f
Terminal window
# Stop containers (keep volumes)
docker compose down
# Stop and remove volumes
docker compose down -v
Terminal window
# Container status and health
docker compose ps
# Logs for a specific service
docker compose logs api
docker compose logs api --follow
# Exec into a running container
docker compose exec api sh
# Inspect a stopped container
docker compose run --rm api sh
SymptomLikely causeFix
service "x" depends on undefined service "y"depends_on references wrong nameMatch the TypeScript export name
Container exits immediatelyApp crash on startdocker compose logs <service>
Port already in useHost port conflictChange host port in ports:
Volume not persistingAnonymous volume vs named volumeUse volumename:/path not just /path
Service can’t reach anotherWrong hostnameUse the service name as hostname
required variable ... is not setMissing env var for env("X", { required: true })Set var in environment or .env

Add health checks to stateful services so dependents wait for readiness:

export const db = new Service({
image: "postgres:16-alpine",
healthcheck: {
test: ["CMD-SHELL", "pg_isready -U myapp"],
interval: "10s",
timeout: "5s",
retries: 5,
start_period: "10s",
},
});
export const api = new Service({
image: "myapp:1.0",
depends_on: {
db: { condition: "service_healthy" },
},
});
  • Pin image tags — avoid :latest (DKRS001 / DKRD001 flags this)
  • Do not expose port 22 (DKRD003 flags this)
  • Set restart: "unless-stopped" or restart: "always" for long-running services
  • Use named volumes for persistent data — never rely on container filesystem
  • Use env() with { required: true } for secrets rather than hardcoding