はじめに
「既にサポート終了になっているRedmine 5.1。これをバージョンアップしたい」がそもそものきっかけ。
しかし、Redmineのメジャーバージョンアップは、RubyやRailsの更新だけではありません。利用しているプラグインやテーマとの互換性、添付ファイル、データベース、さらにはWebサーバーやWAFとの兼ね合いまで確認しなければならず、思いのほか確認項目は多くなります。
特に本番環境を運用している場合、「とりあえずアップデートしてみる」というわけにはいきません。
迂闊にアップデートするとRedmineそのものが動くならない事象が発生します。
そこで今回は、稼働中のRedmine 5.1環境をそのまま複製し、本番とは完全に独立した検証環境を同一サーバー上へ構築しました。
目的は単なるバックアップではなく、Redmine 6.xへの移行を何度でも試行錯誤できる環境を作ることです。
構築環境
今回の構成は次のとおりです。
| 項目 | 内容 |
|---|---|
| OS | Ubuntu 24.04 LTS |
| Webサーバー | Apache 2.4 |
| WAF | ModSecurity + OWASP CRS |
| Ruby | 3.2系(aptビルトイン) |
| Redmine | 5.1系 |
| データベース | MySQL 8.x |
| SSL | Let's Encrypt |
| 添付ファイル | S3互換ストレージ(Wasabi) |
同一サーバー上へ検証環境を追加するため、Apache・Ruby・MySQLは共有しながら、Redmine本体・データベース・ログ・添付ファイルのみを完全に分離します。
本番環境と検証環境の構成
今回の構成では、以下のように役割を分離しています。
| 項目 | 本番環境 | 検証環境 |
|---|---|---|
| URL | redmine.example.com | redmine-test.example.com |
| アプリケーション | /home/www-data/redmine | /home/www-data/redmine-clone |
| DocumentRoot | /home/www-data/redmine/public | /home/www-data/redmine-clone/public |
| データベース | redmine | redmine_clone |
| DBユーザー | redmine | redmine_clone |
| ログ | /var/log/redmine | /var/log/redmine-clone |
| 添付ファイル | /mnt/storage/redmine/files | /mnt/storage/redmine-clone/files |
このようにしておけば、本番環境へ一切影響を与えることなく、何度でもアップグレードの検証を繰り返せます。
さっくりしていそうでさっくりしない手順
あくまでも筆者の手順です。
- MySQLダンプを取得
- Redmine環境の(アプリの)クローン
1. まずはMySQLのダンプを取得する
アプリケーションをコピーする前に、現在のデータベースをバックアップしておきます。
※DB名、ユーザー名は自分の環境に合わせてください。
mysqldump \
--single-transaction \
--routines \
--triggers \
--default-character-set=utf8mb4 \
-u redmine \
-p \
redmine \
> redmine.sql
--single-transactionを利用しているため、InnoDB環境であればサービス停止なしで整合性の取れたバックアップを取得できます。
2. Redmine本体を複製する
アプリケーション本体は cp ではなく rsync を利用しました。
ACLや拡張属性も含めてそのまま複製できるため、権限周りで悩むことが少なくなります。
※ディレクトリ名も自分の環境に合わせます。
cd /home/www-data
sudo rsync -aX redmine/ redmine-clone/
ここではまだ添付ファイルやログは本番環境を参照しています。(エイリアスを切っているため)
次の手順で検証環境用へ切り替えます。
3. 添付ファイルとログを分離する
添付ファイルはS3互換ストレージをマウントしているため、検証用ディレクトリへ切り替えます。
※サーバ上にそのまま保存している場合でも容量に注意しましょう
cd /home/www-data/redmine-clone
sudo ln -sf /mnt/storage/redmine-clone/files files
続いてログディレクトリを作成します。
sudo mkdir -p /var/log/redmine-clone
sudo chown -R www-data:www-data /var/log/redmine-clone
sudo ln -sf /var/log/redmine-clone log
これで本番・検証それぞれのログを独立して取得できます。
4. 検証用データベースを作成する
MySQLへログインし、新しいデータベースとユーザーを作成します。
※DBの向き先は要注意です。パスワードもポリシーに則り、適切なものを指定します。
CREATE DATABASE redmine_clone CHARACTER SET utf8mb4;
CREATE USER 'redmine_clone'@'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON redmine_clone.* TO 'redmine_clone'@'localhost';
FLUSH PRIVILEGES;
5. ダンプをリストアする
取得したバックアップを検証用データベースへ投入します。
※※要注意※※
リストア先とリストア元は三回ぐらい深呼吸して、事前に確認しましょう。
「クローン先のDB名」が先で、「クローン元のダンプファイル」が後です。
mysql \
-u redmine_clone \
-p \
redmine_clone \
< redmine.sql
これでデータベースも本番環境と同じ状態になります。
6. database.ymlを書き換える
Redmineが参照するデータベースを検証環境へ向けます。
production:
- database: redmine
+ database: redmine_clone
- username: redmine
+ username: redmine_clone
password: ********
忘れがちですが、この変更をしないと検証環境が本番データベースへ接続してしまいます。死ぬほど笑えない事象は、往々にしてこういうところから始まります。(始まりました)
7. ModSecurityの除外設定を追加する (オプション)
今回はApacheでModSecurityとOWASP CRSを利用しています。
RedmineはPATCHやPUTなどのHTTPメソッドを使用するため、通常のCRSでは誤検知されるケースがあります。
本番環境ですでに除外ルールを適用している場合は、検証用ホスト名も同様に対象へ追加します。
- redmine.example.com
+ redmine.example.com
+ redmine-test.example.com
これを忘れると、画面上では保存ボタンを押しただけなのに403 Forbiddenになることがあります。
8. Apache VirtualHostを追加する
本番用VirtualHost/etc/apache2/sites-available/redmine.confをコピーし、/etc/apache2/sites-available/redmine-clone.conf
- ServerName
- DocumentRoot
- ErrorLog
- CustomLog
を検証環境用へ変更します。
例えば、
/home/www-data/redmine/public
を
/home/www-data/redmine-clone/public
へ変更し、
/var/log/redmine
も
/var/log/redmine-clone
へ変更します。
設定後は有効化してApacheを再読み込みします。
sudo a2ensite redmine-test.conf
sudo apache2ctl configtest
sudo systemctl reload apache2
動作確認
ここまで終わったら、検証環境へアクセスして以下を確認します。
- ログインできる
- チケット・Wiki・プロジェクトが一致している
- 添付ファイルが表示される
- ログが検証用ディレクトリへ出力される
- ModSecurityで403にならない
ここまで確認できれば、Side-by-Side構成のクローン環境は完成です。
おわりに
サーバー運用では「バックアップを取ってから更新する」は半ば常識になっています。しかし、メジャーバージョンアップのような大きな変更では、それだけでは十分とは言えません。
実際に必要なのは、「失敗してもやり直せる環境」を用意しておくことです。
今回のように本番と完全に切り離した検証環境を用意しておけば、Redmine 6.xへのアップグレードだけでなく、Rubyやgemの更新、不要プラグインの整理、設定変更なども心置きなく試せます。
運用者であれば「更新前にバックアップを取る」は自然とできるようになります。しかし、その先の「何度でも検証できる環境を用意する」まで仕組みにしておくと、運用はさらに一段安定します。
私自身、今回の移行作業ではこの検証環境のおかげで、結果として、一度きりの「勝負」ではなく、納得いくまで検証を重ねた上で本番移行へ臨めます。
コメントを残す