コンテナでRedmineの環境構築をやってみた

#コンテナでRedmineの環境構築をやってみた

## 前提条件
* サーバはAmazon Linux release2 ( EC2 t2.micro )
* redmineはDocker Hubの公式イメージ (https://hub.docker.com/_/redmine)
* データベースは外出しし、Docker Hubの公式イメージMySQL：5.7を利用 (https://hub.docker.com/_/mysql)

##redmineコンテナの構成
### redmineの永続化領域

redmineのコンテナを利用するうえで永続化が必要な領域は下記の通り。

* redmine files(/usr/src/redmine/files)
* redmine plugins(/usr/src/redmine/plugins)
* redmine public/themes(/usr/src/redmine/public/themes)
* redmine config(/usr/src/redmine/config/configuration.yaml)

データベースを外出ししない場合は、下記領域も永続化対象となる。

* postgres DB(/var/lib/postgresql/data)

### 永続化領域の削減
コンテナは必要最小限の永続化領域のみで運用したい。そのため、コンテナイメージにプラグインやConfigをあらかじめ組み込んだコンテナイメージを作成する。redmineに添付されたファイルを保管するfilesのみ、永続化が必要となる。

下記構成のgitリポジトリを作成する。configuration.yamlは公式イメージの `/usr/src/redmine/config/configuration.yaml` を取得しておく。

```
redmine
├── Dockerfile
├── config
│   └── configuration.yaml　（設定ファイル）
├── plugins
│   └── 導入したいプラグインを格納
└── themes
    └── 導入したいテーマを格納
```

#### Dockerfile

Dockerfile内で各々のフォルダの中身をコンテナイメージ内にコピーする。データベースを外出しする構成をとるため、4行目でredmineコンテナの起動オプションをあらかじめ設定している。あらかじめgitHubとDocker Hubを連携しておき、コミットしたら自動ビルドされるように設定しておく。（連携方法は割愛します）

```
FROM redmine:4.0

#環境変数の自動設定
ENV REDMINE_DB_MYSQL mysql
ENV TZ Asia/Tokyo

# プラグインのコピー
COPY plugins /usr/src/redmine/plugins

# テーマのコピー
COPY themes /usr/src/redmine/public/themes

# configurationファイルのコピー
COPY config/configuration.yml /usr/src/redmine/config/

```




## MySQLコンテナの構成
### 公式イメージの文字コード
公式イメージのMySQLは文字コードがlatin1になっており、日本語を利用する場合は文字化けをしてしまう。そのため、MySQLコンテナのイメージを加工して、文字コードをutf8に変更する必要がある。

### 文字コードの変更
フォルダ構成は下記の通り。

```
mysql/
├── Dockerfile
├── README.md
├── conf
│   └── custom.cnf
└── docker-entrypoint-initdb.d
　   └── 起動時に実施したいsqlファイルやshファイルを格納
```

#### custom.cnf

```
[mysql]
default-character-set=utf8

[mysqld]
character-set-server=utf8
```

#### Dockerfile

MySQLは、`/etc/mysql/conf.d/`配下のconfファイルを起動時にすべて読み込む仕様になっている。そのため、Dockerfile内でconfディレクトリをコンテナイメージのconf.dディレクトリにコピーすることで、custom.cnfが起動時に読み込まれ、文字コードがutf8に設定される。

また、MySQL起動時に実施したいsqlファイルやshファイルなどを格納するdocker-entrypoint-initdb.dについてもコンテナ内にコピーをしている。

8.0系のMySQLをredmine 4.0がサポートしていないため、MySQL5.7を指定しています。

```
FROM mysql:5.7

COPY conf /etc/mysql/conf.d/
#COPY docker-entrypoint-initdb.d /docker-entrypoint-initdb.d

```

#### 文字コードの確認方法
MySQLにログインをし、`show variables like "chara%";`を実行することで確認できる。

```
>mysql -u root -p 
Enter password: ******
>use database redmine
>show variables like "chara%";
+--------------------------+--------------------------------------------------------------+
| Variable_name            | Value                                                        |
+--------------------------+--------------------------------------------------------------+
| character_set_client     | utf8                                                         |
| character_set_connection | utf8                                                         |
| character_set_database   | utf8                                                         |
| character_set_filesystem | binary                                                       |
| character_set_results    | utf8                                                         |
| character_set_server     | utf8                                                         |
| character_set_system     | utf8                                                         |
| character_sets_dir       | /opt/rh/rh-mysql57/root/usr/share/rh-mysql57-mysql/charsets/ |
+--------------------------+--------------------------------------------------------------+
8 rows in set (0.00 sec)
```


### データベースの永続化
MySQLのデータファイルは、`/var/lib/mysql`配下に保存されるため、この領域は永続化が必要となる。永続化領域の作成とマウントは後述のdocker-compose内で行う。

## コンテナの起動
コンテナの起動はdocker-composeを使うことで、起動オプションや起動順序などを一つのファイルで管理することができる。コンテナを起動するには、当該ファイルが格納されているディレクトリで`docker-compose up`を実行する。

#### docker-compose.yml
```
version: '2'

# redmine with mysql

services:
  mysql:
    image: asubee/mysql
    container_name: mysql
    volumes:
      - main-redmine-db:/var/lib/mysql
    restart: always
    environment:
      MYSQL_DATABASE: redmine
      MYSQL_PASSWORD: mysql
      MYSQL_ROOT_PASSWORD: mysql
      MYSQL_USER: user

  redmine:
    image: asubee/redmine
    container_name: redmine
    volumes:
      - main-redmine-files:/usr/redmine/files
    ports:
      - "3000:3000"
    links:
      - mysql
    restart: always
    environment:
      REDMINE_DB_MYSQL: mysql
      REDMINE_DB_USERNAME: mysql
      REDMINE_DB_PASSWORD: mysql
      REDMINE_DB_DATABASE: redmine

volumes:
  main-redmine-db:
    external: true
  main-redmine-files:
    external: true

```

#### MySQLコンテナの起動
imagesで指定するコンテナイメージは[MySQLコンテナの構成](#mysqlコンテナの構成)で作成したものを使用する。また、初回起動時に「redmine」という名のデータベースを作成するため、environmentの「MYSQL_DATABASE」に「redmine」を指定する。ほか、environmentに記載のあるものは、MySQLコンテナを起動する際に必須となるオプションである。

#### Redmineコンテナの起動
imagesで指定するコンテナイメージは[redmineコンテナの構成](#redmineコンテナの構成)で作成したものを使用する。ポートはデフォルトのままの3000番を外部に公開する。また、mysqlを参照するために、linkを設定している。

#### 永続化ボリュームの作成
「volumes」句から始まる部分で、redmineのfilesを格納する永続化領域と、mysqlのデータベースを格納する永続化領域を指定している。永続化領域は事前に作成しておく必要がある。

```
$ docker volume create --name=main-redmine-db
$ docker volume create --name=main-redmine-files
```


#参考サイト
* [Redmineインストール from Docker Hub](https://qiita.com/ir-shin1/items/65b935b7a57787a76053)
* [Dockerで立ち上げたMySQLにログインすると日本語が文字化け](https://qiita.com/luccafort/items/0553c589dcc6459746bc)
* [Docker Composeでボリューム作成](https://qiita.com/reflet/items/5c0a488494c7d6904084)