Upgrading Self-Hosted Supabase: A Complete Version Migration Guide

Learn how to safely upgrade your self-hosted Supabase instance, including PostgreSQL 17 migration, with step-by-step instructions.

Cover Image for Upgrading Self-Hosted Supabase: A Complete Version Migration Guide

One of the most common pain points in the self-hosted Supabase community isn't deployment—it's what happens six months later when you need to upgrade. Unlike Supabase Cloud, which handles updates automatically, self-hosted users face a maze of Docker image changes, database migrations, and breaking changes with limited official documentation.

This guide walks through the complete process of upgrading your self-hosted Supabase instance, including the major PostgreSQL 15 to 17 migration that affects many deployments in 2026.

Why Upgrading Self-Hosted Supabase Is Tricky

If you've successfully deployed Supabase on your own server, you might assume updates work like any other Docker-based application: pull new images, restart containers, done.

The reality is more complex:

  • Database migrations don't auto-run: Unlike initial deployment, subsequent updates don't automatically execute migration scripts on existing data
  • Service interdependencies: Supabase consists of 10+ interconnected services that need coordinated upgrades
  • PostgreSQL major version changes: Moving between major Postgres versions requires data export/import, not just container restarts
  • Breaking API changes: New versions occasionally introduce changes that affect your application code

The GitHub issue tracker is full of developers asking "How do I upgrade my self-hosted project?" with no straightforward answer. Supabase has been investing more in self-hosting support lately—including dedicating team members to the experience—but comprehensive upgrade documentation remains a gap.

Before You Begin: Prerequisites

Backup Everything

This cannot be overstated. Before any upgrade:

  1. Database backup: Export your entire PostgreSQL database
  2. Storage backup: Your files in Supabase Storage aren't included in database dumps
  3. Configuration backup: Save your .env file and any custom docker-compose.yml modifications

If you're using Supascale's automated backup system, you already have this covered. Otherwise, run these commands manually:

# Database backup
docker exec supabase-db pg_dump -U postgres -F c -b -v -f /tmp/backup.dump

# Copy backup to host
docker cp supabase-db:/tmp/backup.dump ./backup-$(date +%Y%m%d).dump

# Storage backup (if using local volumes)
tar -czvf storage-backup-$(date +%Y%m%d).tar.gz ./volumes/storage

Check Your Current Version

Identify what you're working with:

# Check Docker image versions
docker compose ps

# Check PostgreSQL version
docker exec supabase-db psql -U postgres -c "SELECT version();"

# Check Supabase API version
curl -s http://localhost:8000/rest/v1/ | head -5

Document these versions—you'll need them if something goes wrong.

Scenario 1: Minor Version Updates (Same PostgreSQL Major Version)

For updates within the same PostgreSQL major version (e.g., 15.4 to 15.8), the process is relatively straightforward.

Step 1: Stop Your Stack

cd /path/to/supabase
docker compose down

Step 2: Pull the Latest Supabase Repository

# Backup your customizations first
cp docker-compose.yml docker-compose.yml.backup
cp .env .env.backup

# Pull latest changes
git pull origin master

Step 3: Update Docker Images

docker compose pull

Step 4: Merge Configuration Changes

Compare your backup files with the new versions. Look for:

  • New environment variables
  • Changed default values
  • New services added to docker-compose.yml
diff .env.backup .env.example
diff docker-compose.yml.backup docker-compose.yml

Step 5: Restart with New Images

docker compose up -d

Step 6: Verify the Upgrade

# Check all services are running
docker compose ps

# Test the API
curl http://localhost:8000/rest/v1/

# Check Studio access
curl -I http://localhost:3000

Scenario 2: PostgreSQL Major Version Upgrade (15 to 17)

The 2026 PostgreSQL 17 transition is a bigger undertaking. Existing Supabase projects on PostgreSQL 15 will reach end-of-life support around May 2026, making this upgrade essential for continued security patches.

Breaking Changes to Prepare For

Before upgrading, address these breaking changes:

Deprecated Extensions:

  • pgjwt - Was enabled by default, may need removal if unused
  • plv8 - JavaScript procedural language
  • timescaledb - Time-series extension

Check if you're using these:

SELECT extname FROM pg_extension WHERE extname IN ('pgjwt', 'plv8', 'timescaledb');

If you are using them, you'll need to either:

  • Migrate to alternative solutions
  • Stay on PostgreSQL 15 until you can migrate
  • Wait for Supabase's planned pg_partman release as a TimescaleDB alternative

The Upgrade Process

PostgreSQL major version upgrades require a dump and restore approach because data directory formats aren't compatible between versions.

Step 1: Export Your Schema and Data

Customize the dump to export only what you need:

# Export the public schema (your application data)
docker exec supabase-db pg_dump -U postgres \
  --schema=public \
  --no-owner \
  --no-privileges \
  --format=custom \
  -f /tmp/public_schema.dump

# Export auth schema (users, sessions)
docker exec supabase-db pg_dump -U postgres \
  --schema=auth \
  --no-owner \
  --no-privileges \
  --format=custom \
  -f /tmp/auth_schema.dump

# Export storage schema (file metadata)
docker exec supabase-db pg_dump -U postgres \
  --schema=storage \
  --no-owner \
  --no-privileges \
  --format=custom \
  -f /tmp/storage_schema.dump

# Copy to host
docker cp supabase-db:/tmp/public_schema.dump .
docker cp supabase-db:/tmp/auth_schema.dump .
docker cp supabase-db:/tmp/storage_schema.dump .

Step 2: Stop and Remove Old Containers

docker compose down -v

The -v flag removes volumes—this is intentional since PostgreSQL 15 data directories aren't compatible with version 17.

Step 3: Update to PostgreSQL 17 Images

Edit your docker-compose.yml:

services:
  db:
    image: supabase/postgres:17.4.1.072
    # ... rest of configuration

Step 4: Start Fresh Database

docker compose up -d db

# Wait for database initialization
sleep 30

Step 5: Restore Your Data

# Copy dump files back
docker cp public_schema.dump supabase-db:/tmp/
docker cp auth_schema.dump supabase-db:/tmp/
docker cp storage_schema.dump supabase-db:/tmp/

# Restore in order
docker exec supabase-db pg_restore -U postgres \
  -d postgres \
  --no-owner \
  --no-privileges \
  /tmp/auth_schema.dump

docker exec supabase-db pg_restore -U postgres \
  -d postgres \
  --no-owner \
  --no-privileges \
  /tmp/storage_schema.dump

docker exec supabase-db pg_restore -U postgres \
  -d postgres \
  --no-owner \
  --no-privileges \
  /tmp/public_schema.dump

Step 6: Start Remaining Services

docker compose up -d

Step 7: Application-Level Validation

Run your application's test suite against the upgraded database. Common issues to check:

  • Authentication flows still work
  • Real-time subscriptions reconnect properly
  • Storage uploads and downloads function
  • Any custom PostgreSQL functions behave as expected

Handling Edge Functions in Self-Hosted Upgrades

If you're running self-hosted Edge Functions, be aware of the 2026 JWT changes. Supabase has transitioned to asymmetric JWT keys (ES256), which can cause verification errors after upgrades.

Check your current JWT key type:

# In your Supabase dashboard, go to Settings > API > JWT Settings
# Verify your key type is 'ECC (P-256)'

If you encounter JWT errors after upgrading, you may need to rotate your keys and update your Edge Function environment variables.

Automation Options

Manual upgrades are tedious and error-prone. Here are alternatives:

Using Supascale for Managed Self-Hosting

Supascale handles the operational complexity of self-hosted Supabase, including:

  • Automated backups before any changes
  • One-click restore if something goes wrong
  • Managed service configuration
  • No ongoing maintenance burden

At a one-time cost of $39.99, it eliminates the 1-2 FTE operational overhead that many teams report spending on self-hosted Supabase maintenance.

CI/CD Pipeline Approach

For teams preferring infrastructure-as-code, you can automate upgrades:

# Example GitHub Actions workflow
name: Supabase Upgrade

on:
  workflow_dispatch:
    inputs:
      target_version:
        description: 'Target Supabase version'
        required: true

jobs:
  upgrade:
    runs-on: ubuntu-latest
    steps:
      - name: Backup database
        run: |
          ssh ${{ secrets.SERVER }} 'docker exec supabase-db pg_dump -U postgres -F c > backup.dump'
          
      - name: Pull new images
        run: |
          ssh ${{ secrets.SERVER }} 'cd /opt/supabase && docker compose pull'
          
      - name: Restart services
        run: |
          ssh ${{ secrets.SERVER }} 'cd /opt/supabase && docker compose up -d'
          
      - name: Health check
        run: |
          sleep 60
          curl -f https://your-supabase-domain.com/rest/v1/ || exit 1

Common Upgrade Issues and Solutions

"Data directory initialized by PostgreSQL version X is not compatible"

You're trying to start a new PostgreSQL major version against an old data directory. You must dump and restore—there's no shortcut.

Services fail to start after upgrade

Check for new required environment variables:

docker compose logs | grep -i "error\|required\|missing"

Compare your .env with the latest .env.example from the Supabase repository.

Real-time subscriptions don't work

The Realtime service may need its configuration updated. Check:

docker compose logs realtime

Ensure your JWT secret matches across all services.

Studio shows blank or errors

Clear your browser cache and check that Kong (the API gateway) is routing correctly:

docker compose logs kong

Staying Informed About Updates

Since self-hosted Supabase doesn't have telemetry, you need to proactively monitor for updates:

  1. Watch the GitHub repository: Star and watch supabase/supabase for release notifications
  2. Follow the changelog: supabase.com/changelog lists all updates
  3. Join GitHub Discussions: The self-hosting discussion thread is where the community shares experiences
  4. Monitor security advisories: Critical patches should be applied promptly

Conclusion

Upgrading self-hosted Supabase requires more care than typical Docker deployments, but it's manageable with proper preparation. The key steps:

  1. Always backup before upgrading
  2. Understand whether you're doing a minor update or major version migration
  3. Test in a staging environment first
  4. Have a rollback plan

For teams who'd rather focus on building their applications than maintaining infrastructure, Supascale offers the cost benefits of self-hosting without the operational overhead. Check out our installation guide to get started.


Further Reading