Skip to main content

Command Palette

Search for a command to run...

Automate Supabase Database Backups Using GitHub Actions

Updated
4 min read
Automate Supabase Database Backups Using GitHub Actions

Backing up a database is one of those things everyone knows they should do…
until something breaks and there’s no backup 😅

If you’re using Supabase, the good news is:
you can fully automate PostgreSQL backups using GitHub Actions + Supabase CLI in just a few minutes.

This setup:

  • Runs automatically

  • Stores backups securely

  • Requires zero manual effort after setup


Why Automate Supabase Backups?

Supabase handles infrastructure well — but your data is still your responsibility.

Automation gives you:

  • ✅ Regular backups (daily / PR / manual)

  • ✅ Versioned SQL dumps

  • ✅ Easy recovery

  • ✅ Peace of mind

⚠️ Important: Always use a private GitHub repository for backups.


What We’re Building

A GitHub Actions workflow that:

  • Uses Supabase CLI

  • Backs up:

    • roles

    • schema

    • data

  • Runs:

    • On push to main

    • On pull requests

    • Daily (cron)

    • Manually

  • Commits backups automatically


Step 1: Get Your Supabase Database URL

Go to your Supabase Dashboard → select your project → click Connect (top-right).

You’ll see multiple connection options.


⚠️ Direct Connection vs Pooler (Important Read)

Initially, I tried using the Direct Connection (port 5432) like this:

postgresql://postgres:[PASSWORD]@db.[project-ref].supabase.co:5432/postgres

But in GitHub Actions, this caused the following error:

pg_dumpall: error: connection to server at "db.xxx.supabase.co" (2406:da18:...)
port 5432 failed: Network is unreachable

Why This Happens

  • Supabase Free projects do not have dedicated IPv4

  • DNS resolves the database host to IPv6

  • GitHub Actions runners (ubuntu-latest) cannot reach Supabase IPv6 on port 5432

  • Result: ❌ backup job fails

You can fix this on paid Supabase plans by forcing IPv4 —
but on the Free tier, the reliable solution is the Connection Pooler.


From the Connect dialog:

  • Choose Connection Pooler

  • Use Transaction mode

  • Port: 6543

Example:

postgresql://postgres.[project-ref]:[PASSWORD]@db.[project-ref].supabase.co:6543/postgres

This works reliably in GitHub Actions and is perfect for backups.


Step 2: Add the Database URL as a GitHub Secret

In your GitHub repository:

  1. Go to Settings → Secrets and variables → Actions

  2. Click New repository secret

  3. Add:

Name: SUPABASE_DB_URL  
Value: <pooler connection string>

Your credentials stay encrypted and never appear in logs.


Step 3: Create the GitHub Actions Workflow

Create the file:

.github/workflows/backup.yml

Paste this:

name: Supabase Backup

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]
  workflow_dispatch:
  schedule:
    - cron: '0 0 * * *' # Daily

jobs:
  run_db_backup:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    env:
      DATABASE_URL: ${{ secrets.SUPABASE_DB_URL }}

    steps:
      - uses: actions/checkout@v3

      - uses: supabase/setup-cli@v1
        with:
          version: latest

      - name: Create backup folder
        run: mkdir -p supabase_backup

      - name: Backup roles
        run: supabase db dump --db-url "$DATABASE_URL" -f supabase_backup/roles.sql --role-only

      - name: Backup schema
        run: supabase db dump --db-url "$DATABASE_URL" -f supabase_backup/schema.sql

      - name: Backup data
        run: supabase db dump --db-url "$DATABASE_URL" -f supabase_backup/data.sql --data-only --use-copy

      - uses: stefanzweifel/git-auto-commit-action@v4
        with:
          commit_message: "Automated Supabase backup"

📁 Note About the supabase_backup Folder

GitHub Actions can create folders during a run, but Git only tracks folders once a file exists.

To avoid confusion on the first run, it’s best to create the folder once.

Quick Options

Option 1: Locally

mkdir supabase_backup
git add supabase_backup
git commit -m "Add supabase backup folder"
git push

Option 2: On GitHub

  • Create a file named:

      supabase_backup/.gitkeep
    
  • Commit it

After this, the workflow will automatically dump backups into the folder.


Where Are the Backups Stored?

After each run, your repo will contain:

supabase_backup/
├── roles.sql
├── schema.sql
└── data.sql

You can pull the repository anytime to access them.


Restoring from Backup (Quick Note)

To restore:

  1. Create a new Supabase project

  2. Connect using psql

  3. Restore in order:

    • roles.sql

    • schema.sql

    • data.sql

This article focuses on creating reliable, automated backups.

The step-by-step restore process deserves its own dedicated post, because it involves:

  • Creating a fresh Supabase project

  • Restoring roles, schema, and data in the correct order

  • Handling extensions, ownership, and permissions safely

👉 In the next blog, we’ll walk through the complete restore process


Key Takeaways

  • Supabase backups can be fully automated

  • Free tier users should use the Connection Pooler

  • Back up roles, schema, and data

  • Store backups in a dedicated folder

  • Always use private repositories


Reference

Supabase Docs:
https://supabase.com/docs/guides/deployment/ci/backups


Automations

Part 1 of 1

Build smart automations with workflows 🔁, APIs 🌐, AI 🧠, and agents 🤖. Turn ideas into real systems that run in the background ⏱️—so you can focus on what matters 💡. Build once. Automate forever. ♾️

More from this blog

A

Akash Blog

7 posts