Sandboxes & Docker
Every pgpg scenario runs against a real PostgreSQL server — not a mock, not a shared instance. Each sandbox is a fresh, fully isolated Docker container with its own throwaway database, so you can break things freely and nothing leaks between scenarios or out to production.
One container per scenario
When you start a scenario, pgpg launches a dedicated PostgreSQL container just for that run. There is no shared state: each sandbox gets its own data directory, its own port, and its own connection string. Anything you do — dropping tables, holding locks, filling disk — stays inside that container.
pgpg> start stage-01/01-missing-index
Sandbox booting...
Sandbox ready at postgres://postgres:postgres@127.0.0.1:55432/app_db
Lifecycle
A sandbox moves through three states, each driven by a REPL command:
start <id>— boots a fresh PostgreSQL container, injects the scenario's fault, and prints the connection string.reset— restores the sandbox to its initial broken state. The fault is re-injected and the connection string stays valid. Use this whenever your investigation leaves the database in a confusing state.stop— tears the sandbox down and frees its resources.
pgpg[stage-01/01-missing-index]> reset
Sandbox restored to initial state.
pgpg[stage-01/01-missing-index]> stop
Sandbox stopped.
Connecting
Each sandbox prints a standard connection string you can use with psql, a GUI client, or your own scripts:
psql postgres://postgres:postgres@127.0.0.1:55432/app_db
The host is always loopback (127.0.0.1) and the credentials are fixed at postgres / postgres. Only the port varies between runs.
Ports
pgpg exposes each sandbox on a local TCP port chosen from a configurable range. This lets multiple sandboxes coexist and avoids clashing with any PostgreSQL you already run locally. See Configuration to adjust the range with [sandbox] port_range.
PostgreSQL image and version
The sandbox uses a real PostgreSQL Docker image. Both the image and version are configurable, so you can pin the exact major version you run in production and reproduce version-specific behavior. Configure these under [postgres] image and [postgres] version.
Cleanup
When you stop a scenario, pgpg removes the container and its volume. If a sandbox is ever left behind — for example after a crash — pgpg cleans up stopped containers it owns on the next start. You can also remove orphaned containers manually; see Troubleshooting.
Nothing touches production
Because every sandbox is a disposable, locally-bound Docker container with a throwaway database, pgpg never connects to your real systems. There is no path from a scenario to a production database. Break whatever you need to — reset brings it back, and stop removes it entirely.