Skip to content

UpgradeInstanceOnHeroku

zunda edited this page Feb 17, 2022 · 21 revisions

データベースを更新する

Hobby-devプランのHeroku Postgresは10000行までしか保存できないという制限があります。プラットフォームが行数の超過に気づくと書き込みができなくなります。その前にHobby-basicに移行しましょう。Hobby-basicのHeroku Postgresは、執筆現在、$9/月かかります。

heroku addons:create heroku-postgresql:hobby-basic --as PG_HOBBY_BASIC -a $APP_NAME
heroku maintenance:on -a $APP_NAME
heroku ps:scale worker=0 -a $APP_NAME
heroku pg:copy DATABASE_URL PG_HOBBY_BASIC -a $APP_NAME
heroku pg:promote PG_HOBBY_BASIC -a $APP_NAME
heroku ps:scale worker=1 -a $APP_NAME
heroku maintenance:off -a $APP_NAME

Standard以上のHeroku Postgresではpg:copyよりもFollower changeoverの方がアプリケーションを停止させておく時間が短くて済む可能性が高いです。

更新されたコードをデプロイする

Heroku CLIを使った場合、あるいは、Heroku Buttonを使った場合の手順のどちらかコードを更新した後、データベースをmigrateします。

Heroku CLIを使った場合

CreateInstanceOnHerokuのデプロイの項のように、ワーキングコピーのoriginリモートにMastodonの上流のレポジトリが、heroku-branchブランチにHerokuアプリケーションのコードがある場合は、下記のように更新されたコードをデプロイできます。

まず、ワーキングコピーに上流の変更内容を取得します。

cd mastodon
git checkout master
git pull

次にHerokuアプリケーションのコードがあるブランチに変更内容を取り込みます。ここではv1.6.2タグの内容を取り込んでみます (執筆時点ではまだこのタグはありません)。

git checkout heroku-branch
git merge v1.6.2

ローカルに加えた変更内容が更新内容とconflictする場合は、適宜修正が必要です。

修正が終わったらデプロイします。

git push heroku heroku-branch:master

また、下記の様にPipelinesを使うと作業を省力化できます。

Pipelinesを使う

日常のコードの更新の省力化のため、Piplinesを設定しました。Staging段にはpush先のブランチごとにアプリを設定して、テストの時にはProduction段に置いてあるストリーミング用のアプリだけにpromotionをします。テストがうまくいけば、本番用のPuma+Sidekiqアプリとストリーミング用のアプリにpromotionをします。

Screen Shot 2022-02-17 at 00 37 28

手元でのgitの操作も含めて、シェルスクリプトで操作しています。諸々確認してCtrl-Dをタイプすると次に進みます。

https://gist.github.com/zunda/2189218dbf77e7f22c99094c567813a5

Heroku Buttonを使った場合

Heroku Buttonでアプリケーションを作成した場合にはそのままではコードを更新することができません。

CreateInstanceOnHerokuのデプロイの項を参考に、手元にワーキングコピーを作成してから、上記のHeroku CLIを使った場合と同様に更新してください。

脆弱性の発見されたaptパッケージを更新する

v1.4からはslug内に、アプリケーションの動作に必要なaptパッケージを持つようになりました。これらのパッケージに脆弱性が発見されてパッケージが更新された場合には、slug内のパッケージも更新が必要です。上記の手順でアプリケーションをデプロイしてください。

  • slug内のパッケージとバージョンを知る方法

NameError: uninitialized constant ActiveModel::Type::Text

コードの更新後Puma/Railsのログに下記のようなエラーが見られた場合には、Railsの更新でキャッシュが非互換になっているのが原因のようです。

method=GET path=/api/v1/timelines/public format=*/* controller=Api::V1::Timelines::PublicController action=show status=500 error='NameError: uninitialized constant ActiveModel::Type::Text'

application_controller.rb:76:in `cache_collection'
api/v1/timelines/public_controller.rb:22:in `cached_public_statuses'
api/v1/timelines/public_controller.rb:16:in `load_statuses'
api/v1/timelines/public_controller.rb:9:in `show'
  :

しばらく待つか、下記のようなコマンドでキャッシュをクリアすることで解消します。

$ heroku run rails c -a $APP_NAME
irb(main):001:0> Rails.cache.clear
=> nil

401 Access Token is Invalid

ログインしたまま1.4.7へ更新するとHomeやNotificationsの閲覧時に上記のようなエラーダイアログが表示されます。一度ログアウトして再度ログインすることで解消できます。

データベースをmigrateする

Release Phaseを利用してProcfilerelease:の行でrake db:migrateするようにすればこの作業は不要です。

heroku run rake db:migrate -a $APP_NAME
heroku ps:restart -a $APP_NAME

v1.4.1からv1.4.2の間に、外部キーが導入されてmigrationが失敗するようになりました:

StandardError: An error has occurred, this and all later migrations canceled: 
PG::ForeignKeyViolation: ERROR:  insert or update on table "statuses" violates foreign key constraint "fk_rails_94a6f70399" 

この場合は、下記のようにまず外部キーを用意してからmigrateしましょう。Release Phaseを有効にしている場合には、migrationが失敗することでこのrakeタスクがデプロイできていない可能性があるので、一度Release Phaaseを無効にした (例えばrelease:の行をコメントアウトした) コードをデプロイして外部キーを用意する必要があります。

heroku run rake mastodon:maintenance:prepare_for_foreign_keys -a $APP_NAME
heroku run rake db:migrate -a $APP_NAME
heroku ps:restart -a $APP_NAME

v1.6.0の後に、プライマリキーの型がintegerからbigintに変更されました。稼働中のアプリケーションがある場合にmigrationが失敗する可能性があります。アプリケーションをメンテナンスモードにしてからmigrationをしてください。手元では5分くらいかかりました。

heroku maintenance:on -a $APP_NAME
heroku ps:scale web=0 worker=0 -a $APP_NAME
heroku run rake db:migrate -a $APP_NAME
heroku ps:scale web=1 worker=1 -a $APP_NAME
heroku maintenance:off -a $APP_NAME