Skip to content

Multi-Instance Development ​

Run multiple instances of the project simultaneously β€” useful when multiple developers, AI agents, or workflows need to work on different branches without port conflicts or shared database interference.

Each instance gets:

  • Its own git worktree (isolated code checkout)
  • Its own Docker containers (MongoDB, Redis) with separate data volumes
  • Offset ports so nothing conflicts with the main repo or other instances

Port Mapping ​

Each instance offsets all ports by N x 100:

ServiceMainInstance 1Instance 2
Backend API388839884088
Frontend Vite517352735373
MongoDB270172711727217
Redis637964796579
Redis Insight554056405740
Bull Board300131013201

Create an Instance ​

From the main repo root:

bash
./scripts/create-instance.sh 1

This will:

  1. Create a git worktree at ../tell-ia-instance-1 on branch instance-1
  2. Run pnpm install
  3. Build shared packages (@tellia-solutions/schemas)
  4. Copy .env files with adjusted ports
  5. Create a .env.compose file for Docker Compose

Start the Instance ​

1. Start infrastructure ​

bash
cd ../tell-ia-instance-1/apps/agri-backend
docker compose --env-file .env.compose up -d

IMPORTANT

Always use --env-file .env.compose when running docker compose in an instance. The regular .env contains multi-line values that Docker Compose can't parse for variable interpolation.

2. Seed the database ​

The instance database starts empty. Populate it from production:

bash
cd ../tell-ia-instance-1/apps/agri-backend
./dev/scripts/create-user-db.sh

The script automatically reads MONGODB_URI from the instance's .env and targets the correct port.

You can also specify the target explicitly:

bash
TARGET_MONGODB_URI="mongodb://user:pass@localhost:27117" ./dev/scripts/create-user-db.sh

3. Start backend and frontend ​

bash
# Terminal 1 β€” Backend
cd ../tell-ia-instance-1
pnpm --filter agri-backend dev

# Terminal 2 β€” Frontend
cd ../tell-ia-instance-1
pnpm --filter agri-frontend dev

Connect to the Instance Database ​

Use MongoDB Compass with the instance connection string:

InstanceConnection String
Mainmongodb://user:pass@localhost:27017/?authSource=admin&directConnection=true
Instance 1mongodb://user:pass@localhost:27117/?authSource=admin&directConnection=true
Instance 2mongodb://user:pass@localhost:27217/?authSource=admin&directConnection=true

Dev Tunnels ​

Each instance gets a pre-configured frpc.toml with tunnel proxies for the frontend and API. Subdomains follow the pattern {user}-i{N}:

InstanceFrontend TunnelAPI Tunnel
Instance 1https://yourname-i1.dev.review-time.infohttps://yourname-i1-api.dev.review-time.info
Instance 2https://yourname-i2.dev.review-time.infohttps://yourname-i2-api.dev.review-time.info

Start the tunnel from the instance directory:

bash
cd ../tell-ia-instance-1
frpc -c frpc.toml

The dev name defaults to $USER. Override it with the DEV_NAME env var:

bash
DEV_NAME=alex ./scripts/create-instance.sh 1

See Dev Tunnels for setup instructions (frpc install, FRP_TOKEN).

Check Instance Ports ​

View the ports assigned to an instance:

bash
cat ../tell-ia-instance-1/apps/agri-backend/.env.compose

Switching Branches Inside an Instance ​

A worktree is a regular git checkout. You can switch to any branch from within it:

bash
cd ../tell-ia-instance-1
git switch some-other-branch

WARNING

Two worktrees can't have the same branch checked out at the same time. Git will block you if you try to switch to a branch that's already checked out in another worktree (including the main repo).

Remove an Instance ​

From the main repo root:

bash
# Keep database data (Docker volumes preserved)
./scripts/remove-instance.sh 1

# Also delete database data
./scripts/remove-instance.sh 1 --volumes

This stops Docker services, removes the git worktree, and deletes the branch.