Background
Patch Labs builds automation tooling for developers. Sofia is the only engineer. She'd built her own dev environment setup over two years — a mix of shell scripts, documented manual steps, and institutional knowledge she carried in her head. It worked most of the time. The problem was 'most of the time.' After a macOS update, after a new dependency version, after coming back from a week off — the environment would have something subtly wrong. An afternoon would disappear. She'd fixed the same Postgres connection issue four separate times and written it down twice.
The challenge
Sofia needed a development environment that was fully deterministic — same behavior on any machine, after any amount of time away, regardless of what had changed on her system. She also needed local development to be honest about production: if something worked locally, it should work in production, and vice versa. The S3-compatible storage was where this had bitten her most — her local mock didn't behave like real S3 at the edges, and she'd shipped bugs because of it.
How they built it
One command on a new machine
Sofia's test for ShipAI was brutal: factory reset a spare laptop, install Docker, clone the repo, run the setup command. Twelve minutes later, the full stack was running. App, database, cache, object storage. She wrote a ticket in her own product, uploaded a file, ran a background job. Everything worked. She'd never had a setup experience like that before.
The Postgres situation, permanently resolved
The recurring Postgres connection issue — the one she'd fixed four times — had always been caused by version drift between what she'd installed locally and what the project expected. With Drizzle migrations running against a pinned Postgres version in Docker, that class of problem no longer exists. Database state is deterministic. She hasn't had a 'what's wrong with my database' morning since.
Local storage that behaves like real storage
Patch Labs uses object storage for file processing. The MinIO instance in the Docker setup implements the same API as AWS S3, down to the edge cases. Sofia ran her file processing logic against MinIO locally for weeks before testing in production. When she deployed, it worked exactly as it had locally. The previous version of her setup had cost her two days of debugging when a local mock diverged from real S3 behavior.
The side effect: more shipping
Sofia hadn't thought of the environment friction as a velocity problem — she thought of it as an annoying tax. After six weeks without environment issues, she looked at her commit history and noticed she'd shipped more in those six weeks than in the previous three months combined. Getting her mornings back turned out to compound.
Outcomes
Consistent 2x weekly output after six weeks
Sofia shipped more in the six weeks following the switch than in the previous three months. She attributes the difference to recovered morning time and reduced context switching.
Zero environment debugging incidents
In six months since the switch, Sofia has had zero 'it works locally but not in CI' or 'database state is wrong on this machine' incidents. The previous rate was roughly once every three weeks.
New machine setup in under 15 minutes
The test she ran on a fresh laptop — clone, install Docker, run setup — completed in twelve minutes to a fully working development stack.
Production bugs from environment mismatch eliminated
Sofia had shipped two bugs in the previous year caused by her local storage mock diverging from real S3 behavior. That class of bug no longer exists.
In their own words
It's not dramatic. No single morning I recover is worth a lot. But I was losing maybe four hours a week to environment friction — setup issues, debugging sessions, figuring out why something worked yesterday and doesn't today. Getting those four hours back every week, for months, adds up to a meaningful amount of product. I track my output. I can see it in the numbers.
“I spent the first two years of Patch Labs losing Monday mornings to my own dev environment. It sounds trivial but it compounds. Getting that time back didn't just change my velocity — it changed my relationship with the project.”
— Sofia Lindqvist
Frequently asked questions
How is the local environment set up?
Docker Compose brings up PostgreSQL, Redis, MinIO (S3-compatible object storage), and the Next.js application together. The database schema is applied automatically via Drizzle migrations. The entire stack runs from a single command with no cloud accounts required.
Does the local setup match production closely enough to trust?
Sofia's experience: yes. The service versions are pinned, the storage API is identical, and the environment variable structure maps directly to production. She's had zero production surprises from local-to-production differences since switching.
Can the same setup be used in CI?
Yes. Sofia runs the same Docker Compose configuration in GitHub Actions for integration tests. Same service versions, same schema state, same behavior as local.