Purgatory architecture
Traefik v3.6 routes requests; Sablier measures idle time and puts a sandbox to sleep. Purgatory creates sandboxes, wakes every sleeping one (within the owner's limits), takes long-asleep ones into deep sleep, and archives them on an explicit delete. A running sandbox's web traffic does not go through Purgatory. Nothing is ever deleted automatically.
1. Components and the path of a request
frps-<name> router to <name>-socat:8080 (by name, not by container address) → frps → tunnel → frpc → the app; Purgatory is not on that path, so running apps keep working while it is down. The router lives on the socat container without allownonrunning: while the sandbox sleeps there is no router, and the request falls to the p7y-wake catch-all, where Purgatory decides whether it may wake. The Sablier middleware on the router only renews the idle session; Sablier stops the group once it has had no traffic for idle_timeout. TLS TCP addresses (*-tcp) and Docker access (*-docker, TLS passed through to the sandbox's own dockerd) go through Purgatory's TCP gateway, which also wakes the sandbox. The registry asks Purgatory for tokens and tells it about every push, which Purgatory scans for secrets.2. The lifecycle of a sandbox
SANDBOX_QUOTA, default 3): letting one sleep frees its place. Asleep ones still hold a Docker network, so the server-wide SANDBOX_MAX_TOTAL (default 200) counts running and asleep ones. At the running limit nothing is put to sleep automatically: the wake is refused, and the owner can choose a running sandbox to put to sleep instead. Only an explicit DELETE archives a sandbox, from any state.3. What happens to an incoming request?
compose start) or a deep-sleeping one (compose up) when the owner has a running place free, shows a waiting page until the router is back, and at the limit answers Running limit reached with a link where the owner can choose what sleeps (the page does not name the owner's other sandboxes). A sandbox Purgatory has just started also gets the waiting page until Traefik picks up its router.Known weak spots
- Waking needs Purgatory: while Purgatory is down, running sandboxes keep serving web traffic, but no sandbox can be woken, and TLS TCP addresses and Docker access (through its TCP gateway) do not work.
- Restart policy: after a wake, only inner containers with
restart: unless-stoppedoralwaysstart again (an accepted, documented trade-off). - Activity: web requests and open Docker connections keep a sandbox awake; a TLS TCP connection alone (e.g. a database client) does not, and drops when the sandbox sleeps.
- Isolation: the default
dindruntime is privileged; root inside a sandbox can reach the host.sysboxruns without it and is used in production; both share the host's kernel, and a Kata runtime (a VM per sandbox) is on the roadmap. - Archive size: the archive of a fresh sandbox is about 200 MB, and archives are never pruned automatically. DELETE is synchronous and can take minutes with a large volume.
- Network limit: every running or asleep sandbox holds a Docker network;
SANDBOX_MAX_TOTAL(default 200) keeps users within the daemon's address pools. Widendefault-address-poolsfor more.