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

__↓ 1/5 はじめに__

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

[前回記事](https://qiita.com/ax_kazz/items/59e15728139a6768bbdf "1/5 はじめに")の続きです。
ここからが本題。

# パッケージ最新化

基本のおまじない。
Docker, Docker Compose のインストールが終わるまでは、root 権限で実施します。

```shell-session:
$ sudo su
# yum update
```

# Docker インストールとサービス起動

こちらも基本のおまじない。

```shell-session:
# yum install docker
```
インストールしたらサービス起動・常駐と確認。

```shell-session:
# systemctl start docker 
# systemctl enable docker 
# systemctl status docker
```

# ec2-user に docker グループを追加

ec2-user ユーザーで docker, docker-compose コマンドを使えるようにするための操作です。

```shell-session:
# grep -i docker /etc/group
# gpasswd -a ec2-user docker
# grep -i docker /etc/group
```
グループ追加には、gpasswd コマンドを使用します[^1]。
（前後の grep コマンドは、追加前と追加後の確認のため。）

[^1]: グループ追加には usermod コマンドもある。それぞれのコマンドには gpasswd が追加（非破壊的）、usermod が変更（破壊的）という違いがある。そのため「usermod -a -G docker ec2-user」だとグループは上書きされるので、すでに所属しているグループからは外れてしまう。個人的には gpasswd を使ったほうが安全な気がするが、今回の環境においては正直どうなんだろ？　識者の方教えてプリーズ！

https://vorfee.hatenablog.jp/entry/2016/01/10/040703

# docker-compose インストール

docker-compose は公式アナウンスに従い、GitHub から最新版を入手します。

```shell-session:
# curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# chmod 0755 /usr/local/bin/docker-compose
```

https://docs.docker.com/compose/install/

グループの内容を変更したので、一旦ログアウトしてから再度ログイン。

```shell-session:
# exit
$ exit
```

再ログインすることによって、グループ内容の変更が確実に反映されます。

:::note info
ここで一旦、EC2 のスナップショットを取得します。
この先は docker の環境構築を行うので、破壊時の戻り先にしておく。
:::

# docker-compose の準備

先のインストールで docker-compose のコマンド確認。

```shell-session:
$ docker-compose --version
```

## .env の設置

docker-compose.yml は、ホストの環境変数を参照することが可能です。
また環境変数に設定していない変数を .env に記述することで、あたかもホストの環境変数のように読み込むことができます。

今回の場合、データベースまわりに必要な接続情報を .env に記述します[^2]。

[^2]: 各種接続情報（アカウントやパスワードなど）といった秘匿情報・固有情報を docker-compose.yml に含めるのはリスキー。環境によって変更される情報は .env に外出しし、適切なパーミッションを設定しておく。

```shell-session:
$ vi .env
```

```ini:.env
DB_DATABASE=********
DB_USER=**********
DB_PASSWORD=************************************

DB_ROOT_PASSWORD=************************************
```

## docker-compose.yml （Compose ファイル）の設置

Compose ファイルを作成し設置します。
（vi で作成してもよいですが、慣れたテキストエディタでファイルを作って、サーバにアップロードするのが無難。）

```yaml:docker-compose.yml:
version: '3.9'

services:
  certbot:
    image: certbot/certbot:latest
    restart: always
    volumes:
      - etc_letsencrypt:/etc/letsencrypt
      - var_www_html:/usr/share/nginx/html
    entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
    networks:
      - frontend

  nginx:
    image: nginx:1.21
    container_name: nginx
    restart: always
    ports:
      - "80:80"
#      - "443:443" # 443 ポートが EXPOSE されてないので、ports で開ける
    environment:
      TZ: Asia/Tokyo
    volumes:
      - ./data/ssl/private/dhparam.pem:/etc/ssl/private/dhparam.pem ro
      - etc_nginx:/etc/nginx
      - etc_letsencrypt:/etc/letsencrypt
      - var_www_html:/usr/share/nginx/html
    command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
    networks:
      - frontend

  redmine:
    image: redmine:4.2-passenger
    restart: always
    container_name: redmine
    ports:
      - 3000:3000
    environment:
      TZ: Asia/Tokyo
      REDMINE_DB_MYSQL: mysql
      REDMINE_DB_DATABASE: ${DB_DATABASE}
      REDMINE_DB_USERNAME: ${DB_USER}
      REDMINE_DB_PASSWORD: ${DB_PASSWORD}
      REDMINE_DB_ENCODING: utf8
    depends_on:
      - mysql
    volumes:
      # /usr/src/redmine/config/configuration.yml をあとで設置
      - redmine_config:/usr/src/redmine/config
      - redmine_files:/usr/src/redmine/files
      - redmine_plugins:/usr/src/redmine/plugins
      - redmine_public_themes:/usr/src/redmine/public/themes
    networks:
      - frontend
      - backend

  mysql:
    image: mysql:8.0
    container_name: mysql
    restart: always
    ports:
      - 3306:3306
    environment:
      TZ: Asia/Tokyo
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
      MYSQL_DATABASE: ${DB_DATABASE}
      MYSQL_USER: ${DB_USER}
      MYSQL_PASSWORD: ${DB_PASSWORD}
    volumes:
      - ./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d # データインポート終了後にマウント削除。初回リリースであればマウント不要
      - etc_mysql:/etc/mysql
      - var_lib_mysql:/var/lib/mysql
    command: mysqld --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_0900_ai_ci
    networks:
      - backend

volumes:
  etc_letsencrypt:
  etc_nginx:
  var_www_html:
  redmine_config:
  redmine_files:
  redmine_plugins:
  redmine_public_themes:
  etc_mysql:
  var_lib_mysql:

networks:
  frontend:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 192.168.10.0/24
  backend:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 192.168.20.0/24
```

https://docs.docker.com/compose/compose-file/compose-file-v3/

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

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

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

__↓ 4/5 MySQL, Redmine の構築__

https://qiita.com/ax_kazz/items/1285534b46aeb307d7e0

__↓ 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