Crowi

バージョンアップ

Crowi を新しいバージョンに入れ替える手順と、版ごとに必要な追加作業

基本の手順

  1. リリースノートで、入れ替える版までの間に追加作業があるかを確認する。
  2. バックアップを取る。
  3. 全レプリカを揃えて停止する (下記)。
  4. イメージのタグを新しいバージョンに書き換え、全レプリカを起動する。
  5. GET /api/app/info が 200 を返すことを確認する。
  6. 下の「版ごとの注記」に該当するものがあれば実行する。

全レプリカを揃えて入れ替える

api レプリカを 1 台ずつ入れ替えるローリング再起動はしないでください。 Crowi の一部のリリースでは、新旧のレプリカが同じプールに同時に存在すると、どちらの世代が受けたかによって結果が変わります。全 api レプリカを揃えて停止し、全レプリカへ新しいバージョンをデプロイしてから揃えて起動してください。新しいバージョンで別の fleet を用意し、トラフィックを一括で切り替える (blue/green) 方法でも構いません。

レプリカが 1 台だけの構成 (開発環境を含む) は、この条件を自動的に満たします。新旧が混在しようがないためです。

版ごとの注記

アカウント連携が入ったリリース

新しいバージョンのレプリカは、外部アカウントの連携フローごとに専用の state cookie を発行します。旧バージョンのレプリカはその名前を知らず、サインイン用の固定 state cookie を読もうとして、しかも検証前にそれを削除します。混在した fleet では、旧レプリカに着地した callback が進行中の連携を壊すだけでなく、同時に進行していた無関係な通常のサインインまで壊します。2 つの世代をつなぐ互換経路はありません。上記のとおり揃えて入れ替えてください。

ページ履歴の移動状態が入ったリリース

ページの rename・ゴミ箱への移動・復元が「移動中」という状態を経由するようになりました。この状態を知らない旧バージョンのレプリカは移動中のページを通常のページとして扱い、別の移動を重ねて開始しえます。そうなるとどちらの移動も完了せず、ページは移動中のまま取り残されます (利用者にはページが消えたように見えます)。

混在させてしまった場合は、全レプリカを入れ替えたうえで回収できます。

crowi-admin page-history repair --transitions

API のパスから v2 が外れたリリース

api の公開 HTTP prefix は /api/v2 ではなく /api になりました。これは境界の rename であり、段階的なバージョン展開ではありません。旧 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 の運用 を参照してください。

次のステップ

On this page