Binding Domains

Connect custom domains to your Supabase projects.

Bind custom domains to your Supabase projects for professional URLs and better branding.

Prerequisites

Before binding a domain:

  1. Own the domain - Have access to DNS settings
  2. Point DNS to server - Create A record pointing to your server IP
  3. Wait for propagation - DNS changes can take up to 48 hours

DNS Configuration

A Record

Create an A record pointing your domain to your server:

TypeNameValueTTL
Aapi203.0.113.50300

For api.example.com pointing to server IP 203.0.113.50.

Verify DNS

Check DNS propagation:

# Check A record
dig +short api.example.com

# Should return your server IP
203.0.113.50

Bind Domain via Web UI

  1. Click on a project
  2. Go to Domain tab
  3. Enter your domain name
  4. Select web server (Nginx/Apache/Caddy)
  5. Click Save Domain

Bind Domain via API

curl -X POST https://supascale.example.com/api/v1/projects/my-project/domain \
  -H "X-API-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "api.example.com",
    "sslEnabled": true,
    "webServer": "nginx"
  }'

Response:

{
  "success": true,
  "domain": {
    "name": "api.example.com",
    "sslEnabled": true,
    "webServer": "nginx",
    "status": "active"
  }
}

Web Server Configuration

Supascale automatically generates web server configuration:

Nginx Configuration

Created at /etc/nginx/sites-available/my-project:

server {
    listen 80;
    server_name api.example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name api.example.com;

    ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_cache_bypass $http_upgrade;
    }
}

Apache Configuration

Created at /etc/apache2/sites-available/my-project.conf:

<VirtualHost *:80>
    ServerName api.example.com
    Redirect permanent / https://api.example.com/
</VirtualHost>

<VirtualHost *:443>
    ServerName api.example.com

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/api.example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/api.example.com/privkey.pem

    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:8000/
    ProxyPassReverse / http://127.0.0.1:8000/
</VirtualHost>

Caddy Configuration

Added to /etc/caddy/Caddyfile:

api.example.com {
    reverse_proxy localhost:8000
}

View Domain Configuration

Via API

curl https://supascale.example.com/api/v1/projects/my-project/domain \
  -H "X-API-Key: your-api-key"

Response:

{
  "name": "api.example.com",
  "sslEnabled": true,
  "webServer": "nginx",
  "certificate": {
    "status": "active",
    "expiresAt": "2026-04-19T00:00:00Z"
  }
}

Remove Domain

Via Web UI

  1. Click on a project
  2. Go to Domain tab
  3. Click Remove Domain
  4. Confirm removal

Via API

curl -X DELETE https://supascale.example.com/api/v1/projects/my-project/domain \
  -H "X-API-Key: your-api-key"

Multiple Domains

Currently, each project supports one domain. For multiple domains:

  1. Use a wildcard certificate
  2. Configure additional server blocks manually
  3. Or use a load balancer/CDN in front

Updating Your Application

After binding a domain, update your application configuration:

// Before
const supabase = createClient(
  'http://your-server:8000',
  'your-anon-key'
)

// After
const supabase = createClient(
  'https://api.example.com',
  'your-anon-key'
)

Troubleshooting

Domain Not Resolving

  1. Verify DNS A record exists
  2. Check DNS propagation: dig +short yourdomain.com
  3. Wait for propagation (can take hours)

Web Server Not Responding

  1. Check web server status: systemctl status nginx
  2. Verify configuration: nginx -t
  3. Check logs: /var/log/nginx/error.log

Connection Refused

  1. Verify project is running
  2. Check the proxy port matches project API port
  3. Test locally: curl http://localhost:8000