Overview
Run a Floot backend on your own server from Supabase's official Docker setup: what differs from Cloud, the request path, and where each topic lives.
This group takes you from Supabase's official Docker setup to a production
backend for a Floot app. Each topic states what any self-hosted stack needs
first, then shows how Floot runs its own backend, api.floot.dev, as a worked
example: its Caddy site, its compose overrides, its backup recipe. The facts
were gathered on the self-hosted release self-hosted/v0.8.2 (Postgres 17,
the Envoy gateway); check them again when you pin a newer one.
Read Going to production first: its four rules apply here unchanged. Self-hosting means you own everything Supabase Cloud does for you, from TLS to backups; if you have no reason to run your own server, Supabase Cloud is the shorter path.
The examples use api.myapp.com for your backend and app.myapp.com for your
web app.
What differs from Cloud
| Topic | Supabase Cloud | Self-hosted |
|---|---|---|
| Settings | The dashboard | Environment variables on each service; nothing reads supabase/config.toml |
| Exposed schemas | Data API → Settings | PGRST_DB_SCHEMAS and PGRST_DB_EXTRA_SEARCH_PATH |
| Deploying functions | supabase functions deploy | Copy the files, then recreate the functions container |
| Function secrets | Set on the project, live without a redeploy | Environment on the functions service, applied by recreating it |
| JWT check on functions | Per function, from verify_jwt in config.toml | One switch for every function, off; each function checks its caller in code |
| Send Email hook | The dashboard | GOTRUE_HOOK_SEND_EMAIL_* on auth, with an https:// URI |
| Migrations | db push to the linked project | db push --db-url over an SSH tunnel, once Realtime is healthy |
| Vault rows | db query --linked | psql |
| Database Webhooks | Enable webhooks in the dashboard | Nothing to do: the stack's init script creates supabase_functions |
| Per-IP auth rate limits | Built in | Off until you set GOTRUE_RATE_LIMIT_HEADER and your proxy sends that header |
| TLS, proxy, firewall | Supabase's | Yours |
| Backups | On paid plans | Yours; the stack ships none |
| Upgrades | Supabase's | Yours, pinned to a release tag |
| Outgoing mail ports | 25 and 587 blocked, use 465 | Whatever your host allows; many block 25 and 465 |
The request path
Only the API is public. Clients reach it through your TLS proxy, which forwards the API paths and nothing else; Studio and Postgres stay on the server's loopback, reached from your laptop through an SSH tunnel. Exposure sets out the rules behind each box.
In this group
Start with the step-by-step guide; the other pages are the reference behind its steps.
- Step by step: from an empty Ubuntu server to a production backend, one checked step at a time, in the shape of Floot's own: SSH and the firewall, Docker, Caddy, the stack with your app's files, the first deploy, a reboot, backups and the smoke check, then your web app as a second site beside the API.
- Shipping a release: the first start, migrations over the tunnel, reference data, the Vault rows, deploying the functions, Floot's release order and the smoke check.
- Exposure: the paths your proxy forwards,
the proxy rules, Docker bypassing
ufw, the tunnel, Cloudflare, and Storage behind a CDN. - Configuration: the stack and your own
compose file, the
config.tomlto environment mapping, function secrets, the JWT switch and the Send Email hook. - Backups: what holds state, Floot's recipe, and restoring onto a new server.
- Watching: optional, Uptime Kuma beside Caddy, sending a Telegram message when the API, the certificate, the backups or the disk need you.
- Upgrades: moving to a newer release tag on purpose.
Supabase Cloud
Take a Floot backend from nothing to a working Supabase Cloud project: link, secrets, functions, migrations, Vault, webhooks, auth and mail.
Step by step
From an empty Ubuntu server to a production Floot backend, one checked step at a time: SSH, firewall, Docker, Caddy, Supabase's stack with your app's files, the first deploy, a reboot, backups and the smoke check, then your web app as a second site.