redmine, postgres, nginx, fluentdをdocker-composeで運用する

## GitHubリポジトリ

こちらから入手できます。README.mdの手順で使用可能となります。

[https://github.com/kurawo/redmine-ops-docker](https://github.com/kurawo/redmine-ops-docker)

## 想定されている使用環境
- 個人
- 社内の比較的小さな部門


##なぜコンテナ、しかも今更docker-composeなのか（長いので理由が不要な人は読み飛ばしてください）

社内のシステムをつくる怠け者のわたくしは、時代はコンテナなんですよ、なんて思いつつコンテナを便利に使わせてもらってます。
それは環境構築をだいぶ自動でやってくれる上に、ソフトウェアが自分の開発マシンだろうがオンプレだろうがクラウドだろうがだいたい動くからです。

マシン間の差分をだいたい吸収できるって、結構嬉しいものです。
たとえば、コンテナが開発マシンで動いたけどステージング環境のマシンでは動かない、となればコンテナでパッケージされているところ以外の環境での差分から原因の切り分けができます。サーバーバイナリを日がな相手している私にとっては非常に助かっております。

そんなコンテナのエンジン、dockerが便利なのはもうみなさんご存知な感じかと思います。そしてコンテナを運用するk8sが大流行しているのもみなさんよくご存知かとおもいます。いかにしてコンテナをうまく運用するかという話になってくれば、最終的にk8sや各種クラウドのコンテナサービスをみんな使っていく状況になるものです。大規模なトラフィックをさばく、高い可用性を与えなければならない、などのすごく大変な要望を叶えるためには、k8sなどがやはり必要になってきます。

とはいえ、私のように個人でコンテナを運用する、または比較的社内の小さな担当レベルでの社内システムを運用する時、つまり大規模なトラフィックや高い可用性の必要のない時、k8sは運用しづらいなあと私はかねがね考えておりました。

k8sは私も開発マシンでなんとかいじっていたのですが、docker-composeに比べてまだ書きづらく、k8sのマシンを用意するにもマネージドサービスが基本で複数台のマシンを動かすので費用がかかりがち、DBもたいていマネージドサービスにあるいずれかを使うことになって更に費用と構築コストがかかるのです。

しかし一方でひとつのマシン上のパッケージ管理システムで格闘するのも面倒です。コンテナで構築する時以上に依存関係を考えながら対処し、以後の運用でもログの管理やバックアップの処理を個別にアップデートするのは案外手のかかる作業です。

例えば社内システムの代表格でもある今回のredmineも、DBのバックアップなどはちゃんとしないといけませんがこれが一瞬でも止まるとビジネスが止まる、というものでもありません。そして大抵の場合、可能な限り構築・運用のコストはお金を直接稼ぐシステム以上に回避したいのが本音です。

そのうえ運用のコードはコンテナに関しても今までそれほど共有されているところもみたことがありませんでした。調査不足なのかもしれませんが。私も自分の都合に合わせてつくりましたが、その雛形になるものがないのは結構面倒でした。

というわけで、わたくしのなかで、コンテナが比較的全部やってくれるものredmineコンテナというアイデアが生まれました。そのアイデアを具現化したものを、今回ご紹介します。

## 概要

このファイル群では、以下の作業をコンテナやdocker-composeがいい感じにやってくれるように実装されています。

- postgresとredmineのファイルをcronでバックアップします。
- バックアップファイルは5日後に削除されます。
- postgresql.confを挿入します。
- nginx.confも挿入します。
- アクセスは全てnginxを経由します。
- コンテナのログはすべてfluentdで収集されます。アクセスログとpostgresのログがJSON形式で時系列で並ぶ形になります。

などなど

今回はredmine用にしていますが他のコンテナをredmineのところの代わりに入れてもらってもだいたいいい感じに動くようになると思います。

## docker, docker-compose install(実行環境をWindows, MacOSにする場合)

dockerを触ったことがない方はdocker for desktopで試して様子を見てもらうなどが良いと思います。インストーラーがいろいろいい感じに環境構築してくれます。

ただGCEとかに載せて運用といった、本番環境に近い形を考えるとLinuxのVMをvagrantなどで用意してそこでデプロイしてもらうのも手のうちです。

## docker, docker-compose install(実行環境をLinuxにする場合)

以前のzabbix記事でも書きましたが、VM起動後にdockerの公式が用意しているというshスクリプトを使うのが楽です。しばらく待つとdockerのバージョンが表示され完了します。VMの作り方については以下の記事の「VagrantでUbuntu18.04を実行する」の項目をご覧ください。

[Zabbix5.0とZabbix agent2をubuntu18.04とvagrantとdocker-composeで動かしてみたけど自分のDockerをまだ監視できない https://qiita.com/GCkurabe/items/74df83729895c404a8b3](https://qiita.com/GCkurabe/items/74df83729895c404a8b3)

[参考:最も簡単なDockerの公式セットアップ方法(CentOS/Ubuntu) https://qiita.com/zembutsu/items/bedb18e1061303e217b8](https://qiita.com/zembutsu/items/bedb18e1061303e217b8)

[参考:Zabbix 5.0 を Docker Compose で起動する手順 https://qiita.com/zembutsu/items/d98099bf68399c56c236](https://qiita.com/zembutsu/items/d98099bf68399c56c236)

```
# curl -fsSL get.docker.com -o get-docker.sh
# sudo sh ./get-docker.sh
```

実行結果は以下のようになります。

```
# Executing docker install script, commit: 
[中略]
+ sh -c docker version
Client: Docker Engine - Community
 Version:           19.03.9
 API version:       1.40
 Go version:        go1.13.10
 Git commit:        9d988398e7
 Built:             Fri May 15 00:25:18 2020
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.9
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.13.10
  Git commit:       9d988398e7
  Built:            Fri May 15 00:23:50 2020
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.2.13
  GitCommit:        7ad184331fa3e55e52b890ea95e65ba581ae3429
 runc:
  Version:          1.0.0-rc10
  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683
If you would like to use Docker as a non-root user, you should
now consider
adding your user to the "docker" group with something like:

  sudo usermod -aG docker your-user

Remember that you will have to log out and back in for this to
take effect!

WARNING: Adding a user to the "docker" group will grant the ability to run
         containers which can be used to obtain root privileges on the
         docker host.
         Refer to https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface
         for more information.
```


次にdocker-composeをcurlでインストールします。

```
# sudo curl -L https://github.com/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
```

実行権限を付与しておきます。

```
# sudo chmod +x /usr/local/bin/docker-compose
```

docker-comoposeのバージョンを確認します。1.25.5となっていればよいです。

```
docker-compose --version
# docker-compose version 1.25.5, build 8a1c60f6
```

## redmineのdocker-compose用のファイルを入手する

以下のように私のリポジトリからgit cloneします。gitは予め準備をお願いします。入手はdockerほど面倒ではないです。

```
git clone https://github.com/kurawo/redmine-ops-docker.git
```

##環境ファイル追加

まずcloneされたディレクトリに入ります。

```
cd redmine-ops-docker /
```

ここで、postgres用の環境変数ファイルを作成します。これはgitで管理できないようにあえてしているためです。

```
vi env / posgres.env
```

環境変数を書きます。ご使用の際はchangepass1とchangepass2を任意のパスフレーズに書き換えてください。

```
POSTGRES_PASSWORD=changepass1
POSTGRES_DATABASE=redmine
POSTGRES_ROOT_PASSWORD=changepass2
POSTGRES_USER=redmine
TZ=Asia/Tokyo
```

次にredmine用の環境変数ファイルを書きます。

```
vi env / redmine.env
```

postgresのchangepass1で書いた内容をこちらのchangepass1にも書き換えてください。

```
REDMINE_DB_POSTGRES=postgres
REDMINE_DB_DATABASE=redmine
REDMINE_DB_USERNAME=redmine
REDMINE_DB_PASSWORD=changepass1
TZ=Asia/Tokyo
```

## chmod exec

次にpostgresのログディレクトリやコンテナログ収集するfluentd用のログディレクトリの権限を以下のshスクリプトで変更します。

```
sh chmod.sh
```

## docker-compose up

いよいよコンテナを起動します。

```
docker-compose up -d
```

これで任意のIPやドメインへブラウザでアクセスしていただければ使用可能となっています。

たとえばdocker for desktopでの場合はローカルホストへのアクセスで良いです。

```
http://localhost
```

vagrantのpraivate networkでipを192.168.33.10に指定して作っている場合はこんな感じになります。

```
http://192.168.33.10/
```

これでredmineが使用可能となりました。

## docker-composeを停止する

終了する時は以下のコマンドを実行します。

```
docker-compose down
```

## おわりに

これでredmineがコンテナで運用できるようになりました。私も実際にGCEを使用して個人プロジェクトをこのredmineで管理できるようにしました。なんだかんだでクラウドでちゃんとコンテナ運用するのは初めてですがそこまで苦労なく始めることができました。

ただその場合だとhttpとなってしまったので、自己証明書、いわゆるオレオレ証明書を作成し、nginxに挿入して使えるようにしました。次回の記事でご紹介します。