Herokuから別のPaaSへ移すとき、ソースコードをGitHubへ置き直すだけでは終わりません。起動方法、環境変数、DB、アドオン、定期実行など、Heroku側が引き受けていた役割を一つずつ対応させる必要があります。
この記事は、HTTPでリクエストを受けるアプリとPostgreSQLを、KamuiDashへ移すための手順書です。先に別URLと空のDBで動作を確かめ、最後のデータ移行と切り替えを分けて考えるのが中心です。
Heroku上の実サービスを今回移した記録ではありません。2026年11月2日の公式資料と、添付サンプルのローカルでのDBダンプ・復元確認をもとに整理しています。停止時間や移行の成功を保証するものではありません。
この記事の内容
移せる構成か、最初に棚卸しする
| Herokuで使っているもの | 移行時に確認すること |
|---|---|
| HTTPアプリのwebプロセス | KamuiDashの対応言語・依存関係・起動コマンドに合わせられるか |
| Heroku Postgres | PostgreSQLの版、拡張、容量、権限、接続上限が移行先で足りるか |
| Config Vars | 秘密値、実行時変数、ビルド時に必要な値を分類する |
| workerプロセス | 実行方式・キュー・停止時の扱いを個別に設計する |
| Schedulerなどのアドオン | 代替サービスや別構成が必要か |
| メール・Redis・ファイル保存 | 接続先を維持するか、別サービスへ移すか |
| 独自ドメイン・Webhook | 切り替える順序、DNS、コールバックURL、再送を確認する |
KamuiDashはNode.js・Python・Go・RubyなどのWebサーバーとPostgreSQLを提供しています。ただし、Herokuのすべてのプロセスタイプやアドオンをそのまま実行できるとは限りません。この記事で扱うのはHTTPアプリとDBの部分です。
アドオンへの依存が強く、置き換えに多くの実装が必要なら、Herokuを使い続ける費用と移行の作業時間も比較します。
Procfileの役割を、3つのコマンドへ対応させる
HerokuのProcfileは、プロセスタイプごとの起動方法を記述するものです。たとえばNode.jsで次のような設定を使っていたとします。
web: npm start
release: npm run migrate
KamuiDashではProcfileが同じように自動解釈されると考えず、アプリの設定に必要なコマンドを明示します。
| 処理 | KamuiDashで設定する例 | 読み替えるときの注意 |
|---|---|---|
| 依存関係・ビルド | セットアップ:npm ci、必要ならnpm run buildも実行 |
ロックファイルと作業ディレクトリを揃える |
| DB変更など | 起動前:npm run migrate |
Herokuのreleaseと実行回数・タイミングが同じとは仮定しない |
| HTTPサーバー | 起動:npm start |
PORT、0.0.0.0、終了処理を確認する |
起動前の処理は、繰り返してもデータを壊さないことが重要です。複数レプリカで同時に動く可能性を考え、マイグレーションの実行方式やロックも確認します。既存の本番DBへ試しに流すのではなく、移行検証用DBで実行します。

環境変数を、値の種類ごとに移す
HerokuのConfig Varsを、変数名だけの一覧にして分類します。実際の値を記事やチャットへ貼る必要はありません。
- DBの接続情報は、移行先のPostgreSQLへ置き換える。
- 外部のメール・認証・決済などは、接続を維持できるかを確認する。
- アプリの公開URL、CORS、認証のコールバックURLは、新しいURLに対応させる。
- ビルド時に読む値は、起動時環境変数と分けて設定する。
KamuiDashではアプリへのDB接続設定によりDATABASE_URLなどが設定されます。旧HerokuのDATABASE_URLを残すと、新しいアプリが旧DBへ書き込み続ける可能性があります。確認用の新URLを作った段階でも、どちらのDBを見ているかは明確にしてください。
セッション署名鍵や暗号化鍵は、単純に新しくすると既存セッションや暗号化データへ影響することがあります。維持すべき鍵と変更すべき接続先を、同じ一括置換で処理しないようにします。
PostgreSQLは、空の移行先へ一度復元してみる
最初の復元は本番切り替えとは別に行います。KamuiDash側には、復元に使う専用の空DBを作ります。以下のPCからの復元には、ProのDBで外部接続を利用できることが前提です。無料トライアルDBへのアプリ内接続とは区別します。
まずCLIの外部接続で、専用DBへ到達する
PCからの接続は、KamuiDash CLIのローカルトンネルを使います。アプリへ設定された内部接続URLを、そのままPCに持ち出して使う方式ではありません。CLIとPostgreSQLのクライアントツールを準備し、対象DBの詳細画面で外部接続を利用できる状態にします。
新しく作った専用DBで外部用パスワードが未初期化の場合は、CLIが案内するDB詳細画面で初期化します。既存のDBの資格情報を、この手順の準備として変更する必要はありません。
kamui login
kamui db connect 'YOUR_PROJECT/YOUR_DATABASE'
接続したpsql内でSELECT current_database(), current_user;を実行し、専用DBであることを確認したら\qで終了します。YOUR_PROJECT/YOUR_DATABASEは管理画面上の名前に置き換えます。
db connectでpsqlを開けます。別のツールであるpg_restoreから利用するには、常駐するローカルトンネルを使います。まずkamui db daemon statusを確認し、未起動なら次を実行します。
kamui db daemon start
kamui db daemon status
デーモンは利用可能な外部接続設定を読み、ローカルの待受ポートを表示します。statusの対象DBの行からポートを確認し、CLIが案内するCAファイルのパスを控えます。既存デーモンが起動済みなら、別の利用を切断するために再起動するのではなく、対象DBのポートとCA設定を確認します。対象行がない場合は、既存の利用が終わってからデーモンを起動し直すか、別の環境でトンネルを起動します。
現行CLIはローカル区間にも検証付きTLSを使います。公式ソースのDB接続処理とトンネル処理が根拠です。古いCLIでコマンドや表示が異なる場合は、対応するリリースへ更新してから手順を確認してください。今回、確認したCLIは0.1.22です。
Herokuのバックアップを取得する
Herokuの公式エクスポート手順に沿った例です。対象アプリ名を自分で指定し、取得が終わったバックアップをダウンロードします。DBが大きい場合や負荷が高い場合は、取得方法と影響を先に確認します。
export HEROKU_APP_NAME='your-source-app'
# DATABASE_URL は移行対象のアタッチメント名に合わせる
heroku pg:backups:capture DATABASE_URL --app "$HEROKU_APP_NAME"
# b123 は capture が表示したバックアップIDに置き換える
BACKUP_ID='b123'
heroku pg:backups:info "$BACKUP_ID" --app "$HEROKU_APP_NAME"
# 対象DBと完了状態を確認してから実行する
heroku pg:backups:download "$BACKUP_ID" --app "$HEROKU_APP_NAME" --output migration.dump
pg_restore --list migration.dump
Herokuは、負荷が中程度で20 GB以下のDBにPGBackupsを推奨しています。Advancedには対応していないため、対象DBのプランに合った論理バックアップ手順を確認します。検証用と最終切り替え用で、ダウンロード先のファイル名を分けます。Heroku PGBackups · Herokuの論理バックアップ
ダンプには実データが含まれます。Gitへ保存せず、アクセスできる人と保管場所を限定します。上の一覧確認だけで復元できると判断せず、実際の空DBへの復元まで試します。
接続情報を分けて、空DBへ復元する
次は、PostgreSQLのサービス定義にkamui-migration-targetという接続先を用意した例です。~/.pg_service.confに設定します。32000は説明用の仮のポートで、必ずstatusに表示された対象DBのポートへ置き換えます。DB名とユーザー名は外部接続情報を使い、CAのパスもCLIが案内した実際の絶対パスに置き換えます。
[kamui-migration-target]
host=127.0.0.1
hostaddr=127.0.0.1
port=32000
dbname=YOUR_EXTERNAL_DB_NAME
user=YOUR_EXTERNAL_DB_USER
sslmode=verify-full
sslrootcert=/ABSOLUTE/PATH/SHOWN/BY/CLI/ca.pem
gssencmode=disable
このファイルを作るだけでは接続できません。対象DBのトンネルが起動していることが必要です。パスワードはここに書かず、以下の-Wによる非表示の入力で指定します。継続利用では、権限を保護した~/.pgpassを使う方法もあります。
先に移行先アプリのDB接続で SELECT current_user; を実行し、アプリが使うロールを確認します。YOUR_APP_DB_ROLE をその名前に置き換えます。外部接続ユーザーからアプリ用ロールに切り替えて復元すると、アプリ用ロールが復元先のテーブルやシーケンスを所有します。SET ROLE が失敗した場合は復元に進まず、利用できる復元経路を管理者に確認してください。
# 復元先が「専用の空DB」であることを先に確認する
psql 'service=kamui-migration-target' -W \
-c 'SELECT current_database(), current_user, version();'
export KAMUI_APP_DB_ROLE='YOUR_APP_DB_ROLE'
psql 'service=kamui-migration-target' -W -v ON_ERROR_STOP=1 \
-v "app_role=$KAMUI_APP_DB_ROLE" <<'SQL'
SET ROLE :"app_role";
SELECT current_user;
SQL
pg_restore \
--role="$KAMUI_APP_DB_ROLE" \
--dbname='service=kamui-migration-target' \
-W \
--no-owner --no-privileges \
--exit-on-error --single-transaction \
migration.dump
--no-ownerと--no-privilegesは、移行元の所有者・権限をそのまま適用しない指定です。権限を再現する必要があるアプリでは、復元後に用途に合う権限を別途設定します。--single-transactionは、エラー時に途中までの復元を残さないための指定ですが、大きなDBや制限のあるDBでは実行時間・ロックなどの制約も確認します。
PostgreSQLの版の組み合わせ、利用している拡張、所有者以外の権限、シーケンスも確認します。古いクライアントでは新しいDBのダンプを扱えない場合があり、新しい版から古い版への復元が保証されるわけでもありません。pg_dumpとpg_restoreの対応範囲を確認します。
上記はCLIの公開仕様とソースを確認した接続設定例で、この執筆ではKamuiDashのDBへのトンネル接続やクラウドへの復元は実行していません。実データを移す前に、同じ経路でテスト用ダンプを専用DBへ復元できるか確認してください。利用資格・接続・復元権限が揃わない場合は、その状態で最終移行へ進まず、対応する実行経路を確認します。
新URLで、データとアプリの両方を確かめる
復元後はテーブル件数だけで終わらせず、主要なレコード、関連データ、日時、IDの採番、ログイン、作成・更新を確認します。ダンプに含まれない画像や外部サービスの状態も対象です。

FastAPI+PostgreSQLの公開手順は、メモの登録・一覧を確認できる最小構成です。既存アプリの移行では、利用している機能ごとに確認項目を増やしてください。
最後の移行では、書き込みを止める時間を決める
検証用バックアップを取った後にも、旧DBへ新しいデータが増える場合があります。検証が終わったからといって、その古いコピーへ切り替えると、その間の更新が失われます。
小さなアプリで停止時間を取れるなら、次の順序が一つの方法です。
- 利用者へ停止時間を案内し、旧アプリの書き込みを止める。管理画面だけでなく、ジョブ、Webhook、別クライアントも対象にする。
- 最終バックアップを取得し、最終移行用の空DBへ復元する。検証済みDBへ重ねて流さない。
- 新アプリをそのDBへ接続し、旧側は書き込み停止のままで主要な処理を確認する。
- 独自ドメインやWebhookの宛先を切り替え、旧側へ残るアクセスも監視する。
- 新側だけで書き込みを再開する。
HerokuのメンテナンスモードはHTTPルーティングを止めますが、dynoは動き続けます。Firではメンテナンスモードを利用できないため、アプリ側などで書き込みを止めます。稼働数を記録し、書き込むワーカーやスケジュールを止め、実行中の処理が終わったことを確認してから最終バックアップを取ります。新側もデフォルトURLやジョブ経由の書き込みを閉じ、切り替え前は読み取り中心で確認します。Herokuのメンテナンスモード
DNSのキャッシュにより、新旧両方へアクセスが来る時間があります。旧側で書き込みを再開して二重運用にしないことが重要です。停止時間を取れない場合は、継続同期やデータ差分の扱いを含めた別の移行設計が必要で、この記事の単純なダンプ・復元だけでは足りません。
切り戻しは、URLだけを戻せば済むとは限らない
新側で書き込みが始まった後は、新DBにしかないデータが生まれます。その状態で旧DBへ戻すと更新を失います。切り戻しの判断期限、書き込みを止める手順、差分を旧側へ戻す方法を、切り替え前に決めます。
旧環境の削除は、動作・データ・費用の確認が終わり、必要な保管期間を満たした後の別作業です。
よくある疑問
Herokuのアドオンもまとめて移せますか?
アドオンごとに違います。アプリのHTTP処理とPostgreSQLが移せても、メール、キュー、定期実行などは別の移行・再設定が必要になる場合があります。
DBを復元する前にマイグレーションを実行しますか?
既存DBのダンプを復元する場合は、空テーブルを先に作って衝突させないようにします。復元するスキーマの版とアプリの版を合わせ、必要な追加変更だけを復元後に適用する計画にします。
この手順はRubyやPythonにも使えますか?
棚卸しとDB移行の考え方は共通です。依存関係の準備、ビルド、起動、マイグレーションのコマンドは言語とアプリに合わせます。Node.jsの例をそのまま転記しないでください。
移行で先に確かめたいのは、起動することに加え、同じデータで必要な処理ができることです。その確認と最後のデータ切り替えを分けると、移行の判断を具体的に進められます。
KamuiDashは、GitHubやAI連携からWebアプリを公開できる東京リージョンのPaaSです。