AWS EC2 に Docker Compose で nginx + certbot (Let's Encript) + Redmine + MySQL 入れてみた（4/5 MySQL, Redmine の構築）

__↓ 1/5 はじめに__

https://qiita.com/ax_kazz/items/59e15728139a6768bbdf

__↓ 2/5 Docker, Docker Compose など基盤構築__

https://qiita.com/ax_kazz/items/816fe535aa3cf402d004

__↓ 3/5 Nginx, Certbot 導入と SSL 証明書の取得・更新__

https://qiita.com/ax_kazz/items/f837e237e968db3d3ab3

[前回記事](https://qiita.com/ax_kazz/items/f837e237e968db3d3ab3 "3/5 Nginx, Certbot 導入と SSL 証明書の取得・更新")の続きです。

この先使用する Compose ファイル（docker-compose.yml）については、[前々記事の最後あたり](https://qiita.com/ax_kazz/items/816fe535aa3cf402d004#docker-composeyml-compose-%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E8%A8%AD%E7%BD%AE "2/5 Docker, Docker Compose など基盤構築 - docker-compose.yml （Compose ファイル）の設置")を、Nginx 設定ファイル（vhost-www\.example.jp.conf）については、[前記事の中央あたり](https://qiita.com/ax_kazz/items/f837e237e968db3d3ab3#compose-%E3%83%95%E3%82%A1%E3%82%A4%E3%83%ABnginx-%E8%A8%AD%E5%AE%9A%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E5%B7%AE%E6%9B%BFhttps-%E5%AF%BE%E5%BF%9C "3/5 Nginx, Certbot 導入と SSL 証明書の取得・更新 - Compose ファイル、Nginx 設定ファイルの差替（https 対応）")をそれぞれ参照してください。

引き続き、面倒な作業が続きます。

1. MySQL（初期インポートするの準備 ⇒ 起動）
1. MySQL（通常起動）
1. Redmine（通常起動）
1. データベースのアップグレード
1. Redmine のファイル群を、移行元から移転。

# MySQL（初期インポートするの準備 ⇒ 起動）

最初に作っておくべきディレクトリは、以下の通り。

```shell-session
$ mkdir -p ./docker-entrypoint-initdb.d
```

ここに初期インポートする .sql ファイルをアップロードします。
準備完了後、mysql を Compose ファイルに則って、普通に起動します。

```shell-session
$ docker-compose up -d mysql
$ docker-compose logs mysql
```

初回起動のみ、データがインポートされます。

ちなみに上記２行目のコマンドにて MySQL のログが確認できますが、その中に、……

```shell-session
YYYY-MM-DD HH:NN:SS+09:00 [Note] [Entrypoint]: /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/XXXXXXXXXXXX.sql
```

…… というログが記載され、さらにそのあとエラーが続いてなければ、データインポートも成功していると思います。

https://qiita.com/NagaokaKenichi/items/ae037963b33a85df33f5

https://thinline196.hatenablog.com/entry/2020/01/28/231346

https://hub.docker.com/_/mysql/

以降元データベースのバックアップについては、以下の公式サイト等をご確認ください

http://guide.redmine.jp/RedmineBackupRestore/

# MySQL（通常起動）

データインポートが完了したら、安全のため、Compose ファイル内のバインドマウント記述を削除しておきます。

```yaml:docker-compose.yml（抜粋）:
    : <snip>
  mysql:
      : <snip>
    volumes:
      ↓↓↓↓↓↓ この行を削除 ↓↓↓↓↓↓
      - ./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d # データ移行する場合のみ必要、移行終了後マウント削除
      ↑↑↑↑↑↑ この行を削除 ↑↑↑↑↑↑
      - etc_mysql:/etc/mysql
      - var_lib_mysql:/var/lib/mysql
          : <snip>
```

そして、MySQL を再起動します。
（最後に、インポートデータも削除しておきます。）

```shell-session
$ docker-compose stop mysql
$ docker-compose up -d mysql
$ rm -rf docker-entrypoint-initdb.d
```

# Redmine（通常起動）

```shell-session
$ docker-compose up -d redmine
```

# データベースをアップグレード

リプレースかつ、リプレース前の Redmine バージョンが古い場合は、ここでリプレース後のバージョンのデータベースに更新する。

```shell-session
$ docker-compose exec redmine bundle exec rake db:migrate RAILS_ENV=production
```

:::note warn
ちなみに自分の環境では、このタイミングでシェルが応答しなくなる場合がありました。
急遽 AWS の CloudWatch にて EC2 の状態を確認したところ、CPU が 100% まで跳ね上がり、バーストクレジットを大きく消費した記録を残したのち、少し待っても、その後のログの取得が取れず。
またシェル応答も引き続き戻ってこなかったのと、再接続もできなかったので、ここでインスタンス再起動しました。
再起動後は、特に不具合ありません。
:::

https://www.redmine.org/projects/redmine/wiki/RedmineUpgrade

# Redmine のファイル群を、移行元から移転。

リプレースの場合は、ここで Redmine データベース以外のファイルを移転します。
主に移転が必要になるファイルは、redmine ディレクトリ（概ね /usr/src/redmine か /var/lib/redmine など）配下の、以下のディレクトリです。

## plugins ディレクトリ

なにかプラグインを導入している場合のみ移行が発生します[^1]。
プラグイン未導入の場合は、README ファイルあるだけで、ほぼ空っぽの状態。

[^1]: プラグインについては、バージョンアップの伴うリプレースの場合、正しく動作しなくなる可能性がある。その場合はリプレース作業の過程で、プラグインのバージョンアップなど、個別の対応が必要になる。

## files ディレクトリ

チケットや Wiki などに貼り付けた画像や添付ファイルが格納されています。
大抵の場合は何かしら入っているはずなので、必ず忘れずに移転しましょう。

## public/themes ディレクトリ

サイト自体に個別のテーマ（デザインのカスタマイズ）を設定している場合、こちらのディレクトリにテーマが格納されています[^2]。

[^2]: テーマについてもプラグインと同様、バージョンアップの伴うリプレースの場合、正しく動作しなくなる可能性がある。その場合はリプレース作業の過程で、個別の対応が必要。

## 移行例

以下は、files ディレクトリの移行コマンド例です[^3]。

```shell-session
$ docker cp redmine.files.tgz redmine:/usr/src/redmine/files  # コンテナ（ボリューム）内に移行データ（圧縮ファイル）格納
$ docker-compose exec redmine bash  # Redmine コンテナのシェルに入る
# cd /usr/src/redmine/files  # Redmine のファイルディレクトリに移動
# tar xvf 20210709.redmine.files.tgz # 移行データを解凍・展開
# chown -R redmine:redmine ./*  # データのオーナー・グループをコンテナのユーザ・グループに変更
# mv var/lib/redmine/files/* .  # 移行元の絶対パスで格納されていたものを展開したので、適切なパスにデータをすべて移動
# rm -rf var  # 移行元の絶対パス（残骸）を削除
# rm 20210709.redmine.files.tgz  # 移行元データ（圧縮ファイル）を削除
# exit  # コンテナから抜ける
```

[^3]: 移行データの取得状態などによって、ファイル名・ディレクトリ名・オーナー・グループが異なる。そのため実際は、適宜コマンド内容などを変更する必要あり。

https://www.redmine.org/projects/redmine/wiki/RedmineBackupRestore#Backing-up-attachments

# Nginx 設定ファイル差替（nginx と Redmine の繋ぎ込み）

Compose ファイルの通り、Redmine は 3000 ポートを開く状態で構築しました。
これを Nginx のリバースプロキシを使って、https（443ポート）に繋ぎ込みます。

```
"ブラウザ" <== Port 443 (https) ==> "nginx" <== Port 3000 (http) ==> "Redmine"
```

具体的には Nginx 設定ファイルにの https（SSL）サーバ接続の記述内に、リバースプロキシによるRedmine 繋ぎ込みの内容を反映し、再アップロードします。
（SSL 側 location / の中身を以下の通り、すべて差し替えます。）

```nginx:vhost-www.example.jp.conf（抜粋）
  : <snip>
server {
    listen        443 ssl;
      : <snip>
    location / {
        proxy_set_header     X-Forward-For $remote_addr;
        proxy_pass           http://redmine:3000/;
        client_max_body_size 500M;
    }
}
```

設定ファイルを Nginx の設定ボリュームへ格納し、再起動・ログを確認します。

```shell-session
$ docker cp vhost-www.example.jp.conf nginx:/etc/nginx/conf.d/vhost-www.example.jp.conf
$ docker-compose stop nginx
$ docker-compose up -d nginx
$ docker-compose logs nginx
```

最後にブラウザアクセスにて動作確認します。

```
http://www.example.jp
https://www.example.jp
```

特に Redmine の以下の箇所を確認し、問題なければ作業完了となります。

* 画面表示の確認。
 * テーマ（デザイン）などをカスタマイズしている場合、適切に反映されているか。
* ログインおよび、各画面遷移。チケット発行や Wiki など、Redmine 機能の動作確認。
* 添付されている画像ファイルなどが、正しく反映されているか。
* プラグインの動作確認（導入している場合のみ）
* メール送信などの各種連携[^4]。

[^4]: 当方利用 Redmine システムではメール送信や Git の連携など、一部追加の修正が必要なありました。しかしながら、これらについては Docker 云々とは離れた内容であるため、手順等については記事省略しています。

[最後の記事（参考・謝辞）](https://qiita.com/ax_kazz/items/be1e491910b9546bc8c1 "5/5 引用・謝辞")に続きます。

__↓ 5/5 引用・謝辞__

https://qiita.com/ax_kazz/items/be1e491910b9546bc8c1


# 参考・引用

http://kikei.github.io/server/2020/07/11/redmine.html

https://qiita.com/tu-kun/items/a8aa0926b090b7cccc9d