Redmine 4.x へのアップグレード作業手順(Kubernetes)
Redmine 4 にアップグレードしたいが、ローカルで検証しないまま Kubernetes 上でアップグレードの検証をするために試行錯誤した記録。
- 移行検証のためのテスト環境をローカルに作るのが面倒くさい方
- サービスの影響範囲が限られていて、数時間停止してもいいやと思っている方
- Kubernetes 上で動かすことはできたけど、その後のメンテナンスをどうやっていけばいいかわからない方
いずれかに該当する場合は役に立つ情報かもしれません。
前提
- sammersbn/redmine イメージを使ってRedmineを動かしています。
- もう何年もお世話になってます。完成度が高くて、これが無いとRedmineをセットアップ・運用したくないレベルの依存度
- 記事タイトルの通り、Kubernetes ホスト上で Docker コンテナを動かしています。
- Docker / Docker Compose ならばデータの実体も同一ホスト上にあるので分かりやすいですが、Kubernetes 上では PVC 等を用いてデータの実体は異なるところからマウントしているので、直感的ではない部分もあるでしょう(Kubernetes デプロイに慣れていない場合は)。
- そのため、Docker コマンドで操作するのとは異なる一癖があります。Kubernets の基本的なお作法を抑えておいたほうが、いざという時に落ち着いて対応できるはず。
- バックアップはしっかりとっておきましょう。
- これも、sameersbn/redmine イメージならコマンド1個でバックアップができてしまうので大変お手軽です。
作業前の準備
Redmineのプラグインが少なければ少ないほど、一発成功の可能性は高くなるでしょう。しかし、Redmineを使い込むほどプラグインは増えがちのはず。プラグインが多い場合、ほぼ確実に何かしらひっかかると思います。事前に一通りのプラグインのリストアップ、および最新バージョン・互換性の確認を強く推奨します。
バックアップ
なにはともあれ、まずはバックアップ。いざという時(最終手段)のよりどころです。
kubectl exec
でコンテナ内に入り込んで、sameersbn/redmine
で用意されているコマンドを実行します。
ちなみにコマンドは、/sbin/entrypoint.sh
および、引数として渡すサブコマンドで実行できます。バックアップのためのサブコマンドは app:backup:create
です。 https://github.com/sameersbn/docker-redmine/blob/4.1.1-2/entrypoint.sh
## コンテナに入る
kubectl -n <Namespace> exec -it <Podの名前を入力> bash
# Namespace: 自身の環境に合わせて置き換えてください。特に意識していないならば default です
## バックアップコマンドを実行
/sbin/entrypoint.sh app:backup:create
-- log --
Initializing logdir...
Initializing datadir...
... 中略
Creating backup archive: 1591455718_redmine_backup.tar...
Deleting old backups... (1 removed)
バックアップファイル(tar)は、/home/redmine/data/backups
配下に作成されるので、ローカルにコピーしておきます。うっかりVolumeさえ削除しなければ問題ないはずなので、念の為程度のものです。
なお、1591455718
は今回バックアップをとったタイムスタンプなので、都度変わります。
## リモートからローカルにコピー
kubectl -n <Namespace> cp <Podの名前>:/home/redmine/data/backups/1591455718_redmine_backup.tar 1591455718_redmine_backup.tar
ちなみに、docker-compose
ならこんな感じでしょうか。
docker-compose run redmine sameersbn/redmine:<使っているバージョン> app:backup:create
リストアする場合
今回リストアする状況に至りませんでしたが、これも以下の1コマンドでお手軽です。.tar
の中身は、コンテンツ(画像とかの)ファイル群、および SQL のダンプなので、サブコマンドに頼らずに1個1個手動でやることも可能です。
docker-compose run redmine sameersbn/redmine:<使っているバージョン> app:backup:restore
詳細は 公式ドキュメントを参照してください。
バージョンアップの基本動作
さて本題です。今回のケースでは、Redmine 3.4系からRedmine 4.1系へのアップグレードをすることになりますが、まずは 4.0 系で動くことを確認したあとに、4.1系へのアップグレードとしました。
1. 既存バージョンでプラグインをアップデートする
- 面倒臭さとのトレードオフですが、1個1個試したほうが確実です。
- プラグインをアップデートすると、**既存Redmineバージョンは動作対象外になっていて最新Redmineバージョンでしか動かない互換性のケース**もあったりするので、事前に提供元サイトを見ておくのが無難でしょう。
2. プラグインをアップデートしてPodが起動しなくなったら、`command: seleep 3600` として空で立ち上げた上でトラブルシュートやデータ補正
3. 設定を戻して Pod を削除、自動起動のうえ正常性確認
4. 既存Redmineバージョンで動くことが確認できたら、新Redmineバージョンにアップグレード
- 操作的には、`sameersbn/redmine` イメージのタグを書き換えるだけ。直感的です。
- 既存バージョンでプラグインをアップデートする
- 面倒臭さとのトレードオフですが、1個1個試したほうが確実です。
- プラグインをアップデートすると、既存Redmineバージョンは動作対象外になっていて最新Redmineバージョンでしか動かない互換性のケースもあったりするので、事前に提供元サイトを見ておくのが無難でしょう。
- プラグインをアップデートしてPodが起動しなくなったら、
command: seleep 3600
として空で立ち上げた上でトラブルシュートやデータ補正 - 設定を戻して Pod を削除、自動起動のうえ正常性確認
- 既存Redmineバージョンで動くことが確認できたら、新Redmineバージョンにアップグレード
- 操作的には、
sameersbn/redmine
イメージのタグを書き換えるだけ。直感的です。
- 操作的には、
以後、2〜4 の繰り返し
sleep している理由
プラグインアップデート後にRedmineが起動しない(すなわち、Railsが起動しない)場合、コンテナはクラッシュしたものと扱われます。そうなると、kubectl exec
で Pod 内に入り込むこともできません。それではトラブルシュートができずに困りますので、コンテナ起動コマンド(command
)を seleep 3600
で上書きして、とりあえずコンテナが起動できる状態にします。
手段は、手元に Deployment
のコンフィグがあるならば、Containers
のセクションで command:
で上書きして kubectl apply -f
しますし、手元になければ kubectl edit deploy ...
にてターミナル上で直接編集します(後者の場合、慎重に!)
記載内容は以下の通り。
spec:
containers:
- command:
- sleep
- "3600"
command:
について:Define a Command and Arguments for a Container - Kubernetes
sameersbn/redmine イメージの特徴
内容的には sleep しているだけなので、コンテナは何もしていません。この隙に kubectl exec
でコンテナ内に入って、プラグインの差し替えやログ確認など、トラブルシュートします。以下の点をおさえておけば、なんとかなるかと思います。
/home/redmine/data/plugins
に、volumeMounts しているプラグインデータの実体がある- 一方で、Redmineコンテナ起動時に使っているプラグインデータは
/home/redmine/redmine/plugins
にある(/home/redmine/redmine
がアプリケーションのROOT)- 本来、
sameersbn/redmine
の起動スクリプト/sbin/entrypoint.sh app:start
にて、/home/redmine/data/plugins
から/home/redmine/redmine/plugins
へ コピーされる sleep
で起動している現状は、app:start
サブコマンドを実行していないので、データは空
- 本来、
- データ補正が終わったら
/sbin/entrypoint.sh app:start
を実行すると、Redmineの起動を試行できる- そこで問題なく起動すれば作業完了
- 何かしらエラーが出る場合は、そのエラーメッセージに準じてプラグインの見直しをする
- 同じコンテナ内で2回目の
app:start
を実行をする場合は、2種類の plugins ディレクトリそれぞれ意識する必要がある- 大本の
/home/redmine/data/plugins
だけ弄っても、コピー先の/home/redmine/redmine/plugins
に残骸が残っていて「直したはずなのに起動しない(実は変わっていない)」ということが起きるので混乱しないように気をつける
- 大本の
ちなみに参考(プラグインのアップデート)
今回試した環境では以下のPluginを利用しています。GitHubから取得できるプラグインは clone
してそのまま配置しているので、アップデートも git pull
を実行して一気に最新化する、ちょっと強引な手段をとっています。基本的にはこれで問題は起きていません。
git pull だけで済んだもの
Redmine 4 そのものは 2018-12-09 にリリースされていますので、現在1年半経過しています。なのでオフィシャルレポジトリでの対応も大部分が済んでいるでしょう。逆に今でも終わっていないものはメンテナンスが停滞しているとも言えます。
cd ./plugins/redmine_default_custom_query; git pull
cd ./plugins/redmine_issue_templates; git pull
cd ./plugins/redmine_wiki_extensions; git pull
cd ./plugins/view_customize; git pull
cd ./plugins/redmine_pivot_table; git pull
cd ./plugins/redmine_github_hook; git pull
cd ./plugins/redmine_issues_summary_graph; git pull
(お試しで入れてるだけで本格利用はしていない)
いくつか、pull
が完了しないものがあったりします。これはローカルファイルのパーミッションなんかが変わっていて差分が発生してしまうためです。経験上、この変更が重要だったことはないので、git stash
で一時退避したあとに再度 pull
して上書きしてしまいます。
オフィシャル対応が済んでいないもの
Redmineはバージョンアップが数年周期に行われるので(メジャーアップは3年?)、メンテナンスが終了・停滞してしまっているプラグインもやはり出てきます。そんなときはまず、GitHubのPull Request を見ましょう。多くの場合は Redmine 4.x 対応のような Pull Request が出されていて、あとは Mergeだけすればいいような状況だったりします。
- clipboard_image_paste
- 個人的にこれは非常に重要です。テキスト何十行にも及ぶ記述よりも1個の画像の方が正確な場面はよくありますよね。しかし、いちいちローカルに画像を保存して、よくあるエクスプローラーの操作でファイル選択するのは非常に煩わしい・・・。そんな悩みを解決してくれるプラグインです。クリップボードの画像を
Ctrl + V
で一発挿入してくれます。 - しかしオフィシャルレポジトリは Redmine 3.x で停滞しているようです。
- この Pull Request を使いましょう Updates to make plugin work with next Redmine V4.0.0 by Utopism · Pull Request #80 · peclik/clipboard_image_paste
git clone <https://github.com/Utopism/clipboard_image_paste.git
>
- 参考:オフィシャル peclik/clipboard_image_paste: Redmine plugin for pasting cropped image from clipboard as an attachment.
- 個人的にこれは非常に重要です。テキスト何十行にも及ぶ記述よりも1個の画像の方が正確な場面はよくありますよね。しかし、いちいちローカルに画像を保存して、よくあるエクスプローラーの操作でファイル選択するのは非常に煩わしい・・・。そんな悩みを解決してくれるプラグインです。クリップボードの画像を
廃止したプラグイン
この期に整理(削除)したプラグイン達。
- Easy Gantt (Free版) もセットアップしていたのですが、この期に削除しました。
sameersbn/redmine
では Plugin ディレクトリにプラグインファイルを配置するだけでDBマイグレートを自動でやってくれるのですが、Easy Gantt に限っては、初期セットアップ時にそれだけでは済まなかった気がします(うろ覚え)。Plugin以外にもrake db:migrate
も実行したような・・・。- マイグレーションの数は多くないので、最悪手動でメンテすればいいかと、プラグインファイルの削除だけで妥協しました。
- redmine_agile
- 見た目かっこよかったので入れていたのですが、無料版だと機能が限定的で、実用的に使うのは少々難しかったので削除。
- Migrationがあるので
redmine:plugins NAME=redmine_agile RAILS_ENV=production
しないといけない(やりそびれたので、後でやらないと・・。) - https://www.redmine.org/plugins/redmine_agile
- redmine_tweaks
- Redmineを使い始めた初期は、かなりお世話になりました。メンテナンスはとっくに終わっていますし、いくつかのプラグインを組み合わせて代替手段も確立できているので削除。
- Migrationが無いのでプラグインファイルを削除するだけなのですが、このプラグインはRedmine本体のDBにレコードを保存するので、お行儀に少々難あり。
Setting
だったかのモデル操作をしていて、ファイルを消すだけだと完全とは言えないのですが、実害はないと思うので放っておきます。 - https://github.com/AlphaNodes/redmine_tweaks
新たにセットアップしたプラグイン
久々に Redmine のプラグインを整理したので、気になっていたけど手を出していなかったものをお試し導入。
Redmine Issue Checklist Plugin
チケット運用をしているとありがちな、「細かいアクションを書きたいのだけど、子チケットを作成するほどでも無いんだよな・・・」というシーンで、GitHubでの [ ] ToDo
/ [x] Completed ToDo
のようなチェックリストを使いたいニーズを解決してくれるもの。
Official Repository は Restream/redmine_issue_checklist: Checklist Plugin creates simple checklists for Redmine issues. ですが、数年更新が止まっていて Redmine 4.x 対応はダメそう(2020/06/07時点)
Redmine 4.x 対応の Pull Request があるので、これを利用しましょう。 Make checklist plugin compatible to Redmine 4.0.4 by lammel · Pull Request #34 · Restream/redmine_issue_checklist
## コンテナ内の Plugins ディレクトリで
git clone -b bugfix/redmine40-compat https://github.com/lammel/redmine_issue_checklist.git
そしてコンテナを再起動して Plugin の Migration が実行されますが、失敗するはずです。
Caused by:
StandardError: Directly inheriting from ActiveRecord::Migration is not supported. Please specify the Rails release the migration was written for:
class CreateIssueChecklists < ActiveRecord::Migration[4.2]
/home/redmine/data/tmp/bundle/ruby/2.4.0/gems/activerecord-5.2.4.2/lib/active_record/migration.rb:528:in `inherited'
/home/redmine/redmine/plugins/redmine_issue_checklist/db/migrate/20111010202847_create_issue_checklists.rb:1:in `<top (required)>'
/home/redmine/data/tmp/bundle/ruby/2.4.0/gems/activesupport-5.2.4.2/lib/active_support/dependencies.rb:291:in `require'
1ファイル、若干修正する必要があります。redmine_issue_checklist/db/migrate/20111010202847_create_issue_checklists.rb
を以下のように修正(追記)します。
## 変更前
class CreateIssueChecklists < ActiveRecord::Migration
## 変更後
class CreateIssueChecklists < ActiveRecord::Migration[4.2]
Rails 5 にて導入された Migration Versioning による変更です。 参考: Add migration versioning via Migration subclasses by matthewd · Pull Request #21538 · rails/rails
この変更により、Migrationが成功するでしょう :)
Migrating plugins. Please be patient, this could take a while...
== 20111010202847 CreateIssueChecklists: migrating ============================
-- create_table(:issue_checklists, {:options=>"ENGINE=InnoDB", :id=>:integer})
-> 0.0300s
== 20111010202847 CreateIssueChecklists: migrated (0.0311s) ===================
Redmine Issue Badge Plugin
akiko-pusu/redmine_issue_badge: Plugin to show the number of assigned issues with badge on top menu.
自身のみ完了チケットを、画面右上に常時バッジで表示してくれます。これいいですね・・・!
これまで工夫として「自身の担当チケット」へのリンクをヘッダーに配置したり、メンバーが少しでもチケットを消化してくれるよう導線を設計してきたのですが、メンバーが多数いると全員への意識付けもそう簡単ではありません。ですが、このように「バッジ」が表示されると、気になる人は潰しにかかってくれる気がします。
「どれがいい」ではなくて、「あらゆる手段で」導線を設けて、健全なチケット運用をしていきたいところ。
redmine-atjs
evolvingweb/redmine_atjs: Integration of redmine with at.js
本文中にチケット間を参照する際に、対象のチケット番号を調べるのって今のRedmineのUIだと面倒くさいですよね・・・。これを使うと #
を入力した時点で候補がリストアップされ、文字で絞り込みができるので操作性が激向上しそうです。日本語もOK。
Support multi-word searching (IMPORTANT)consider creating AtjsController to provide optimized/customizable autocomplete endpoint.
write tests
複数ワードでの補完が重要課題になっているようですが、いまのシングルワードでも十分な実用性だと感じます。
Redmine Indicator
少しでも視覚的な情報があれば、チケット消化意識が進まないかなと。バージョンは若いですが、ここ最近いでも Commit が発生しているようなので、期待しつつ様子見。
まとめ
Kubernetes コンテナで動かしているRedmineのバージョンアップや、プラグインアップデートの試行錯誤を記録しました。
今回は手元の開発環境の都合でローカルセットアップができなかった(普段遣いの macOS ハード故障中・・・)ので、直接 K8s ホスト上で実行することにしました。メンテナンスでのダウン時間が許容できるなら特に問題にならないかと思いますが、メジャーバージョンアップはトラブルも多いので、しっかりローカルで検証してから本番に挑みたいですね。
OpenProjectも気になるんですが、やはりsameersbn/redmine
イメージをやめるほどのモチベーションはなく、今後もお世話になります。
なお、プラグイン開発やバージョンアップでの考慮点はこちらも参考になります。Redmine4時代のプラグイン開発 redmine.tokyo #13