まず知っておくこと:Zeabur には標準バックアップがあるが、それだけでは足りないことも
Zeabur のドキュメントによると、データベースサービスの「Backup」タブで「Backup」ボタンを押すと、数分でダウンロードできるようになります。この機能は有料プラン(Dev プラン以上)限定で、バックアップは 7 日間保持された後に自動削除されます。
| データベース | Zeabur 標準バックアップの形式 | 復元に使うもの |
|---|---|---|
| PostgreSQL | pg_dumpall による .sql。サービス内の全データベースを含む | psql |
| MySQL / MariaDB | .sql。システム以外の全データベースを含む | mysql |
| MongoDB | 複数の .bson ファイル | mongorestore |
おすすめ:標準バックアップをダウンロードしたうえで、下のコマンドで自分でももう 1 つ取っておく。 理由は PostgreSQL の節で説明しますが、マネージド DB へ移る場合、標準バックアップの形式ではエラーになります。
接続情報の場所
Zeabur の PostgreSQL テンプレートの説明によると、データベースサービスの「Instruction」タブにある「Public (External)」セクションに、外部接続用の Connection String と接続コマンドがあります。ホスト名は hkg1.clusters.zeabur.com のような形で、ポートは Zeabur が割り当てた番号です。
末尾が zeabur.internal のホスト名は Zeabur 内部専用で、手元のパソコンからは接続できません。
以下のコマンドはすべて Docker で実行するので、ローカルにデータベースツールをインストールする必要はありません。
PostgreSQL
1. まずサーバーのバージョンを確認
docker run --rm postgres:17 psql "postgresql://USER:PASS@HOST:PORT/DB" -tAc "show server_version"
pg_dump のバージョンはサーバーと同じかそれ以上である必要があります。 バージョン 15 の pg_dump でバージョン 16 のサーバーをバックアップすると、すぐに中止されました。
pg_dump: error: aborting because of server version mismatch
pg_dump: detail: server version: 16.15 ...; pg_dump version: 15.19 ...
そのため、下のイメージのバージョン(postgres:16)は、サーバーと同じかそれより新しいメジャーバージョンに置き換えてください。
2. バックアップ(custom 形式がおすすめ)
docker run --rm -v "$PWD:/out" postgres:16 \
pg_dump "postgresql://USER:PASS@HOST:PORT/DB" -Fc -f /out/backup.dump
3. Neon や Supabase などのマネージド DB に復元
マネージド DB で使えるアカウントは superuser ではなく、Zeabur 上のテーブルの所有者は root です。そのまま復元すると次のエラーになります。
pg_restore: error: could not execute query: ERROR: role "root" does not exist
--no-owner --no-acl を付ければ回避できます。検証ではエラーゼロ、件数も正しく、新しく挿入した id も元のシーケンスから正しく続きました。
docker run --rm -v "$PWD:/out" postgres:17 \
pg_restore --no-owner --no-acl -d "新しいDBの接続文字列" /out/backup.dump
Zeabur 標準バックアップの data.sql で復元する場合
Zeabur のドキュメントでは、解凍してから次を実行する手順になっています。
psql -h ホスト -p ポート -U ユーザー postgres < data.sql
同じ形式(pg_dumpall)で検証した結果:
- 自分で管理する PostgreSQL(superuser あり)への復元:成功、データも完全
- マネージド DB(superuser なし)への復元:失敗、
ERROR: permission denied to alter roleが出ます。この場合は上のpg_dump -Fcを使ってください
セキュリティ上の注意:
data.sqlの冒頭には次の 2 行があります。
CREATE ROLE root;ALTER ROLE root WITH SUPERUSER ... PASSWORD 'SCRAM-SHA-256$...';つまり、復元するとデータベースのパスワードが Zeabur 上の古いパスワードに戻ります。Zeabur ではセキュリティインシデントが起きているので、復元後すぐにパスワードを変更してください。
ALTER ROLE root WITH PASSWORD '新しい長いパスワード';Zeabur のドキュメントにも、現在のパスワードを維持したい場合は復元前に
data.sqlからCREATE ROLEとALTER ROLEの行を削除できると書かれています。
バックアップの検証(5 分、強く推奨)
ローカルで空のデータベースを起動し、バックアップを復元して、テーブルと件数を確認します。
docker network create restore-net
docker run -d --name restore-test --network restore-net -e POSTGRES_PASSWORD=x postgres:17
# データベースの起動を数秒待つ
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 テーブル名"
# 確認が終わったら片付ける
docker rm -f restore-test && docker network rm restore-net
なぜ
-p 5433:5432でポートを公開しないのか? 最初の検証ではそう書いていましたが、検証用マシンの 5433 番ポートでたまたま別のローカル PostgreSQL が動いていて、バックアップがそちらに復元されてしまいました。Docker ネットワークを使えば検証用 DB は外部にポートを公開しないので、接続先を間違えることがありません。
MySQL / MariaDB
# バックアップ:--single-transaction でテーブルをロックせず、--routines --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'
# 復元
docker run --rm -v "$PWD:/out" mysql:8 sh -c 'mysql -h 新HOST -P 新PORT -u USER -pPASS DB < /out/backup.sql'
検証結果:データ、ストアドプロシージャ 1 つ、トリガー 1 つがすべて移行できました。
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 "新しい接続文字列" --archive=/out/backup.archive --gzip
検証時の出力:50 document(s) restored successfully. 0 document(s) failed to restore.
Redis
Redis をキャッシュとしてだけ使っているなら、移行する必要はありません。新しい Redis が動き始めればキャッシュは自然に作り直されます。キューやランキングなど、本当にデータを Redis に保存している場合は次のとおりです。
docker run --rm -v "$PWD:/out" redis:7 redis-cli -h HOST -p PORT -a PASS --rdb /out/dump.rdb
成功すると Transfer finished with success と表示されます。dump.rdb を新しい Redis のデータディレクトリ(公式イメージでは /data)に置いて起動すれば、自動で読み込まれます。検証ではキーの数が一致しました。
復元後に必ずやること
- 新しい接続文字列(
DATABASE_URLなど)に切り替え、データベースのパスワードを変更する - 重要なテーブルをいくつか選んで件数を照合する
- 新しいプラットフォームで毎日の自動バックアップを有効にし、実際に一度ダウンロードして取り出せることを確認する