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:
- Database backup: Export your entire PostgreSQL database
- Storage backup: Your files in Supabase Storage aren't included in database dumps
- Configuration backup: Save your
.envfile and any customdocker-compose.ymlmodifications
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 unusedplv8- JavaScript procedural languagetimescaledb- 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_partmanrelease 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:
- Watch the GitHub repository: Star and watch
supabase/supabasefor release notifications - Follow the changelog: supabase.com/changelog lists all updates
- Join GitHub Discussions: The self-hosting discussion thread is where the community shares experiences
- 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:
- Always backup before upgrading
- Understand whether you're doing a minor update or major version migration
- Test in a staging environment first
- 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.
