別リージョンへのアプリケーションの移行
この記事の英語版に更新があります。ご覧の翻訳には含まれていない変更点があるかもしれません。
最終更新日 2024年05月08日(水)
Table of Contents
この記事に記載の手順に従ってすべてのアドオンサービス、環境設定、Heroku Postgres データを別のリージョンにある新しいアプリにコピーし、その新しいアプリに本番稼働トラフィックを移行します。
Heroku CLI
ここに記載の機能を使用するには、Heroku CLI がインストールされている必要があります。CLI がインストールされていることを検証し、heroku update
で最新バージョンに更新してください。
プロセス
このガイドでは、sourceapp
が元の (ソース) アプリ、targetapp
が移行先の (ターゲット) アプリです。
アプリの移行を開始する前に、提案されるプロセスと、お使いのアプリケーションに固有の細かな差異を理解してください。推奨される移行方法は以下のとおりです。
検証フェーズ
heroku fork
を使用して、targetapp
をsourceapp
のフォークとして作成しますtargetapp
アドオンのプロビジョニングと環境設定を検証します
本番稼働トラフィックのカットオーバー
- 移行用に DNS とデータを用意します
sourceapp
をメンテナンスモードにします- 本番データを移行します
- カスタムドメインを
sourceapp
からtargetapp
に移動します targetapp
を指すように DNS 設定を調整しますtargetapp
の設定を終了します
アプリケーションのフォーク
アプリケーションをフォークして別のリージョン (eu
リージョンなど) にコピーを作成し、検証フェーズを開始します。これにより、すべての Heroku Postgres データと環境設定がコピーされ、すべてのアドオンが再プロビジョニングされます。データベースのサイズによっては、このプロセスに時間がかかる可能性があります。
Heroku Postgres データのみが自動的に新しいアプリケーションにコピーされます。その他すべてのアドオンは、再プロビジョニングされるのみです。このアプローチによる影響を考慮し、その他の該当するアドオンについて、適切なデータ移行を計画してください。
フォーキング
heroku fork
コマンドはデフォルトでは Heroku CLI に含まれませんが、以下のコマンドを使用して、プラグイン経由で利用できます。
heroku plugins:install heroku-fork
これにより、以下のコマンドを使用できるようになります。
heroku fork
により、sourceapp
が新しい targetapp
にフォークされます。targetapp
は fork コマンドよりも先に存在してはなりません。
$ heroku fork --from sourceapp --to targetapp --region eu
Creating fork targetapp... done
Copying slug... done
Adding heroku-postgresql:essential-0... done
Creating database backup from sourceapp... .. done
Restoring database backup to targetapp... .. done
Copying config vars... done
Fork complete, view it at http://targetapp-1234567890ab.herokuapp.com/
反対に、アプリが eu
リージョンにあり、us
リージョンに移行する場合は --region us
を使用してください。
プロビジョニングのエラー
sourceapp
以外のリージョンにフォーキングする場合、一部のアドオンでは、それらのアドオンが新しいリージョンで利用できない場合、または古いプランである場合にプロビジョニングが失敗することがあります。
$ heroku fork --from sourceapp --to targetapp --region eu
Creating fork targetapp... done
Copying slug... ........ done
Adding airbrake:developer... done
Adding bonsai:test... skipped (not found)
Adding komrade:test... skipped (This app is in region eu, komrade:test is only available region us)
...
元のプランがすでに存在しないためにアドオンをプロビジョニングできない場合は、ソースアプリのプランをアップグレードしてシームレスな移行ができるようにしてください。
$ heroku addons:upgrade memcachier:dev -a sourceapp
Upgrading to memcachier:dev on sourceapp... done, v207 (free)
アドオンが新しいリージョンでまだ利用できない場合は、アプリのリージョンでの利用を可能にできるそのサービスの別のプロバイダの使用を検討してください。
エラーなく完了できるまで、fork コマンドを再実行します。各実行の前に、targetapp
の不完全なプロビジョニングが破棄されていることを確認してください。
$ heroku apps:destroy -a targetapp
アドオンの手動設定
一部のアドオンでは、プロビジョニングの後に追加の設定が必要です。以下に表示されているアドオン以外にも該当のアドオンがある可能性があるため、ご使用のアプリのアドオンで、手動の設定が必要なアドオンを確認してください。
スケジューラー
Heroku Scheduler アドオンでは、ジョブスケジュールを手動で転送する必要があります。sourceapp
と targetapp
の両方で横並びでスケジューラーダッシュボードを開き、diff を表示して手動でジョブをコピーします。
$ heroku addons:open scheduler -a sourceapp
$ heroku addons:open scheduler -a targetapp
検証
フォーキングが完了してすべてのアドオン設定がコピーされたら、フォーク済みのアプリケーションを開き、最終的な移行手順に進む前に、アプリケーションが適切に機能することを検証します。
$ heroku open -a targetapp
アプリで OAuth が使用されている場合、またはその他のドメイン固有の外部サービスが使用されている場合に、ドメインが本番環境の設定と異なるときは、使用する新しいサービスのプロビジョニングをこの検証フェーズ中に行う必要があります。
フォーク済みのアプリが適切に機能することが検証されたら、カットオーバープロセスを開始できます。
DNS の準備
カスタムドメインを使用するアプリでは、アプリの名前変更や DNS アドオンの使用とは対照的に、手動で DNS 設定を調整する必要があります。これらの代替はサポートされず、重大なダウンタイムの原因となります。
ご利用のアプリにカスタムドメインがある場合、DNS プロバイダーを使用して各ドメインの TTL を低い値 (60 秒、120 秒など) に設定してください。これにより、移行プロセス中にレコードを変更したことによって生じるダウンタイムが最小化され、DNS 関連のエラーをすばやく修正することができます。
すべての DNS キャッシュが新しい TTL で更新されるようにするには、移行を進める前に、少なくとも以前の TTL と同じ時間待機する必要があります。
データベースの準備
アプリのフォーキングプロセスによって新しいデータベースが作成されますが、このデータベースは新しいアプリの設定の検証にのみ使用されます。実際のデータベース移行は、(移行中にデータが書き込まれるのを回避するため) sourceapp
がメンテナンスモードの場合にのみ、さらにアプリケーションのダウンタイムが最小限になる方法で行われる必要があります。
Standard 層以上のデータベースがある場合、フォロワーデータベースをあらかじめプロビジョニングしておいて、マスターデータベースによって最新の状態になるのを待ってから、アプリをカットオーバーすることもできます。(開発プランのデータベースユーザーのデータベース移行はカットオーバーフェーズ中に完全に行われるため、これらのユーザーはこの手順をスキップできます)。
フォロワーの作成
targetapp
で (同じプランの) 新しいデータベースをプロビジョニングし、sourceapp
の現在のデータベースをフォローするようにします。
$ heroku addons:create heroku-postgresql:standard-0 -a targetapp --follow `heroku config:get DATABASE_URL -a sourceapp`
Adding heroku-postgresql:standard-0 on targetapp... done, v32 ($50/mo)
Attached as HEROKU_POSTGRESQL_CHARCOAL_URL
Follower will become available for read-only queries when up-to-date
Use `heroku pg:wait` to track status.
$ heroku pg:wait -a targetapp
Waiting for database HEROKU_POSTGRESQL_CHARCOAL_URL... / available
フォロワーが利用できるようになった後、ソースデータベースからすべてのデータを受信するまでに時間がかかる可能性があります。pg:info
コマンドを使用して、フォロワーのコミットのうち、ソースデータベースからのものがいくつあるかを表示します。
$ heroku pg:info -a targetapp
=== HEROKU_POSTGRESQL_CHARCOAL_URL
Plan: Standard 0
Status: available
Region: eu-west-1
...
Behind By: 47980 commits
フォロワーのコミット数が最大で数百の場合にのみ、アプリケーションの移行を開始できます。
メンテナンスモード
移行プロセス中にデータの変更が行われないようにするため、sourceapp
をメンテナンスモードにしておく必要があります。
この時点以降、ユーザーはソースアプリケーションにアクセスできなくなります。アプリが移行され、すべての DNS 伝播が完了した後のみ、ターゲットアプリにアクセスできるようになります。このダウンタイムは適切に計画してください。
$ heroku maintenance:on -a sourceapp
Enabling maintenance mode for sourceapp... done
スイッチオーバーデータベース
sourceapp
がメンテナンスモードになると、データを安全に targetapp
に移行できるようになります。ここで使用するアプローチは、Heroku Postgres データベースプランに応じて異なります。
Standard 層
Standard 層以上のデータベース
Standard 層以上のデータベースがあり、targetapp
でフォロワーデータベースを作成している場合、完全に取り込まれ (残りのコミットが 0)、マスターデータベースに昇格するまで待機します。
$ heroku pg:info -a targetapp
=== HEROKU_POSTGRESQL_CHARCOAL_URL
Plan: Standard 0
Status: available
Location: eu-west-1
...
Behind By: 0 commits
$ heroku pg:unfollow -a targetapp HEROKU_POSTGRESQL_CHARCOAL_URL
Unfollowing HEROKU_POSTGRESQL_CHARCOAL_URL... done
$ heroku pg:promote -a targetapp HEROKU_POSTGRESQL_CHARCOAL_URL
Promoting HEROKU_POSTGRESQL_CHARCOAL_URL to DATABASE_URL... done
フォロワーデータベースが targetapp
の主要データベースになり、場所が DATABASE_URL
環境設定にコピーされています。
PG バックアップ
Essential 層データベースをお使いの場合は、PG Backups を使用してデータベースを転送する必要があります。pg:copy
を使用して、データベースを直接転送できます。
$ heroku pg:copy sourceapp::DATABASE_URL DATABASE_URL -a targetapp
データベースのサイズによっては、この処理に時間がかかることがあります。
アドオンデータ
その他のアドオンプロバイダーでは移行の手順が異なったり、移行機能がなかったりします。アドオンの使い方は、データの移行が必要かどうかに左右されます。詳細は、アドオンプロバイダーについてのドキュメントを参照してください。
dyno のスケーリング
heroku ps
を使用して dyno を検証し、Dyno formation を sourceapp
から targetapp
にコピーします。
$ heroku ps -a sourceapp
=== web: `bundle exec thin start -p $PORT`
web.1: up 2013/02/12 18:56:17 (~ 20h ago)
web.2: up 2013/02/12 19:14:45 (~ 19h ago)
$ heroku scale web=2 -a targetapp
ログを確認して、dyno が適切に起動されていることを確認します。
$ heroku logs -t -n 1000 -a targetapp
カスタムドメイン
targetapp
がユーザーアクティビティを受信するには、アプリによってどのドメインが提供されているかを、Heroku が把握している必要があります。古いアプリのカスタムドメインを一覧にします。
$ heroku domains -a sourceapp
=== sourceapp Domain Names
www.example.com
これらの各ドメインを、sourceapp
から削除して targetapp
に追加します。
$ heroku domains:remove -a sourceapp www.example.com
Removing www.example.com from sourceapp... done
$ heroku domains:add -a targetapp www.example.com
Adding www.example.com to targetapp... done
DNS
トラフィックを新しいアプリにルーティングするには、すべてのカスタムドメインが targetapp
に対して名前解決されるように DNS 設定を調整します。以下の CNAME レコードを DNS プロバイダーのコントロールパネルに追加します。
タイプ | 名前 | ターゲット |
---|---|---|
CNAME | www | targetapp-1234567890ab.herokuapp.com |
A レコードはサポートされていません。必要に応じて、DNS レベルのリダイレクトまたはエイリアスレコードを使用して、ルートドメインを targetapp-1234567890ab.herokuapp.com
に対して名前解決します。
伝播
DNS TTL を低い値に調整している場合、リクエストがターゲットアプリにルーティングされるまでにかかる時間はほんの数分です。ターゲットアプリのログを調査して、リクエストが適切に名前解決され、処理されていることを確認します。
$ heroku logs -t -a targetapp
DNS が変更されると、カスタムドメインへのすべてのリクエストの伝播は新しい EU の場所から行われます。
Git リモートの更新
アプリケーションのフォーキングによって、現在のプロジェクトに新しい Git リモートが自動で作成されることはありません。targetapp
にデプロイを行うには、ユーザー自身が Git リモートを確立する必要があります。heroku info
を使用して新しいアプリケーションの Git URL を取得し、手動で設定します。
$ heroku info -a targetapp
=== targetapp
...
Git URL: git@heroku.com:targetapp.git
...
$ git remote add forked git@heroku.com:targetapp.git
この例では、targetapp
の Git リモートは forked
と呼ばれます。以下のように、このアプリにデプロイします。
$ git push forked master
この新しいアプリを (移行後に) デプロイのデフォルトのターゲットにする場合は、Git リモートの名前を変更できます。
$ git remote rename heroku old
$ git remote rename forked heroku
今後すべてのデプロイで、targetapp
がデプロイのデフォルトのターゲットになります。十分な時間が経過してから、sourceapp
にある使用しないリソースはすべてプロビジョニング解除してください。
フォーク済みアプリの状況
フォーク済みアプリは可能な限りソースアプリに似せられています。ただし、いくつか相違点があります。
共同作業者
ソースアプリのユーザーがフォーク済みアプリに転送されることはありません。共同作業者はユーザー自身が追加する必要があります。
$ heroku access:add colleague@example.com -a targetapp
Labs 機能
sourceapp
で有効化されている Heroku Labs 機能は、targetapp
で再有効化されません。これらはユーザー自身が再有効化する必要があります。