バージョンアップ
Crowi を新しいバージョンに入れ替える手順と、版ごとに必要な追加作業
基本の手順
- リリースノートで、入れ替える版までの間に追加作業があるかを確認する。
- バックアップを取る。
- 全レプリカを揃えて停止する (下記)。
- イメージのタグを新しいバージョンに書き換え、全レプリカを起動する。
GET /api/app/infoが 200 を返すことを確認する。- 下の「版ごとの注記」に該当するものがあれば実行する。
全レプリカを揃えて入れ替える
api レプリカを 1 台ずつ入れ替えるローリング再起動はしないでください。 Crowi の一部のリリースでは、新旧のレプリカが同じプールに同時に存在すると、どちらの世代が受けたかによって結果が変わります。全 api レプリカを揃えて停止し、全レプリカへ新しいバージョンをデプロイしてから揃えて起動してください。新しいバージョンで別の fleet を用意し、トラフィックを一括で切り替える (blue/green) 方法でも構いません。
レプリカが 1 台だけの構成 (開発環境を含む) は、この条件を自動的に満たします。新旧が混在しようがないためです。
版ごとの注記
refresh token が系列 id で管理されるようになったリリース
OAuth の refresh token は、サインインごとの不変の系列 id で失効を管理するようになりました。この id を持たない既存の token は、起動時の migration (listen 前に自動実行) がすべて失効させます。CLI など OAuth で連携していた既存のクライアントは、アップグレード後に一度サインインし直す必要があります。 移行前に分岐していた token も例外なく失効するため、利用可能なまま残るものはありません。migration が失敗した場合は起動が失敗し、未適用のまま listen することはありません。
必ず 全旧レプリカを停止してから新しいバージョンで起動 してください。旧レプリカが DB を書ける状態で並走する blue/green でも、旧レプリカの停止は省略できません。省略して旧レプリカを併走させると、その間に旧レプリカが発行した token は、新しいバージョンで更新するときに失効して invalid_grant になり、利用者はサインインし直すことになります。この窓だけが混在で起こる影響で、ハートビートや世代判定のような仕組みはありません。運用手順で避けてください。
アカウント連携が入ったリリース
新しいバージョンのレプリカは、外部アカウントの連携フローごとに専用の state cookie を発行します。旧バージョンのレプリカはその名前を知らず、サインイン用の固定 state cookie を読もうとして、しかも検証前にそれを削除します。混在した fleet では、旧レプリカに届いた callback が進行中の連携を失敗させるだけでなく、同時に進行していた無関係な通常のサインインまで失敗させます。2 つの世代をつなぐ互換経路はありません。上記のとおり揃えて入れ替えてください。
ページ履歴の移動状態が入ったリリース
ページの rename・ゴミ箱への移動・復元が「移動中」という状態を経由するようになりました。この状態を知らない旧バージョンのレプリカは移動中のページを通常のページとして扱い、別の移動を重ねて開始することがあります。そうなるとどちらの移動も完了せず、ページは移動中のまま取り残されます (利用者にはページが消えたように見えます)。
混在させてしまった場合は、全レプリカを入れ替えたあとに、取り残されたページを次のコマンドで直せます。
crowi-admin page-history repair --transitionsページ履歴の追跡状態が保存で戻らなくなったリリース
以前の版では、古い状態のまま保存されたページが履歴の記録を失い、同じ連番のリビジョンが重複することがありました。全レプリカを止めて揃えて入れ替え、起動したあとに、次のコマンドを 1 回実行してください。戻ったページは記録中に復旧され、連番が重複したページは blocked として報告されます。
crowi-admin page-history repair --outbox --scanAPI のパスから v2 が外れたリリース
api の公開 HTTP prefix は /api/v2 ではなく /api になりました。これは公開パスの名前を変えただけで、新旧のパスを並行して使える移行期間はありません。旧 prefix へのリダイレクトや alias は用意されていないため、新旧のレプリカが混在した fleet では、どちらの prefix を使ってもおよそ半分のリクエストが 404 になります。
load balancer 経由では、リクエストごとに 1 台しかサンプリングできません。トラフィックを流す前に、デプロイツールの「完了」シグナルだけを信用せず、各レプリカへ個別に次を確認してください。
GET /api/openapi.jsonが全レプリカで 200 を返す。GET /api/v2/openapi.jsonが全レプリカで 404 を返す。
どちらかを満たさないレプリカは、まだ切り替わっていません。ロールバック時は同じ確認を逆向きに行います (/api/openapi.json が 404、/api/v2/openapi.json が 200)。ロールバックも全レプリカを揃えて行ってください。混在した fleet では、部分アップグレードと同じ問題が起きます。
レンダラのバージョンが上がるリリース
ページのレンダリング結果はリビジョンに保存されており、保存時のレンダラのバージョンが稼働中のものと完全に一致するときだけそのまま使われます。バージョンが上がると、古いページは表示のたびに再レンダリングされます (結果は保存されません)。デプロイの直後に一度、保存済みの結果を作り直してください。
crowi-admin rebuild rendered-astこのコマンドは冪等です。全レプリカが新バージョンで動いていることを確認してから最後にもう一度実行し、対象が 0 件になれば完了です (旧バージョンのレプリカが残っていると、古い形式のリビジョンが新しく作られ続けます)。
Redis のエンドポイントを入れ替えるとき
停止と起動の手順は上と同じですが、切り替え前に古いインスタンスのコーディネーション state をクリアする必要があります。手順は Redis の運用 を参照してください。