- 1 container per project
- 1 worktree per person
- 1 preview per person
The problem
Give each person their own container and collaboration gets expensive and slow to start. Put everyone in one shared container and they overwrite each other's files, break each other's previews and fight over one git branch.
I wanted the middle ground: one container per project, but with each person working as if they had it to themselves.
Worktrees: one repo, many checkouts
git worktree lets one repository have several working directories, each on its own branch, sharing a single object store. That was the core of it:
# one worktree per person, each on its own branch
git worktree add /work/alice -b alice/settings-2fa
git worktree add /work/bob -b bob/fix-checkoutEach person edits their own directory and commits to their own branch. Merging back is ordinary git, with no file locks and no custom sync protocol.
Keeping people apart
Separate directories are not separation if every process can write everywhere. Three layers did the real work:
- A user ID per person in the container. Each person's processes run as their own user, and file permissions keep them inside their own worktree.
- A preview per person. Each worktree gets its own document root, and the router sends each person's preview URL to their own copy. You see your change, not someone else's half-finished one.
- Health checks per preview. The routing layer only sends traffic to a preview that answers its health check, so a person who breaks their build gets a clear error instead of a blank page, and nobody else is affected.
What broke first
- Shared caches. Package and build caches were shared by default and written by whoever ran first. Giving each user their own cache directory fixed permission errors that looked random.
- Ports. Every preview wanted the same port. Assigning ports per worktree, and routing by name instead of by port, removed a whole class of "works for me" bugs.
- Cleanup. Abandoned worktrees pile up. A worktree now goes away with its session, and
git worktree pruneruns on a schedule.
What I would do differently
I would treat the per-person user ID as the foundation from the start instead of adding it after the directories. Most of the later bugs were about permissions, and they would never have existed if every process had started as the right user.
Takeaway
You don't always need more containers to give people their own space. One repository, a worktree each, a user each and a routed preview each got most of the isolation for a fraction of the cost.