Creates or updates a Supabase instance on an SSH host.
This action sets up a self-hosted Supabase instance on a remote server, including:
- Database configuration
- SSL certificates
- Nginx reverse proxy
- Migration application
- Serverless function deployment
- Email testing with Inbucket
- A server with:
- Ubuntu/Debian-based OS
- Docker installed
- Node.js and npm installed (will attempt to install if missing)
- Nginx (will attempt to install if missing)
- Port 80/443 available for SSL certificate validation
- Sufficient permissions to run Docker containers
- DNS records pointing to your server for:
api.yourdomain.com
graphql.yourdomain.com
storage.yourdomain.com
studio.yourdomain.com
inbucket.yourdomain.com
- SSH access to the server via SSH keys
When running Supabase locally, different services communicate with each other using different ports on localhost:
- REST API (PostgREST): port 3000
- GraphQL API (pg_graphql): port 5300
- Storage API: port 5000
- Studio UI: port 3000
- Inbucket (email testing): port 9000
In production, we use separate subdomains instead of ports for several reasons:
- Security: Allows proper HTTPS (TLS/SSL) encryption for all services
- Simplicity: Uses standard web ports (443 for HTTPS) instead of remembering custom port numbers
- Compatibility: Some networks block non-standard ports, but rarely block standard HTTPS
- Authentication: Enables proper cookie-based auth across services
- Scalability: Makes it easier to scale individual services independently
The Nginx reverse proxy manages routing requests to the appropriate internal services based on the hostname.
Domain | Service | Description |
---|---|---|
api.yourdomain.com |
PostgREST | REST API for database access |
graphql.yourdomain.com |
pg_graphql | GraphQL API interface |
storage.yourdomain.com |
Storage API | File storage and retrieval |
studio.yourdomain.com |
Supabase Studio | Admin dashboard interface |
inbucket.yourdomain.com |
Inbucket | Email testing service |
name: Deploy Supabase Instance
on:
push:
branches: [ main ]
paths:
- 'src/supabase/**'
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Supabase Instance
uses: supabase-helper/setup-instance@v1
with:
target-host: 'your-server.example.com'
target-username: 'ubuntu'
target-ssh-key: ${{ secrets.SSH_PRIVATE_KEY }}
base-domain: 'your-domain.com'
acme-email: '[email protected]'
source-path: './src/supabase'
# Optional: Use custom ACME server for SSL certificates
acme-server: 'https://acme.your-domain.com/directory'
# Optional: Skip SSL setup (default: false)
acme-skip: 'false'
Input | Description | Required | Default |
---|---|---|---|
host |
SSH host to deploy to | Yes | - |
username |
SSH username | Yes | - |
ssh-private-key |
SSH private key for authentication | Yes | - |
domain |
Domain name for Supabase endpoints | Yes | - |
email |
Email for SSL certificate registration | Yes | - |
source-path |
Path to Supabase files | Yes | './src/supabase' |
acme-server |
Custom ACME server URL | No | Let's Encrypt |
skip-ssl |
Skip SSL certificate creation | No | 'false' |
Your project should have a Supabase directory (default: src/supabase
) with:
src/supabase/
├── functions/ # Edge functions
│ ├── function-1/
│ │ └── index.ts
│ └── function-2/
│ └── index.ts
├── migrations/ # Database migrations
│ ├── 0001_initial.sql
│ └── 0002_updates.sql
└── seeds/ # Database seed files
└── initial_data.sql
Store your SSH private key as a GitHub secret:
- Go to your repository settings
- Navigate to Secrets and Variables > Actions
- Add a new secret named
SSH_PRIVATE_KEY
- Paste your SSH private key
The action will generate CSPRNG secure credentials for:
- PostgreSQL database
- JWT tokens (
ANON
andSERVICE_ROLE
) - Studio admin interface
These can be found in the .env
file on your server at /opt/supabase/.env
To view an example of this action in use, see deploy-environments.yml
MIT License - see LICENSE file for details