Zeabur Database Backup and Restore: Tested Commands for PostgreSQL, MySQL, MongoDB and Redis

Two ways to get your databases off Zeabur: the built-in backup and your own dump. Every command was run in Docker, and the error messages you will hit are listed alongside.

Key points

  • pg_dump must be the same major version as the database server or newer, or it aborts.
  • When restoring into a managed database such as Neon or Supabase, add --no-owner --no-acl, or you get role "root" does not exist.
  • Zeabur's built-in data.sql only restores into a database where you are superuser, and it restores the old password too.
  • The MySQL, MongoDB and Redis commands all worked in our tests. If Redis is only a cache, don't migrate it.
How was this verified? (5 tested, 2 from official docs)
Tested ourselves
  • PostgreSQL 16 → 17: pg_dump -Fc / pg_restore into a database where we are not superuser (simulating Neon/Supabase); all 500 rows and the sequence were correct
  • PostgreSQL: a pg_dumpall data.sql (the format of Zeabur's built-in backup) restored into both self-managed and managed databases
  • MySQL 8: mysqldump backup and restore, including a routine and a trigger
  • MongoDB 7: mongodump / mongorestore (archive + gzip)
  • Redis 7: export with redis-cli --rdb and load into a new Redis
Written from official docs, not run ourselves
  • Zeabur's Backup and Instruction tabs: written from Zeabur's official docs; we did not operate a Zeabur account
  • The tests used Docker containers simulating Zeabur's databases (superuser also named root), not real Zeabur hosts
Contents (7 sections)
  1. First: Zeabur has built-in backups, but they may not be enough
  2. Where to find the connection details
  3. PostgreSQL
  4. MySQL / MariaDB
  5. MongoDB
  6. Redis
  7. After restoring

First: Zeabur has built-in backups, but they may not be enough

According to Zeabur’s docs, you open a database service’s Backup tab, click Backup, and after a few minutes the file is ready to download. This needs a paid plan (Dev Plan and above), and backups are kept for 7 days before being deleted automatically.

DatabaseFormat of Zeabur’s built-in backupRestore with
PostgreSQL.sql from pg_dumpall, covering every database in the servicepsql
MySQL / MariaDB.sql, covering all non-system databasesmysql
MongoDBMultiple .bson filesmongorestore

Our advice: download the built-in backup, then take a second one yourself with the commands below. The reason is in the PostgreSQL section: the built-in format fails when you move to a managed database.

Where to find the connection details

According to Zeabur’s PostgreSQL template, a database service’s Instruction tab has a Public (External) section with the external Connection String and a connect command. The host looks like hkg1.clusters.zeabur.com, and the port is a number assigned by Zeabur.

Hostnames ending in zeabur.internal only work inside Zeabur; you cannot reach them from your own machine.

All commands below run in Docker, so you don’t need database tools installed locally.

PostgreSQL

1. Check the server version first

docker run --rm postgres:17 psql "postgresql://USER:PASS@HOST:PORT/DB" -tAc "show server_version"

pg_dump must be the same version as the server or newer. Backing up a version 16 server with pg_dump 15 aborts immediately:

pg_dump: error: aborting because of server version mismatch
pg_dump: detail: server version: 16.15 ...; pg_dump version: 15.19 ...

So replace the image tag below (postgres:16) with your server’s major version or newer.

docker run --rm -v "$PWD:/out" postgres:16 \
  pg_dump "postgresql://USER:PASS@HOST:PORT/DB" -Fc -f /out/backup.dump

3. Restore into a managed database such as Neon or Supabase

A managed database does not give you a superuser account, and tables on Zeabur are owned by root. A plain restore fails with:

pg_restore: error: could not execute query: ERROR:  role "root" does not exist

Adding --no-owner --no-acl avoids this. In our test: zero errors, correct row counts, and newly inserted ids continued the original sequence:

docker run --rm -v "$PWD:/out" postgres:17 \
  pg_restore --no-owner --no-acl -d "NEW_DATABASE_CONNECTION_STRING" /out/backup.dump

Restoring Zeabur’s built-in data.sql

Zeabur’s docs say to unzip the backup and run:

psql -h HOST -p PORT -U USER postgres < data.sql

Our results with the same format (pg_dumpall):

  • Into a self-managed PostgreSQL (you are superuser): works, data complete
  • Into a managed database (not superuser): fails with ERROR: permission denied to alter role. Use pg_dump -Fc above instead

Security note: data.sql starts with these two lines:

CREATE ROLE root; ALTER ROLE root WITH SUPERUSER ... PASSWORD 'SCRAM-SHA-256$...';

In other words, after the restore the database password is back to your old Zeabur password. Given Zeabur’s security incidents, change it right away:

ALTER ROLE root WITH PASSWORD 'a-new-long-password';

Zeabur’s docs also mention that to keep your current password, you can delete the CREATE ROLE and ALTER ROLE lines from data.sql before restoring.

Start an empty local database, restore the backup into it, and check the tables and row counts:

docker network create restore-net
docker run -d --name restore-test --network restore-net -e POSTGRES_PASSWORD=x postgres:17
# wait a few seconds for the database to start
docker run --rm --network restore-net -v "$PWD:/out" postgres:17 \
  pg_restore --no-owner --no-acl -d "postgresql://postgres:x@restore-test:5432/postgres" /out/backup.dump
docker exec restore-test psql -U postgres -tAc "select count(*) from your_table"

# clean up afterwards
docker rm -f restore-test && docker network rm restore-net

Why not publish a port with -p 5433:5432? That is how our first test was written, and another local PostgreSQL happened to be listening on port 5433 of the test machine, so the backup was restored into that database instead. With a Docker network, the test database never exposes a port, so you can’t connect to the wrong one.

MySQL / MariaDB

# Backup: --single-transaction avoids locking tables; --routines --triggers includes stored procedures and triggers
docker run --rm -v "$PWD:/out" mysql:8 sh -c \
  'mysqldump -h HOST -P PORT -u USER -pPASS --single-transaction --routines --triggers DB > /out/backup.sql'

# Restore
docker run --rm -v "$PWD:/out" mysql:8 sh -c 'mysql -h NEW_HOST -P NEW_PORT -u USER -pPASS DB < /out/backup.sql'

Tested: data, one stored procedure and one trigger all came across intact.

MongoDB

docker run --rm -v "$PWD:/out" mongo:7 \
  mongodump --uri "mongodb://USER:PASS@HOST:PORT/?authSource=admin" --archive=/out/backup.archive --gzip

docker run --rm -v "$PWD:/out" mongo:7 \
  mongorestore --uri "NEW_CONNECTION_STRING" --archive=/out/backup.archive --gzip

Test output: 50 document(s) restored successfully. 0 document(s) failed to restore.

Redis

Most people only use Redis as a cache, and then you don’t need to migrate it; the new Redis rebuilds the cache on its own. If you really store data in Redis (queues, leaderboards):

docker run --rm -v "$PWD:/out" redis:7 redis-cli -h HOST -p PORT -a PASS --rdb /out/dump.rdb

On success it prints Transfer finished with success. Put dump.rdb in the new Redis data directory (/data in the official image) and start it; it loads automatically. In our test the key count matched.

After restoring

  • Switch to the new connection string (DATABASE_URL or similar) and change the database password
  • Compare row counts on a few important tables
  • Turn on daily automatic backups on the new platform, and actually download one to make sure you can

FAQ

Does Zeabur have built-in database backups?

Yes. The Backup tab of a database service lets you download backups, on paid plans only, and backups are kept for 7 days. PostgreSQL backups are .sql files produced by pg_dumpall.

Why do I get role "root" does not exist when restoring?

Tables on Zeabur are owned by root, and a managed database has no such role. Add --no-owner --no-acl to pg_restore; in our test that produced zero errors.