Deploy it: the poor man’s stack
One small VPS, Docker, Caddy, self-hosted Supabase, and a domain - the whole thing for about the price of two coffees a month, and honest about where it stops scaling.
Checked against the sources on 2026-08-30
What "poor man" buys you
Everything on one small server: the app, the database, auth, realtime, TLS. No managed services, no registry, no CI - you build on the box and restart. This is not the compromise it sounds like: a space holds twelve people, realtime is the hungry part, and one honest VPS carries several busy rooms before anything creaks.
What it deliberately is not: highly available. One box means one box - a reboot is a minute of downtime and a dead disk without backups is the end. The backups step below is therefore not optional, and the guide says so again when it gets there.
The recipe
Rent the box and point a domain at it
Cost: ~€5-8/month for the VPS, ~€10/year for the domain
A small cloud server with 4GB RAM - the Supabase stack is the hungry tenant, and 2GB plus swap works until the day it does not. Any of the budget providers do; pick one with a data centre near your players.
Two DNS A records at your registrar: one for the app (app.example.com or the bare domain) and one for the API (api.example.com), both pointing at the box.
Lock the door before you furnish the room
Takes: Twenty minutes, once
SSH keys only (password login off), a firewall allowing exactly 22, 80 and 443, and automatic security updates. Docker and Docker Compose from the official install script.
Watch out: Do this before installing anything with secrets in it. A database that was public for an afternoon stays leaked forever.
Stand up self-hosted Supabase
Where: The official supabase/docker compose setup
Clone their docker directory, then change every secret before first start: the Postgres password, the JWT secret, and the anon and service keys generated from it. The defaults are publicly known - a stack started with them is open to anybody who read the same README.
Keep Studio and anything administrative off the public ports - reachable through an SSH tunnel or behind auth in the reverse proxy, never bare. Then apply the migrations from the kxb repository against your database.
Build and run the app on the box
The repository ships a Dockerfile; the poor man’s registry is no registry - build the image on the server. One thing must be right at build time, not at run time: the NEXT_PUBLIC_* variables (your Supabase URL and anon key) are baked into the client bundle during the build. Setting them afterwards changes nothing and fails silently.
Run the container with restart unless-stopped, listening only on localhost - the proxy is the one with the public face.
Watch out: NEXT_PUBLIC_* at build time is the classic trap in this whole recipe. If auth mysteriously talks to the wrong host, you rebuilt with the wrong env.
Put Caddy in front
Caddy exists because of setups like this: a few lines mapping your two hostnames to the two local ports, and it fetches and renews the TLS certificates by itself. There is genuinely nothing else to do - no certbot, no cron, no openssl.
Give GoTrue a way to send mail
Signup confirmations need SMTP. A free transactional-mail tier is plenty at this scale - configure its credentials in the Supabase auth service and send a test signup before telling anybody the site exists.
Know the default send limits: self-hosted GoTrue ships conservative rate caps (on the order of tens of mails per hour, with a cooldown per address). Fine for a quiet launch; raise them deliberately when a real crowd arrives, not in a panic while it does.
Backups, then call it deployed
A nightly pg_dump, compressed, copied off the box - a €1 storage box or any object storage does. Test the restore once, on a day you do not need it. Day-two operations are then one loop: pull, rebuild, restart, and the deploy is whatever minute you ran it in.
Before the domain goes anywhere public: the imprint placeholders from the starter guide, and the legal shell chapter. A deployed site is a published site.
Watch out: An untested backup is a hope, not a backup. Restore it once into a scratch database and look at the tables.
The whole bill
| What | Amount |
|---|---|
| VPS, 4GB | €5-8/month |
| Domain | ~€10/year |
| TLS certificatesCaddy and Let’s Encrypt. | €0 |
| Transactional mailFree tier covers a small launch. | €0 |
| Backup storage | ~€1/month |
| TotalThe two-coffees stack. | Under €10/month |
The words in the recipe
- VPS
- The one rented server everything lives on.
- Caddy
- The reverse proxy that does TLS by itself - the poor man’s load balancer.
- Self-hosted Supabase
- The official docker compose of Postgres, auth, realtime and storage.
- GoTrue
- Supabase’s auth service - the part that needs SMTP and has send limits.
- Anon / service key
- The two API keys derived from your JWT secret - one public, one never.
- NEXT_PUBLIC_*
- Env vars baked into the client at build time - the trap of the recipe.
- pg_dump
- The one-command backup that makes the single box survivable.
The traps
- Starting the Supabase stack with its default secrets.
- Setting NEXT_PUBLIC_* at run time and wondering why nothing changed.
- Studio or Postgres reachable from the internet.
- 2GB of RAM and no swap - the OOM killer picks the database at the worst moment.
- No backups until the first loss, or backups nobody ever restored.
- Going public with the imprint placeholders still in place.
Where to check this yourself
- Run kxb yourselfThe local half this guide continues.
- Supabase self-hosting docsThe compose setup and the secrets that must change.
- Caddy docsThe whole proxy config is shorter than this sentence list.
- The kxb repositoryThe Dockerfile and the migrations.
This is a map, not legal or tax advice - and an honest one about how it was drawn: the Germany guide was written by a person who walked the route; most other countries were drafted with AI against the official sources and have not yet been walked by someone who did it. Laws change. Every guide carries the date it was last checked and the sources to check it yourself - and if you have been through one of these routes, your corrections are exactly what this handbook wants.


