Self-host Supabase with Postgres, Auth, and Storage
Supabase is an open-source alternative to Firebase that provides a Postgres database, authentication, instant APIs, storage, and a real-time engine. Self-hosting gives you full control over your data and infrastructure.
This guide covers deploying the Supabase stack on Railway as multiple services in a single project.
What you will deploy
The Supabase stack consists of several services:
- Postgres stores all application data and user accounts.
- GoTrue handles authentication (sign-up, sign-in, OAuth, magic links).
- PostgREST generates a REST API from your Postgres schema automatically.
- Storage API handles file uploads and serves files from an S3-compatible backend.
- Studio is the browser-based dashboard for managing your project.
- Kong or API Gateway routes requests to the correct service.
All services run in one Railway project and communicate over private networking.
One-click deploy from a template
Railway has a community Supabase template that provisions the full stack:
This sets up all required services and wires them together. After deploying, generate domains for the API gateway and Studio services.
It is recommended to eject from the template to get a copy of the configuration on your own GitHub account.
If you prefer to understand the architecture or customize the setup, continue reading.
Architecture
The Supabase stack routes all client requests through an API gateway (Kong or a custom router). The gateway forwards requests to the appropriate service based on the URL path:
| Path | Service | Purpose |
|---|---|---|
/auth/v1/* | GoTrue | Authentication endpoints |
/rest/v1/* | PostgREST | Auto-generated REST API |
/storage/v1/* | Storage API | File upload and download |
/realtime/v1/* | Realtime | WebSocket subscriptions |
Each service connects to Postgres over private networking. The API gateway is the only service that needs a public domain.
JWT configuration
All Supabase services authenticate requests using JWTs signed with a shared secret. You need two keys:
anonkey: a JWT with theanonrole. Used by the client library for unauthenticated requests. Safe to expose in frontend code.service_rolekey: a JWT with theservice_rolerole. Bypasses Row Level Security. Must be kept server-side only.
Generate these keys using the JWT secret you configure on all services. Use Supabase's key generation guide to create them.
Set the following variables on all Supabase services:
Connecting from a frontend
Install the Supabase client library:
Initialize the client pointing to your self-hosted instance:
Replace the URL with the public domain of your API gateway service. The anon key is safe to include in frontend code as it respects Row Level Security policies.
Authentication
Querying data
File uploads
Storage backend
The Supabase Storage API needs an S3-compatible backend. Create a Railway Storage Bucket and configure the Storage API service with the bucket credentials:
Securing Studio
The Studio dashboard provides full access to your database, auth configuration, and storage. Do not expose it publicly without authentication.
Options:
- Do not generate a public domain for Studio. Access it only through Railway's private networking or a VPN.
- Add basic auth using a reverse proxy (Caddy or Nginx) in front of Studio.
- Restrict access by IP if your team uses a fixed IP range.
Common pitfalls
Service startup order. GoTrue and PostgREST require Postgres to be running and have the required schemas. On initial deploy, these services may restart once or twice while Postgres initializes. Railway's restart policy handles this automatically.
JWT key mismatch. If the JWT_SECRET differs between services, authentication fails silently. Ensure all services share the same secret using reference variables.
Realtime not connecting. The Realtime service uses WebSockets. Ensure the API gateway forwards WebSocket upgrade requests to the Realtime service. See Choose between SSE and WebSockets for Railway's WebSocket support details.
Next steps
- Storage Buckets - Configure S3-compatible storage for Supabase.
- Private Networking - How services communicate internally.
- Add authentication to a frontend - Patterns for using Supabase Auth in your app.
- Manage environment variables - Handle anon keys vs service role keys.