こんにちは、テクマトリックスの村上です。
以前、社内利用のRedmineをEC2のDockerコンテナに移行しましたが、本件では移行したRedmineとデータベースをバージョンアップしたので、詳細を記載します。

バージョンアップのきっかけ

移行してから時間が経ちましたが、Redmineのバージョンアップをしていませんでした。
Redmineの新しいバージョンがリリースがされているため、脆弱性の対応や新機能を使えるようにバージョンアップを行います。

バージョンアップをするRedmineの環境情報

Redmineの情報は以下です。

RedmineのバージョンRedMica2.0.0(Redmine5.0.0)
利用しているOSSプラグイン・Redmine Startpage plugin
・Redmine Lightbox 2
・View Customize plugin
DBの種類とバージョンPostgreSQL 14.5

バージョンアップ後のRedmineの環境情報

バージョンアップ後のRedmineは以下で、RedmineとOSSプラグイン(View Customize plugin)、PostgreSQLのバージョンアップを行います。Redmine Startpage pluginは利用していないため、アンインストールを行います。

RedmineのバージョンRedmine5.1.7
利用しているOSSプラグイン・Redmine Lightbox 2
・View Customize plugin
DBの種類とバージョンPostgreSQL 17.4

バージョンアップの手順

①バックアップの取得

バックアップを取得するために、環境構築時に作成していたバックアップを取得するshellを実行します。実行後は、バックアップファイルが取得されていることを確認します。

bash /opt/redmine/backup.sh


[参考]バックアップ取得用のshellは以下です。

#!/bin/sh

#dumpファイルを取得
docker exec redmica_db_1 pg_dump -Uユーザー名 --if-exists -c redmine > /tmp/redmine_`date "+%Y%m%d"`.pgdump
#圧縮して保存場所に配置
tar -zcvf 保存先ディレクトリ/redmine_`date "+%Y%m%d"`.pgdump.tar.gz /tmp/`date "+%Y%m%d"`.pgdump

#不要ファイルの削除
rm  /tmp/redmine_`date "+%Y%m%d"`.pgdump

#filesを圧縮
tar -zcvf 保存先ディレクトリ/redmine_`date "+%Y%m%d"`.file.tar.gz filesディレクトリ

取得したdumpファイルを開き、最終行あたりに「GRANT ALL ON SCHEMA public TO postgres;」が記載されているかを確認します。記載がある場合は、docker-compose.ymlの「POSTGRES_USER」を確認し、「postgres」以外を指定してる場合は削除します。Redmineのデータベースでは、「POSTGRES_USER」で指定したユーザーを利用しているため、postgresを利用していない場合は、該当の箇所は不要です。

「postgres」以外を指定してる状態で、該当の箇所を削除しない場合、リストア時に「ERROR: role “postgres” does not exist」のエラーが発生します。

ALTER TABLE
ALTER TABLE
ALTER TABLE
ERROR: role "postgres" does not exist

②Redmineとデータベースのコンテナを削除

起動しているコンテナを削除します。

$ cd [docker-compose.ymlを配置しているのディレクトリ]
$ docker-compose down

③docker-compose.ymlとDockerfileを編集し、バージョンを書き換え
設定ファイルに記載されているRedmineとPostgreSQLのバージョンを書き換えます。
※今回のバージョンアップでは、REDMINE_SECRET_KEY_BASEも追記しました。追記しないとRedmineのコンテナ起動時にエラーが発生します。

services:
  redmine:
    build: .
    environment:
      REDMINE_DB_POSTGRES: db
      REDMINE_DB_PASSWORD: パスワード
      REDMINE_DB_DATABASE: データベース名
      REDMINE_DB_USERNAME: ユーザー名
      REDMINE_PLUGINS_MIGRATE: 1
      REDMINE_SECRET_KEY_BASE: 任意のシークレットキー 
      TZ: Asia/Tokyo
    ports:
            - ポート番号:3000
    privileged: true
    volumes:
      - ./data/plugins:/usr/src/redmine/plugins
      - ./data/files:/usr/src/redmine/files
    restart: always
  db:
    #バージョンの変更
    image: postgres:17.4
    environment:
      POSTGRES_ROOT_PASSWORD: パスワード
      POSTGRES_USER: ユーザー名
      POSTGRES_PASSWORD: パスワード
      POSTGRES_DATABASE: データベース名
      TZ: Asia/Tokyo
      POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --locale=C"
    restart: always
#Redmineのバージョンを変更
FROM redmine:5.1.7

# システム設定
ENV LANG=ja_JP.UTF-8 \
    LC_ALL=ja_JP.UTF-8
RUN apt-get -y update
RUN apt-get -y install -y libjpeg62 libfontconfig-dev unzip wget libxrender1 make g++

#設定ファイルをコピーして配置する
COPY ./data/config/configuration.yml /usr/src/redmine/config/
COPY ./data/config/environment.rb /usr/src/redmine/config/
COPY ./data/config.ru /usr/src/redmine/
COPY ./data/config/environments/production.rb /usr/src/redmine/config/environments/

RUN bundle install --without development test

④プラグインのアンインストール
利用しているRedmine Startpage pluginプラグインは、インストール時にマイグレーションを行っていないため、フォルダの削除のみ行います。

$ rm -rf [docker-compose.ymlを配置しているディレクトリ]/data/plugins/redmine_startpage

※プラグインによっては、インストール時にマイグレーションコマンドを実行しているものがあり、その場合はアンインストールコマンドを実行します。実行後は、手順バックアップの取得を再度行い、手順⑦のバックアップファイルの復元には、ここで取得したバックアップファイルを利用します。
アンインストールコマンドを実行するか(インストール時にマイグレーションコマンドを実行していたか)どうかは、各プラグインのダウンロードページにあるインストール手順を確認してください。


⑤プラグインのバージョンアップ

View Customize pluginのバージョンアップを行います。バージョンアップには、ファイルの差し替えを行います。

$ rm -rf [docker-compose.ymlを配置しているディレクトリ]/data/plugins/view_customize
$ cd [docker-compose.ymlを配置しているディレクトリ]/data/plugins/
$ git clone https://github.com/onozaty/redmine-view-customize.git view_customize

※View Customize pluginは、バージョンアップ時にマイグレーションコマンドの実行が必要ですが、本環境の場合は、手順⑧にて復元したデータベースに対し、マイグレーションが自動で実行されます。

⑥Redmineを起動
コンテナを再構築します。

$ cd [docker-compose.ymlを配置しているディレクトリ]
$ docker-compose build
$ docker-compose up -d

⑦バックアップファイルを復元
手順①で取得したdumpファイルを利用して、データベースの復元を行います。添付ファイル(files)は、volume設定により永続化しているため、作業は不要です。

【EC2上で操作】

#DBコンテナにダンプファイルをコピー
$ docker cp 保存先ディレクトリ/バックアップファイル名 redmine-db-1:/tmp

#Redmineコンテナを停止
$ docker stop redmine-redmine-1

#DBコンテナにアタッチ
$ docker exec -it redmine-db-1 /bin/bash

【DBコンテナ内で操作】

#PostgreSQLにログイン
$ su postgres
$ psql -U redmine

#redmineのデータベースを削除
> \c postgres
> drop database redmine;

#redmineのデータベースを作成
> CREATE DATABASE redmine WITH ENCODING='UTF8' OWNER=redmine;
> \q

#redmineのデータベースをリストア
$ psql -U redmine -d redmine < /tmp/ダンプファイル名

#パスワードの設定
$ psql -U redmine
> ALTER USER redmine WITH PASSWORD 'パスワード';


⑧Redmineの起動

Redmineを起動します。
DockerイメージのRedmineは、Redmine本体のバージョンアップで必要なマイグレーションを起動時に自動で行います。また、プラグインのバージョンアップで必要なマイグレーションも、docker-compose.ymlで「REDMINE_PLUGINS_MIGRATE: 1」を設定しているため、起動時に自動で行います。
このタイミングで復元したデータに対し、必要なマイグレーションコマンドが実行されます。

#Redmineコンテナを起動
$ docker start redmine-redmine-1


⑨Redmineの動作確認

RedmineにログインしてRedmineやプラグインの動作、データに問題がないかを確認します。

まとめ

Dockerコンテナで動作するRedmineとデータベース、プラグインのバージョンアップを行いました。環境作成時にバージョンアップを考慮した作りにしていたため、設定ファイルの移行等は発生せず、バージョンアップを比較的簡単に行えました。Dockereコンテナで動作するRedmineやデータベースのバージョンアップのご参考になれば幸いです。