The problem
Your API and your web app both need the development database, and so does every extra instance you spin up for an agent. Giving each its own Postgres means as many containers, migrations and seeds as instances, and data that differs between them.
A service with scope = "global" is created once per config root and shared by every sandbox that lists it.
Config
devsandboxes.toml
[services.postgres]
image = "postgres:16"
scope = "global" # one container for the whole config root
env = { POSTGRES_PASSWORD = "postgres" }
ports = ["127.0.0.1:5432:5432"] # optional: reach it from the host too
[template.base]
image = "node:22"
services = ["postgres"]
# The hostname is the service's name.
containerEnv = { DATABASE_URL = "postgres://postgres:postgres@postgres:5432/postgres" }
[sandbox.api]
extends = "base"
folder = "../api"
[sandbox.web]
extends = "base"
folder = "../web"Try it
TERMINAL
devsandbox run api # starts postgres, then api
devsandbox run web # joins the running postgres
devsandbox run api --name fix-login # its own worktree, same database
devsandbox service ls # one global postgres--name: the instance name.
Check an instance resolves the service, and connect from the host:
TERMINAL
devsandbox exec fix-login getent hosts postgres
psql postgres://postgres:postgres@127.0.0.1:5432/postgresHow it works
- Every instance that lists the service joins its network and reaches it by name (services).
stopandrmleave it running for the others;devsandbox gcremoves it once no running instance uses it.devsandbox service rebuild postgresapplies config changes and rewires running sandboxes in place (drift).- The data lives in the service container:
service rebuildandgcstart it empty, so keep a way to re-seed.
Agent instructions
Give my devsandbox sandboxes one shared Postgres database that every sandbox and every instance connects to.
- Read the devsandbox-cli and config-toml-spec skills first (load them if they are installed, otherwise read them from https://github.com/Nemikolh/devsandboxes/tree/main/skills). Follow them over your own assumptions: unknown config keys are hard errors.
- Find my devsandbox config dir: the folder holding devsandboxes.toml, passed to devsandbox as
-C <config dir>. If you cannot tell which one, ask me. - Add
[services.postgres]withimage = "postgres:<postgres version>"(the version the repo targets),scope = "global"andenv = { POSTGRES_PASSWORD = "<password>" }. Addports = ["127.0.0.1:5432:5432"]only if I want to reach it from the host and that port is free. - Add "postgres" to
servicesof a template every sandbox extends, withcontainerEnvpointing the app at hostpostgresunder the variable name the repo already reads, e.g.DATABASE_URL = "postgres://postgres:<password>@postgres:5432/postgres". - Validate with
devsandbox -C <config dir> lsand fix every error it reports before going on. - Start the sandboxes with
devsandbox -C <config dir> run <sandbox>and checkdevsandbox -C <config dir> service lsshows a single global postgres. - Check
devsandbox -C <config dir> exec <instance> getent hosts postgresresolves, then run the repo's migrations in that instance. - Ask me before anything destructive: devsandbox rm, gc, rebuild --force, service rebuild, deleting files or branches.
<…> fill in before sending Agent skills (opens in a new tab)
Source: site/src/content/examples/shared-postgres.mdxEdit this page on GitHub(opens in a new tab)