new-project-docker — new project = Docker + Makefile
Invariant: every new project is containerized from the start. Not "local first,
wrap it later" — from the first commit there's a Dockerfile, docker-compose.yml,
Makefile and log wiring. This kills "works on my machine", gives unified commands and
turns on observability right away.
What we create in the skeleton
Dockerfile — app image (multi-stage if compiled; slim base).
docker-compose.yml — app service(s) + deps (db/cache/queue).
Each service — restart, mem_limit/cpus, healthcheck where apt.
.env + .env.example — cfg (secrets in .env, it's in .gitignore;
.env.example with placeholders in git).
Makefile — unified commands (template in templates.md):
help, info, up, down, ps, restart name=…, logs name=…, build,
config, log-test. HOST_IP computed dynamically (hostname -I).
- Logging — wire up skill
fluent-logging right away: submodule/composer
libs, overlay docker/fluent-logging.yml, env block, COMPOSE_FILE. Containers
write structured JSON to stdout → fluent-bit → Graylog.
.gitignore, README.md/DEPLOY.md with the command list.
Happy-path
- Create repo +
git init. Commits — per git-flow core.
Dockerfile + docker-compose.yml (app + deps).
Makefile from templates.md — adjust service names/ports.
.env/.env.example (incl. fluent-logging block from skill fluent-logging).
- Wire up logs (skill
fluent-logging): lib + overlay + COMPOSE_FILE.
make config → make up → make log-test → check arrival in Graylog.
Principles
- Host ports — unique on the machine (don't collide with other projects;
ss -ltn).
Bind to 127.0.0.1:<port> if not needed externally.
COMPOSE_PROJECT_NAME set in .env (else broken container names and
prefixes in Graylog).
- Resource limits (
mem_limit/cpus) with headroom — but set them, don't leave unset.
- Deps — managed images (postgres/redis/…), don't install into the app image.
- Deploy =
docker compose build && up -d (+ git submodule update --init if
log lib is a submodule). Document in DEPLOY.md.
Templates (Makefile, docker-compose.yml, Dockerfile) — in templates.md.
Take log wiring from skill fluent-logging.
1---2name: new-project-docker3description: Scaffold a new project, repository, or service in Docker from day one with a Dockerfile, Docker Compose, Makefile, and fluent logging. Use for a new project, bootstrap, service setup, or project skeleton.4---56# new-project-docker — new project = Docker + Makefile78**Invariant: every new project is containerized from the start.** Not "local first,9wrap it later" — from the first commit there's a `Dockerfile`, `docker-compose.yml`,10`Makefile` and log wiring. This kills "works on my machine", gives unified commands and11turns on observability right away.1213## What we create in the skeleton141. **`Dockerfile`** — app image (multi-stage if compiled; slim base).152. **`docker-compose.yml`** — app service(s) + deps (db/cache/queue).16 Each service — `restart`, `mem_limit`/`cpus`, healthcheck where apt.173. **`.env` + `.env.example`** — cfg (secrets in `.env`, it's in `.gitignore`;18 `.env.example` with placeholders in git).194. **`Makefile`** — unified commands (template in [templates.md](templates.md)):20 `help`, `info`, `up`, `down`, `ps`, `restart name=…`, `logs name=…`, `build`,21 `config`, `log-test`. `HOST_IP` computed dynamically (`hostname -I`).225. **Logging** — wire up **skill `fluent-logging`** right away: submodule/composer23 libs, overlay `docker/fluent-logging.yml`, env block, `COMPOSE_FILE`. Containers24 write structured JSON to stdout → fluent-bit → Graylog.256. **`.gitignore`**, `README.md`/`DEPLOY.md` with the command list.2627## Happy-path281. Create repo + `git init`. Commits — per [git-flow](../git-flow/SKILL.md) core.292. `Dockerfile` + `docker-compose.yml` (app + deps).303. `Makefile` from [templates.md](templates.md) — adjust service names/ports.314. `.env`/`.env.example` (incl. fluent-logging block from skill `fluent-logging`).325. Wire up logs (skill `fluent-logging`): lib + overlay + `COMPOSE_FILE`.336. `make config` → `make up` → `make log-test` → check arrival in Graylog.3435## Principles36- **Host ports — unique** on the machine (don't collide with other projects; `ss -ltn`).37 Bind to `127.0.0.1:<port>` if not needed externally.38- **`COMPOSE_PROJECT_NAME`** set in `.env` (else broken container names and39 prefixes in Graylog).40- **Resource limits** (`mem_limit`/`cpus`) with headroom — but set them, don't leave unset.41- **Deps — managed images** (postgres/redis/…), don't install into the app image.42- **Deploy** = `docker compose build && up -d` (+ `git submodule update --init` if43 log lib is a submodule). Document in `DEPLOY.md`.4445Templates (`Makefile`, `docker-compose.yml`, `Dockerfile`) — in [templates.md](templates.md).46Take log wiring from skill `fluent-logging`.