はじめに
コンテナ上で稼働しているRedmineのバージョンをアップデートする機会が今後あった時用?に手順をまとめておこうと思います。また、自己証明書を使ったhttps化の手順ついでにまとめようと思います。
想定読者
- dockerやpodmanに興味がある方
アップデートおよびhttps化の流れ
このブログで紹介する手順としては大雑把に以下の流れで行います。
①Redmineの構成紹介と新旧のバージョン比較
②旧バージョンの構築
③新バージョンにアップデート
④https化
前提として、今回実際にRedmineが稼働するサーバはインターネットに接続できない状態だと仮定し、イメージのダウンロードなどインターネットに接続が必要な手順については、予めインターネットに接続可能なサーバで実施することとします。
なおこのブログでは文字数等の関係で②まで記載し、③以降について別記事にしたいと思います。(いつ上げるかは不明)
①Redmineの構成紹介と新旧のバージョン比較
RedmineとRedmineに関連するソフトウェアの簡単な構成図と新旧のバージョンは以下の通りです。
上記のように、PodmanのPodと呼ばれる複数のコンテナを1つのまとまりとして扱う仕組みを使って構築予定になります。なぜPodmanを使うのかというとPodmanの学習のためになります。PodmanはDockerと互換性を持って作られていて、引数などの指定方法はすべてDockerと同じらしいです。
- 新旧のバージョン
| ソフトウェア名 | 旧バージョン | 新バージョン |
|---|---|---|
| Redmine | 5.1.1 | 6.0 |
| MySQL | 5.7 | 8.1 |
| Apache(httpd) | 2.4.66 | - |
②旧バージョンの構築
まず旧バージョンでRedmineを構築したいと思います。
※dockerコマンドを使ったりpodmanコマンドを使ったりバラバラです…
大まかな流れとしては下記です。
②-1 イメージダウンロード用(以下イメージサーバ)とRedmineを稼働させる用(以下コンテナサーバ)の仮想マシンを作成
②-2 イメージサーバでイメージの準備
②-3 コンテナサーバで予め準備したイメージを使ってRedmineを構築する
※文字数等の関係上、②-1の記載は省略
②-2
Redmineについては、以下のようなDockerfileを作成してbuildします。
FROM redmine:5.1.1
USER root
# プラグイン配置
COPY plugins /usr/src/redmine/plugins
# 権限設定
RUN chown -R redmine:redmine /usr/src/redmine/plugins
# 作業ディレクトリ
WORKDIR /usr/src/redmine
# プラグイン依存ライブラリのインストール
RUN bundle install --without development test
# 権限設定
RUN chown -R redmine:redmine /usr/src/redmine
# 実行ユーザー
USER redmine
続いてその他必要なイメージをダウンロードし、他のサーバに移動できるようにtarファイルにします。
# docker pull mysql:5.7
# docker save mysql:5.7 > mysql_5-7.tar
tarファイルをコンテナサーバにscpを使って移動出来たら、①-2は終了です。
②-3
まずtarファイルをロードして、イメージに変換します。
# docker load -i mysql_5-7.tar
変換したイメージを確認します。
# docker images
~省略~
docker.io/library/redmine 5.1.1 f9c53923718d 8 weeks ago 718 MB
docker.io/library/mysql 5.7 5107333e08a8 2 years ago 520 MB
docker.io/library/httpd 2.4.66 14ca0b0b9518 2 months ago 120 MB
~省略~
続いてPodを作成していきます。
Podの特徴としては以下のようなものがあります。
Podmanでは、Podを生成すると、管理用のコンテナであるinfraが自動的に作成されます。infraは、Pod内のリソースを管理する役割を担います。Podが公開するポート、Cgroupのリソース、カーネルの名前空間などは、このinfraコンテナを通して管理されます。
https://www.designet.co.jp/faq/term/?id=UG9k#podfunction
以下のコマンドを使って、Podを作成します。※事前に443のポートを開けるのを忘れないようにする
# podman pod create --name redmine-pod -p 8080:80 -p 8443:443
Podman作成後は以下のコマンドでPodの情報を見ることができます。
[root@localhost ~]# podman pod ps
POD ID NAME STATUS CREATED INFRA ID # OF CONTAINERS
2a596b6e9f95 redmine-pod Created 6 seconds ago 7af8a752c5ea 1
[root@localhost ~]# podman ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7af8a752c5ea 16 seconds ago Created 0.0.0.0:443->443/tcp, 0.0.0.0:8080->80/tcp 2a596b6e9f95-infra
[root@localhost ~]#
続いて各コンテナを作成していきますが、作成の前に各イメージが指定しているボリュームを確認します。
docker inspect <image名> | grep -A 2 '"Volumes":'
※redmineの場合
[root@localhost images]# docker inspect redmine:5.1.1 | grep -A 2 '"Volumes":'
Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg.
"Volumes": {
"/usr/src/redmine/files": {}
},
上記で表示される/usr/src/redmine/filesはコンテナ外部に保存した方がいいディレクトリを指しております。コンテナ作成時のボリュームを指定する際にこのディレクトリを指定します。
まず、MySQLのコンテナを作成します。
podman run -d \
--name redmine-db \
--pod redmine-pod \
-e MYSQL_ROOT_PASSWORD=<password> \
-e MYSQL_DATABASE=<database_name> \
-e MYSQL_USER=<user_name> \
-e MYSQL_PASSWORD=<PASSWORD> \
-v $(pwd)/redmine/db/my.cnf:/etc/mysql/conf.d/my.cnf:Z \ #Zオプションはselinux対処のため
-v redmine-db-data:/var/lib/mysql \
mysql:5.7
なおmy.cnfの中身は下記のようにしております。これをしないと日本語に対応せずinternal_errorが発生します。
[root@localhost images]# cat redmine/db/my.cnf
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
[client]
default-character-set=utf8mb4
続いて、Redmineのコンテナを作成します。
podman run -d \
--pod redmine-pod \
--name redmine-app \
-e REDMINE_DB_MYSQL=<dbcontainer_name> \
-e REDMINE_DB_DATABASE=<datebase_name> \
-e REDMINE_DB_USERNAME=<user_name> \
-e REDMINE_DB_PASSWORD=<PASSWORD> \
-v redmine-app-data:/usr/src/redmine/file \
redmine:5.1.1
最後に、Apacheのコンテナを作成します。
Apacheのコンテナ作成にあたり事前にhttpd.confのコピーをとりたいので、仮のコンテナを作成して、ローカルにファイルをコピーします。
停止中のコンテナを作成
# docker create --name tmp-apache httpd:2.4.66
停止済みのコンテナからhttpd.confをローカルにコピー
# docker cp tmp-apche:conf/httpd.conf redmine/apache/
一時コンテナの削除
# docker rm tmp-apache
httpd.confの編集、別でredmineにプロキシするための設定ファイルも作成
# vi redmine/apache/httpd.conf
# vi redmine/apache/conf.d/reverse-proxy.conf
apacheコンテナの作成
# podman run -d \
--pod redmine-pod \
--name redmine-apache \
-v $(pwd)/redmine/apache/httpd.conf:/usr/local/apache2/conf/httpd.conf:ro,Z \
-v $(pwd)/redmine/apache/conf.d:/usr/local/apache2/conf/conf.d:Z \
httpd:2.4.66
最後に全てのコンテナが適切に稼働しているか確認して、http://コンテナサーバのIPアドレス:8080にアクセスできるか確認します。
[root@localhost images]# docker ps -a
Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5a48eab972f6 About a minute ago Up 45 seconds 0.0.0.0:8080->80/tcp, 0.0.0.0:8443->443/tcp 7110af948363-infra
49521cf9f118 docker.io/library/mysql:5.7 mysqld 45 seconds ago Up 45 seconds 0.0.0.0:8080->80/tcp, 0.0.0.0:8443->443/tcp, 3306/tcp, 33060/tcp redmine-db
9339444dfdb0 docker.io/library/redmine:5.1.1 rails server -b 0... 29 seconds ago Up 29 seconds 0.0.0.0:8080->80/tcp, 0.0.0.0:8443->443/tcp, 3000/tcp redmine-app
02f13d1fd96d docker.io/library/httpd:2.4.66 httpd-foreground 4 seconds ago Up 4 seconds 0.0.0.0:8080->80/tcp, 0.0.0.0:8443->443/tcp redmine-apache
[root@localhost images]#
また、下記管理タブの情報において、エラーが出ていないか確認します。(キューアダプターがデフォルト (開発・テスト用) 以外のものに変更済みについては検証用であれば問題ないらしい)

※プラグインを入れている場合
プラグインを入れている場合、下記のコマンドを実行して、プラグインを反映する
podman exec -it redmine-app \
bundle exec rake db:migrate RAILS_ENV=production
podman exec -it redmine-app \
bundle exec rake redmine:plugins:migrate RAILS_ENV=production
※bind mountとvolumeの違い
コンテナ内のデータをホスト側に残したい場合、以下の方法を使って、データの永続化が可能です。
| 方法 | 説明 |
|---|---|
| bind mount | コンテナサーバ上のファイルやディレクトリをコンテナから参照 |
| volume | コンテナサーバが管理するボリュームをコンテナで利用 |
今回redmineをコンテナで構築する中で気づいたそれぞれのメリット、デメリットは下記の通りです。
| 方法 | メリット | デメリット |
|---|---|---|
| bind mount | ローカルで作成した設定ファイルをコンテナ内に反映できる | ホスト側のファイルやディレクトリの権限が反映される |
| volume | コンテナ側のファイルやディレクトリの権限をあまり意識しなくてよい | ファイルやディレクトリごと別ホストに移行ということが難しい(やりにくい) |
redmineのコンテナではredmineユーザーが稼働するのですが、例えば、コンテナサーバ側のredmin/appをコンテナ内の/usr/src/redmine/filesとして利用するとします。
そうすると、もしこのredmin/appをコンテナ内のredmineユーザーと同じUIDで作成しない場合、コンテナ内の/usr/src/redmine/filesの所有者(所有グループも含む)がredmineと違うユーザーになってしまい、そのディレクトリがコンテナ内で開けないという事態に陥ります。(私はrootで作成したため、root所有者になってしまい、エラーがでました。)
上記を防ぐためには、redmineユーザーと同じUIDを持つユーザーでコンテナサーバ側のディレクトリを作成すればいいのですが、わざわざ同じUIDを持つユーザーを調べて、そのユーザーの権限でディレクトリを作成するのはとても面倒だし、何も知らない人からみたら、「なぜこのディレクトリだけユーザーが違うのか」という疑問を持つかもしれません。
その点volumeであれば、dockerやpodman側で権限の辺りをうまくやってくれるので、コンテナ内の権限をあまり意識しなくてよいかと思います。
ちなみに今の稼働しているコンテナがbind mountかvolumeどちらを使用しているのか確認したい場合は以下のコマンドを利用すると分かります。
docker inspect <container_name> | grep -A 2 "volume"
docker inspect <container_name> | grep -A 2 "bind"
上記コマンドを実行すると下記のような結果が返ってきます。
# docker inspect redmine-db | grep -A 2 "volume"
Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg.
"Type": "volume",
"Name": "redmine-db-data",
"Source": "/var/lib/containers/storage/volumes/redmine-db-data/_data",
"Destination": "/var/lib/mysql",
"Driver": "local",
[root@localhost images]#
# docker inspect redmine-db | grep -A 2 "bind"
Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg.
"Type": "bind",
"Source": "/srv/docker/images/redmine/db/my.cnf",
"Destination": "/etc/mysql/conf.d/my.cnf",
--
参考サイト
https://hiiragi-works.sakura.ne.jp/docker-003/
http://qiita.com/ymd65536/items/f17cdc5dabd1a1bac3d8
https://qiita.com/tutuz/items/048b8f7cbfaae649d137
https://note.com/ictlink/n/n5be706a45ccf
https://qiita.com/Toyo_m/items/95a2543c07dc5b126208
参考文献
古賀 政純.Docker実践ガイド 第3版.インプレス,2026

