I use Claude Code daily for real product engineering. I'm building a clinical trials platform at PhaseV, and Claude Code is my primary coding partner across a multi-repo microservices stack.
Recently I asked it to set up a local Docker Compose dev environment with multi-instance support. It took 15 commits across 10+ sessions to get there. Not because the problem was hard, but because the first session produced everything as one intertwined system instead of building up to it incrementally.
What I Asked For
Several backend services, a frontend, and shared infrastructure. Each service in its own repo. I wanted a central repo that orchestrates everything with Docker Compose so a developer can run docker compose up. I mentioned that multi-instance support would be important — being able to run the stack twice for different feature branches.
What I Got
The first session produced everything at once:
- A
compose.yamlwithincludes for each service - A shared Dockerfile for all Python services
- A custom shell script called
pvwith subcommands for managing instances - Port offset arithmetic and environment file layering for multi-instance support
- Workspace selection logic for choosing which repos to include
I asked for a compose-based dev environment with multi-instance support. The implementation approach came as a package — one intertwined system. Each piece was defensible in isolation. Together they were complex, fragile, and hard to maintain.
The Simplification Marathon
What followed was 10+ sessions of me pulling things back out:
Session 2-3: "Why do we need the pv compose script? Can't we just use docker compose directly?" Claude explained the benefits. I said drop it. Dropped.
Session 4-5: "Why does each service use a shared Dockerfile? Let each repo own its own." Switched to per-repo Dockerfiles with Compose Watch for live reload. Removed the shared Dockerfile, entrypoint-dev.sh, and the pv rebuild command.
Session 6-7: "Why is infrastructure separate from apps? Just put them in the same Compose project." Merged infra into the main compose file. Removed container_name directives, the shared network, and the separate pv infra command.
Session 8: "Why do we need port variables for every service? Just let Docker assign random ports." Removed a dozen port variables from .env. Only the frontend kept a fixed port.
Session 9-10: "Why is .env so big? Most of these values are constants." Moved defaults into each service's compose file. The .env went from ~30 variables to 2.
Final state: A 15-line compose.yaml with includes, a compose.infra.yaml, a 2-line .env.example, and a README. Multi-instance works via Compose project names — no scripts, no port arithmetic.
What Happened
I went back and read the session transcripts — not just for this feature, but across other repos.
The unit of work is wrong. The default behavior is to treat each task as a single delivery — plan, build, present. By the time I saw the full output, the pieces were intertwined and hard to pull apart. If it had delivered a bare compose file first and then added multi-instance support on top, I could have steered the implementation approach early instead of unwinding it after the fact.
What I'm Trying
After the analysis, I added a rule to my global CLAUDE.md — the config file that Claude Code loads into every conversation:
## Lead with increments
For complex features, act as a tech lead managing the process:
1. Propose a sequence of increments — not a detailed plan,
just the milestones.
2. Implement the first increment autonomously. Build the
smallest complete version that works. Deliver it.
3. Check in briefly before the next increment. Let the user
decide if more is needed. Often the first increment is enough.
This is untested. I'm hoping it shifts Claude from "deliver the comprehensive solution" to "deliver the first working version and let the user steer from there." For the dev-environment case, that would have looked like: "Step 1: compose file that starts all services. Step 2: add profiles. Step 3: multi-instance support." By step 3, the basic setup would already be working, and I could have evaluated what multi-instance actually needs — instead of unwinding an over-engineered approach after the fact.
Whether a CLAUDE.md rule can actually change this behavior, I don't know yet. Discussion welcome.
Top comments (0)