← Projects

forkspace(active)

Isolated local dev/test environments for multi-repo compose stacks.

Run parallel copies of the same compose stack side by side without fighting over ports, containers, and volumes. Wraps Docker Compose project namespacing in a CLI that makes isolated “lanes” a one-liner.

forkspace up dev
forkspace up test --fork agent-a
forkspace up test --fork agent-b
forkspace down test --fork agent-a
Status
v0.2, open source
Distribution
CLI + browser playground
Evidence
3 concurrent isolated test lanes, zero interference

Why

Git worktrees give agents and branches isolated file trees, but they all share one machine: one port 3306, one MySQL data directory, one Docker network namespace. Two agents running tests against “the” local database corrupt each other’s feedback loops. Full per-workspace VMs solve this with a sledgehammer; most stacks just need their compose services forked.

forkspace is the lightweight middle: a workspace-level compose manager that lets you choose isolation per service — container, namespace, or shared — instead of duplicating everything or sharing everything.

Scenarios

FIG. 01

All at once

All at once: dev QA, test baseline, agent forks, Puppeteer e2e, and an isolated migration running concurrently on one machine
One machine, many environments. Dev, test baseline, agent forks, e2e, and a migration each get their own port range; services share or fork by isolation level.

Dev, tests, agent forks, Puppeteer e2e, and a one-off migration can all run concurrently. Each environment gets its own port range; within an environment, forks share or fork individual services by isolation level — one MySQL can host many namespace databases while DynamoDB stays shared, and --isolate mysql spins up a separate container only for the fork that needs it.

Parallel / forking agents

FIG. 04

Parallel / forking agents

Parallel coding agents: three agents each fork the test environment; MySQL gives each a namespace database in one container, the other services are shared
Worktrees isolate files; forkspace isolates state. Each up test --fork <name> gets a slot, env file, and MySQL database inside one baseline container.

Worktrees isolate agents’ files; forkspace isolates their state. Each agent runs up test --fork <name> and gets its own slot, env file, and MySQL database inside the one baseline container — no per-agent MySQL, no corrupted feedback loops.

Local tests

FIG. 03

Local tests

Local tests: forkspace up test starts a clean seeded stack; down drops volumes so state does not drift between runs
Clean, seeded, ephemeral. up runs bootstrap → seed; down drops volumes. Coexists with the dev baseline — check proves the port math.

A clean, seeded, ephemeral stack on its own ports. up runs bootstrap → seed, tests source the env file, and down drops the volumes so no state drifts between runs. The test baseline coexists with your dev baseline — forkspace check proves the port math workspace-wide.

Full-stack local dev

FIG. 02

Full-stack local dev

Full-stack local dev: forkspace up dev starts a persistent baseline and writes .env.forkspace.dev for the app and QA
Persistent baseline for day-to-day work. up dev claims services from your repos' compose files, writes .env.forkspace.dev, and keeps volumes across down.

One persistent baseline for day-to-day work. forkspace up dev starts the services your forkspace.yml claims from your repos’ compose files, writes .env.forkspace.dev, and your app and QA sessions run against it. Volumes survive down.

Isolation levels

Each service in an environment declares an isolation level:

Level What the fork gets When to use
container Own compose service instance (container, volumes, host port) Full data isolation — separate MySQL per fork
namespace Namespace token inside the baseline service (own database, table prefix, …) Schema/data isolation without extra containers
shared The baseline service as-is DynamoDB, queues, object storage that don’t need per-fork copies

Typical test setup: MySQL is namespace, everything else is shared. One baseline MySQL; each --fork gets its own database name derived from the fork name.

services:
  mysql:
    isolation: namespace
    exports:
      DATABASE_URL: "mysql://root:root@{host}:{port}/{ns}"
  dynamodb:
    isolation: shared
    exports:
      DYNAMO_ENDPOINT: "http://{host}:{port}"

forkspace is the naming authority, not a database driver. It mints the namespace token ({ns}, FORKSPACE_NS), exposes export templates, and calls lifecycle hooks. Engine-specific create/drop/list logic lives in your repo scripts.

Playground

An interactive browser playground simulates forkspace without Docker — terminal, guided scenarios, command panel, and a live forkspace.yml editor.

Try it · full command reference, hooks, and env contract live in the GitHub README.