Sandbox
Deploy a container image and get a URL. It runs when a request arrives or when something happens in your game, and costs nothing in between.
Sandbox runs your container image. You deploy it, you get an address, and from then on it runs when something needs it: a request arriving at that address, or something happening in one of your games — a player joining a server, a server finishing its start. When nothing needs it, nothing is running and nothing is charged.
https://-7f3a91..plany.runIt is the place for the pieces of a game that are not the game server: a matchmaker, a webhook receiver, a backend for your game client, a Discord bot, or the code that should run every time somebody joins.
Create a sandbox, deploy new revisions, roll back, attach secrets.
Run your code when a player joins, leaves, or a server starts or stops.
From zero to as many instances as the traffic needs, and back.
Where the images a sandbox runs live.
What you get
- An address that never changes. A sandbox's URL is assigned when you create it and stays the same through every deploy, every rollback and every time it scales to zero — so you can write it into a client before the first deploy has finished.
- Scale from zero. A request that arrives while nothing is running is held, an instance starts, and the request is answered — it looks like a slow response rather than a failure, typically a few seconds. More traffic starts more instances, up to a ceiling you set.
- Events from your games. A trigger delivers something that happened on one of your game servers to your sandbox as an HTTP request. You write the code that runs when a player joins; you do not write, host or pay for the thing that was listening for it.
- Deploys you can take back. Every deploy is a revision with its image pinned to the exact bytes you pushed. A deploy that fails leaves the previous one serving, and rolling back is choosing an earlier revision.
- Credentials without pasting them. Secrets are attached by name and read by the container when it starts. A rotation reaches the next instance with nothing to redeploy.
- Your private network, outbound. A sandbox can be connected to one of your networks to reach a database or a game server's admin port there. Nothing on that network can connect back to it.
The parts
| Sandbox | The name, the URL, how it scales and who can reach it. projects/{project}/locations/{location}/sandboxes/{sandbox} |
| Revision | One deploy: the image (pinned to a digest), its command, environment, secrets and size. Immutable. |
| Instance | A running copy of the serving revision. Zero or more, decided by traffic. |
| Trigger | A game event delivered to the sandbox as a request. |
A sandbox is regional: its image, its instances and its URL are in one region. A service you want in two regions is a sandbox in each.
Images
A sandbox runs an image from a repository in Plany's Container
Registry, at .plany.cr, in the same
project and region as the sandbox. Push it with docker push as you would to any
registry, then deploy it by repository and tag:
docker push .plany.cr//api:v1plany sandbox sandboxes create api --image api:v1 --vcpus 1 --memory 512MiBThe sandbox is given permission to pull from that repository on its own; there is
nothing to configure. Images must be built for linux/amd64.
Who can reach it
| Public (the default) | Reachable at its URL by anybody on the internet, over HTTPS. Plany does not authenticate the caller — a webhook sender or a game client cannot present a Plany credential — so check whatever your service needs to check in your own code. |
| Internal | No URL at all. Only triggers reach it. The right choice for code that only ever reacts to your games. |
The container itself speaks plain HTTP/1.1, or HTTP/2 without TLS for a gRPC server. Plany handles TLS and the certificate; callers always connect over HTTPS.
Logs
Everything your container writes to standard output and standard error is kept under the sandbox's name, from every instance, including ones that have since been stopped. Read it on the sandbox's Logs tab in the console, or:
plany sandbox sandboxes logs api --contains errorPricing
You pay for instances while they run, and for requests. A sandbox with nothing running costs nothing.
| Price | |
|---|---|
vCPU (sandbox-vcpu-hour) | $0.016 per vCPU-hour |
Memory (sandbox-gib-hour) | $0.007 per GiB-hour |
Local storage (sandbox-local-storage-gib-hour) | $0.00014 per GiB-hour |
Requests (sandbox-requests) | $0.40 per million, with the first 2 million each month free |
Compute is charged for the CPU an instance reserves and the memory it has, only while the instance is running. A trigger delivery counts as one request. Preparing a new revision is not charged.
Setting min_instances above zero keeps instances running with no traffic, and
those are charged continuously, like any always-on service.
It all draws on your account's prepaid credit, and creating or deploying a sandbox is refused when there is none.
Limits
| Quota | Hobby | Pro |
|---|---|---|
| Sandboxes per project per region | 5 | 100 |
| Sandbox instances per project per region | 10 | 200 |
Sandbox instances is counted against the max_instances every sandbox
declares, summed across the project — not against what happens to be running. So
a sandbox's ceiling is checked when you set it, rather than discovered during a
traffic spike. Either quota can be raised; see Quotas.