22 October 2026 · 5 min read · BlitzHash Team · Supabase
What self-hosting Supabase actually includes
Supabase Cloud and a self-hosted Supabase stack can expose the same style of API. They do not carry the same work. Cloud is a managed platform. Self-hosting means the containers, the database, the TLS certificate, the firewall, and the backups live in an account you control. That is the point of the move, and it is also the part teams underestimate.
Self-Hosted Supabase is the fixed-scope setup we run when a team wants that control. This note is the boundary of the job, so a proposal does not pretend the server maintains itself.
One project on a server you control
The Docker setup is a single Supabase project. You get Postgres, the API gateway, Auth, Storage, Realtime, and Studio. You do not get a silent extra environment. Staging is a decision. It can be a second, smaller stack, or it can be a separate Cloud project used only for experiments. It should not be the same database your customers write to.
Pick the region before the first migration. Moving a live database later is a project of its own. Size the disk for the data you have and the backups you intend to keep on that machine. A volume that fills up at 2 a.m. takes the API down with it.
The application still needs somewhere to run. Supabase is the backend. The Next.js or other front end usually sits on its own host, with environment variables that point at this project. We keep those hosts in accounts you own. We do not hide them behind an account only we can open.
Backups are yours, including the restore
A dump schedule is not a backup until someone has restored it. On a self-hosted project that responsibility sits with the operator. The practical version is a daily dump, copies stored off the same disk, and a written restore that has been tried.
The restore test should answer plain questions. Where is the latest good copy? Which command loads it? How long did it take? Can you sign in to an app pointed at the restored database and see a row you expect? Write the answers in the runbook. A future engineer, including a future you, will not remember the flags.
Point-in-time recovery is possible with Postgres tooling, and it is more moving parts than a nightly dump. Use it when the product cannot lose a day of writes. Say so in the scope. Do not assume the default compose file invented it for you.
Managed Supabase includes its own backup story, with the platform's limits and controls. Self-hosting trades that for a server you can inspect. Neither choice removes the need to try a restore before you trust it.
Updates, keys, and hardening
Containers age. Postgres ages. Auth services ship fixes. Someone has to apply updates on purpose, in a window, with a backup taken first and a way back if the API does not return.
Hardening is the unglamorous list. TLS on the public names. A firewall that exposes only the ports the app needs. SSH limited to keys, not passwords shared in chat. Studio not left open to the whole internet with a default password. Database passwords and JWT secrets generated for this project and stored in a password manager the company controls. Service-role keys kept on the server. The anon key is the one client apps may hold, and only behind Row Level Security that you have tested with a second user.
Logs need a home. If the only copy is on the server that just filled its disk, you will not have them when you need them. Ship them somewhere you can read, and decide who is allowed to read customer data inside them.
We document this in the handover. Ongoing updates can stay with your team, or they can move to Managed Infrastructure Care as a monthly engagement. The setup project does not silently become an endless retainer.
SMTP and Auth email
Sign-up mail is part of the product. The default mail path is for getting started. Production should send through SMTP you control, from a domain you control, with the DNS records that mail providers expect. Test confirmation, password reset, and an invite if you use one. Open the message on a phone. The link must return to the URL your users actually use, not to localhost and not to a hostname that only existed during setup.
Auth settings deserve a pass at the same time. Site URL, redirect allow-list, and the session length you are willing to live with. If you turn on a new provider later, add its callback to the allow-list on purpose.
Studio is an admin tool
Studio is how you inspect tables, run SQL, and edit auth settings. Treat it as an admin console. Put it behind a hostname you intend, with a password that is not the example from a tutorial, and with access limited to the people who administer the project. A Studio left on a public port is a second database password taped to the server.
Use Studio to confirm RLS, not to bypass it out of habit. The service-role key skips policies. That is useful for migrations and dangerous as a daily client. Application code that only needs a user's own rows should use the user session.
What this does not include
Self-hosting does not include your front end, your payment provider, or a redesign. It does not include a promise that the server can never go down. It does not move data by magic. If you are leaving Supabase Cloud or a builder's hosted database, the migration is a scoped piece of work: a copy, a check, a cutover window, and a rollback plan.
It also does not set a universal size. Disk, CPU, and bandwidth follow the workload we see on the call. The quote comes after that look, in USD, in writing. There is no menu of box prices on this site because the honest number depends on the project.
Some products should stay on Supabase Cloud. If you want managed backups, a console you do not patch, and you are fine with the platform's limits, Cloud is the simpler system. We will say so. Self-hosting is for teams that want the database and the keys in their own account and are ready to own the operations, either themselves or with a care plan.
How to decide
Bring the workload, the region you need, and whether you already have a server. We will tell you if Cloud is the better fit. If it is not, the written scope names the stack, the restore test, the mail path, and the runbook. You accept that scope before any build starts. The server, the DNS, and the repository stay yours when the project ends.
