最近、とあるお仕事で長年運用してきたRedmine v1.4をRedmine v5.1へアップグレードしました。
Redmineの構築は約10年ぶり。作業しながらだんだん思い出してきましたが、Redmineのインストールはとても面倒です。Redmineの、というよりは、Ruby on Railsベースのアプリの、というほうが正しいのかもしれませんが。
作業のログを残しておきます。
要件
- OSのEOSL対応。元々Redmineを運用してきたサーバーのOSのEOSL対応が必要なため、別途新しくサーバーを用意してRedmineをインストールする。
- 基盤をさくらのVPSからAWSへ移行。構築や運用における様々な利便性を考慮し、新しいサーバーOSはAWS上に構築する。
- 旧環境のデータを新環境へ移行。旧環境のRedmineからデータベース内の全データとディスク上の添付ファイルを移行する。
- DBもEOSL対応。OS同様にEOSL対応が必要なため、新しいサーバー上に最新のMySQLをインストールする。
- RDS化やコンテナ化はなし。移行対象のRedmineはアクセス数もデータ量も限られ、SLAもとくに考慮しなくていい環境のため、1つのEC2インスタンス上ですべて完結させることとする。技術的には魅力的ではあったがコスト最適の観点で思いとどまった。
スペック比較
今回のアップグレードによる旧環境と新環境のスペック(バージョン等)を対比すると以下のようになる:
項目 | 旧環境 | 新環境 |
---|---|---|
サーバースペック | 仮想コア2、メモリ1GB、HDD100GB | 仮想コア2、メモリ0.5GB、HDD10GB(インスタンスタイプにt4g.nano、EBSにgp3を使用) |
OSディストリビューション&バージョン | CentOS v6.8 | Amazon Linux 2023(minimal) |
Rubyバージョン | v1.9 | v3.2 |
Apache httpdバージョン | v2.2 | v2.4 |
MySQLバージョン | v5.1 | v8.0 |
Redmineバージョン | v1.4 | v5.1 |
EC2インスタンスタイプは基本的には t4g.nano
なのだが、bundle install
やgem install
実行時だけ一時的に t4g.xlarge
に引き上げている。gem install
は依存関係の解決とビルドに大きなリソースを要求するようで、nano
のままでは実質的にハングしてしまったため。
手順1:仮想マシンの作成
インスタンスタイプはt4g.nano
。とにかく安価なオプションを求めていたので、サイズは最小しかもARMアーキテクチャを選択。
AMIは amazon/al2023-ami-minimal-2023.4.20240319.1-kernel-6.1-arm64
。
OSのディストリビューションは旧環境がCentOSであったため、Amazon Linux 2023を選択した。CentOSの後継としてはRockyなど複数がありえたが、AWS上で運用する上で「あえて」Amazon Linux以外を選ぶ理由が今回はなかったので。
さらにディスク容量もなるべく節約したかったため、Amazon Linux 2023のAMIのうちでも「minimal」のものを利用。
作成した仮想マシン(EC2インスタンス)にはSSH接続およびSFTP接続を行うためのセットアップをいたしましたが、この記事の趣旨とはあまり関係がないので、ここではその手順は割愛いたします。
手順2:パッケージのインストール
RubyやApache httpdをはじめとしたパッケージをインストール。まずはdnf
でインストールできる範囲。
sudo dnf install ruby3.2 ImageMagick ghostscript httpd
Apache httpdをサービスとして起動しておく:
sudo systemctl start httpd
sudo systemctl enable httpd
Amazon Linux 2023の標準YumリポジトリーにはMySQLが含まれないため、MySQLのサイトからPRMを入手する。
MySQL Yum Repositoryにリストアップされたもののうち、以下のRPMを利用した:
Red Hat Enterprise Linux 9 / Oracle Linux 9 (Architecture Independent), RPM Package
(mysql80-community-release-el9-5.noarch.rpm)
sudo dnf localinstall https://dev.mysql.com/get/mysql80-community-release-el9-5.noarch.rpm
sudo dnf install mysql-community-server mysql-community-client
MySQLをサービスとして起動しておく:
sudo systemctl start mysqld
sudo systemctl enable mysqld
さらにbundle install
やgem install
で依存性解決とビルドを行うために必要になるパッケージをインストール:
sudo dnf groupinstall "Development Tools"
sudo dnf install ruby-devel openssl-devel readline-devel zlib-devel curl-devel libffi-devel mysql-community-devel httpd-devel libpq-devel
ここでははじめからインストールすべきパッケージが分かっているかのような書き方になっていますが、実際にこのアップグレードを行った時にはトライ&エラーでした。bundle install
やgem install
の実行中に様々な依存性不足のエラーに見舞われており、そのたびdnf install
で不足している依存性(パッケージ)をインストールしています。
手順3:旧環境のデータを転送
旧環境から各種データをエクスポートして新環境に転送する。
まずはデータベースをダンプしてGZIP圧縮(データベースのユーザー名やデータベース名は適宜読み替えて):
mysqldump -u redmine_user -p redmine_db | gzip > redmine_db_`date +%y_%m_%d`.gz
次に添付ファイルをTARアーカイブ化してGZIP圧縮(Redmineのインストール・ディレクトリは適宜読み替えて):
tar zcvf redmine_files_`date +%y_%m_%d`.tar.gz /var/lib/redmine/files
さらに設定ファイルをTARアーカイブ化してGZIP圧縮(同上):
tar zcvf redmine_config_`date +%y_%m_%d`.tar.gz /var/lib/redmine/config
これらのGZIPファイルを新環境の仮想マシンにアップロードしておく。
言うまでもないことですが、いずれのコマンドについても、ファイルパスやデータベース・ユーザー名、データベース名などは旧環境のインストール状況にあわせて指定する必要があります。
手順4:空のデータベースを作成
先ほどMySQLを起動した時にMySQLが出力したログから、root
ユーザーの初期パスワードを入手する:
cat /var/log/mysqld.log |grep "A temporary password"
パスワードの規則を厳格化し、root
ユーザーのパスワードを変更し、不要なデータベースを削除する:
mysql_secure_installation
MySQLデータベースに接続し:
mysql -u root -p
空のデータベースを作成する:
CREATE DATABASE redmine_db CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
CREATE USER 'redmine_user'@'localhost' IDENTIFIED BY 'xxxx';
GRANT ALL PRIVILEGES ON redmine_db.* TO 'redmine_user'@'localhost';
旧環境のデータベースのダンプ・ファイルを解凍して、今しがた作成した空のデータベース上に復元する:
tar -zxvf redmine_db_...gz
mysql -u user_redmine -p db_redmine < redmine_db_...
手順5:Redmineをインストール
Redmineの公式サイトのLatest releasesページから、最新のstableなリリースのtar.gz
ファイルをダウンロードし、新環境の仮想マシン上にアップロードする。
今回は redmine-5.1.2.tar.gz
:
ファイルを解凍・展開して /var/lib/redmine
として配置(移動&リネーム):
tar -zxvf redmine-5.1.2.tar.gz
sudo mv redmine-5.1.2 /var/lib/redmine
旧環境から転送してきた添付ファイルを /var/lib/redmine/files/
配下に配置:
tar -zxvf redmine_files_24_03_23.tar.gz
sudo mv files/* /var/lib/redmine/files/
旧環境から転送してきた設定ファイルを /var/lib/redmine/config/
配下に配置。
今回のアップグレード対応では database.yml
と configuration.yml
のみを配置しているが、必要に応じて他のファイルも配置する:
tar -zxvf redmine_config_24_03_23.tar.gz
sudo cp config/database.yml /var/lib/redmine/config/
sudo cp config/configuration.yml /var/lib/redmine/config/
設定ファイルに記述されているデータベースの接続情報を、新環境のデータベースにあわせて修正する。またアダプター名が mysql
となっていたので、 mysql2
に書き換え:
sudo vi /var/lib/redmine/config/database.yml
build install
コマンドを実行する前にEC2インスタンスのインスタンスタイプを t4g.nano
からt4g.xlarge
に変更。
t4g.nano
のままbuild install
コマンドを実行すると、スペック不足のためか、依存性解決の開始後その先に処理が進まなくなってしまい、事実上のハング状態となってしまいました。このため一時的にインスタンスタイプを変更しています。xlarge
を選んだことにとくに理由はなく、「さすがにこれくらいあれば十分だろう」と思ってこうしたというにすぎません。。
Redmineの依存性解決とビルドのためにbuild install
を行う:
cd /var/lib/redmine/
sudo bundle install --without development test
Railsがセッション情報の管理に使用するCookieの暗号化に使用するトークンを(再)生成:
sudo bundle exec rake generate_secret_token
インスタンスタイプをt4g.xlarge
から t4g.nano
に変更(元に戻す)。
戻し忘れに注意してください。言うまでもないことですが戻し忘れるとEC2インスタンスの利用料として無用なコストを払うことになります。
データベースをバージョンアップしているのでマイグレーションを実行:
sudo bundle exec rake db:migrate RAILS_ENV=production
手順6:Passengerをインストール
Railsアプリケーションを実行するためのApache httpdモジュール Passengerをインストールする。
sudo gem install passenger
sudo passenger-install-apache2-module
インストールが完了すると、以下のようなメッセージが表示され、Apache httpdの設定ファイルの編集を案内される:
Please edit your Apache configuration file, and add these lines:
LoadModule passenger_module /usr/local/share/ruby3.2-gems/gems/passenger-6.0.20/buildout/apache2/mod_passenger.so
<IfModule mod_passenger.c>
PassengerRoot /usr/local/share/ruby3.2-gems/gems/passenger-6.0.20
PassengerDefaultRuby /usr/bin/ruby3.2
</IfModule>
After you restart Apache, you are ready to deploy any number of web
applications on Apache, with a minimum amount of configuration!
Press ENTER when you are done editing.
/ect/httpd/conf.module.d/passenger.conf
を作成して、指示された内容+αを書き込む。今回は サイトのルート・ディレクトリでRedmineを配信するのでドキュメント・ルートを/var/lib/redmine/public
とする。これに伴う権限設定をDirectory
ディレクティブで行っている:
sudo vi /ect/httpd/conf.module.d/passenger.conf
LoadModule passenger_module /usr/local/share/ruby3.2-gems/gems/passenger-6.0.20/buildout/apache2/mod_passenger.so
<IfModule mod_passenger.c>
PassengerRoot /usr/local/share/ruby3.2-gems/gems/passenger-6.0.20
PassengerDefaultRuby /usr/bin/ruby3.2
Header always unset "X-Powered-By"
Header always unset "X-Rack-Cache"
Header always unset "X-Content-Digest"
Header always unset "X-Runtime"
</IfModule>
<Directory "/var/lib/redmine/public">
Require all granted
</Directory>
passenger.conf
は旧環境では/etc/conf.d/
配下に作成していましたが、新環境では/ect/httpd/conf.module.d/
配下に作成しています。これはApache httpdにより自動的に読み込まれるモジュールの設定ファイルの置き場所が変わったためです。
前述の通りドキュメント・ルートを/var/lib/redmine/public
とするのでその設定を httpd.conf
に行う:
sudo vi /ect/httpd/conf/httpd.conf
DocumentRoot /var/www/html
となっている行をコメントアウトし、 DocumentRoot /var/lib/redmine/public
という行を追加する。
ここまで追加した各種ファイルについてオーナーを root:root
からapache:apache
に変更する:
sudo chown -R apache:apache /var/lib/redmine
Apache httpdを再起動して設定を反映させる:
sudo systemctl restart httpd
今回は サイトのルート・ディレクトリ(例:http://www.example.com/
)でRedmineを配信するのでこのような設定になりました。
サブディレクトリ(例:http://www.example.com/redmine/
)で配信する場合はhttpd.conf
とpassenger.conf
の記載内容が異なってくるのでご注意ください。
どうにかこうにかRedmineのアップグレードが完了。。