dockerマルチサイト構築(conoha+centos7+nginx-proxy, docker-compose)

## はじめに
dockerを使って趣味サーバで依存関係を気にしなくて良い環境を安く作りたく、既存サーバーのリプレイスとしてdocker環境を構成。docker初心者です。

## やりたかったこと
- 複数のwebサーバ、webアプリをひとつのVPSで実行。
    - 　www.xxx.com"→ウェブサーバへ。app1.xxx.com→webアプリへ。
- dockerで運用、可能な限りdocker-composeだけで運用。
- 趣味サーバなのでそこまでパフォーマンスは不要。将来的な拡張ができること。
- https対応

## 構成イメージ
<img width="856" alt="スクリーンショット 2019-11-11 21.16.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517076/0083e23e-6f01-0c9e-97e1-12d10e3464d2.png">

##VPS
1年前、仕事の関係の検証でAWSとGCPとAzureを一気に作成しましたが結果検証環境程度であればVPSが一番安いという気づきがありました。最近はコンテナ関連日々変わっているのは理解しつつ、既存さくらを使っていたので評判のいいconohaを使ってみました。

## 初期セットアップ
>- [ConoHa と CentOS7 でサーバー構築](https://qiita.com/nanocloudx/items/e393dead67b8a48ba6a6)
- [CentOS7 SSH設定の記録](https://qiita.com/mirai_is_here/items/0120d584dd0c5ea0664d)

基本設定。sshはポートを変更。公開鍵認証はセキュリティ観点というより昨今は圧倒的にいろいろ楽です。

## docker エンジンセットアップ
> - [Get Docker Engine - Community for CentOS](https://docs.docker.com/install/linux/docker-ce/centos/)
- [Dockerを導入する（CentOS版）](https://qiita.com/zwirky/items/991f61a231f4e198a320)

Dockerは公式のドキュメントが非常に親切。公式の通りにやれば問題なく進みました。

## ドメイン取得、DNS設定
ムームードメイン、ムームーDNSを利用。(結果安かったので。)
今回サブドメインでルーティングするため、使いそうなサブドメインをAレコードとして追加しておきます。

※実はここで一番時間をロス。
2日待っても全然DNS解決されない→whoisで確認→client holdになっている→？
<font color="Crimson">→ドメイン開設後のメール認証忘れに気づく</font>
→メール認証→２時間後にDNS解決される状態に。

## マルチサイト構築(docker-compose)
ここからが今回の本番です。
> - [VPSにdockerで複数サイトをホスティングするには？](https://suin.io/561)
- [docker-composeを使うと複数コンテナの管理が便利に](docker-composeを使うと複数コンテナの管理が便利に)
- [[公式]複数の Compose ファイル](http://docs.docker.jp/compose/extends.html)

docker-composeでの運用をいろいろ検討しましたが、複数のComposeファイルがあるのは面倒だと感じ、ひとつで統一。

```:最終的なディレクトリ構成
~/web
├── .env
├── docker-compose.yml
├── wordpress
│   ├── index.php
│   ├── …
└── wordpress2
```
wordpressフォルダはvolumeをマウントすることで自動作成されます。

> - [Docker Compose でWordPress環境を作ってみる](http://bashalog.c-brains.jp/19/08/15-120000.php)

->ローカル環境で諸々の動作確認

> - [【Docker】マルチサイト構築（WrodPress,Ruby on Rails,Let'sEncrypt,nginx-proxy,postfix,MySQL）](https://qiita.com/pyuta/items/0e143d1fb910b10a2617)

-> かなり構成を参考にさせていただきました。``version: '2'``で書かれたcomposeファイルがあとあとうまくいかなくなったので最終的に``version: '3'``にしました。volumeのつくり方でつまづきその辺りを修正。networkの作り方やssl化はいろいろアレンジ。下記を好きなディレクトリに置いて```dokcer-compose up -d```を叩くと完成。

```:.env
MYSQL_ROOT_PASSWORD=mysqlxxx
WORDPRESS_DB_PASSWORD=mysqlxxx
```

```yml:docker-compose.yml
version: '3'

services:
  db:
    image: mysql:5.7
    container_name: mysql
    volumes:
      - "db-data:/var/lib/mysql"
    restart: always
    env_file: .env
    networks:
      - back_bridge
  wordpress:
    depends_on:
      - db
    image: wordpress
    container_name: wordpress
    expose:
      - "80"
    volumes:
      - "$PWD/wordpress:/var/www/html"
    env_file: .env
    environment:
      VIRTUAL_HOST: www.xxx.com
      WORDPRESS_DB_HOST: db:3306
      LETSENCRYPT_HOST: www.xxx.com
      LETSENCRYPT_EMAIL: xxx@xxx.com
    networks:
      - front_bridge
      - back_bridge
  db2:
    image: mysql:5.7
    container_name: mysql2
    volumes:
      - "db-data2:/var/lib/mysql"
    restart: always
    env_file: .env
    networks:
      - back_bridge
  wordpress2:
    depends_on:
      - db2
    image: wordpress
    container_name: wordpress2
    expose:
      - "80"
    volumes:
      - "$PWD/wordpress2:/var/www/html"
    env_file: .env
    environment:
      VIRTUAL_HOST: app1.xxx.com
      WORDPRESS_DB_HOST: db2:3306
      LETSENCRYPT_HOST: app1.xxx.com
      LETSENCRYPT_EMAIL: xxx@xxx.com
    networks:
      - front_bridge
      - back_bridge
  nginx-proxy:
    container_name: nginx_proxy
    image: jwilder/nginx-proxy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - html:/usr/share/nginx/html
      - dhparam:/etc/nginx/dhparam
      - vhost:/etc/nginx/vhost.d
      - certs:/etc/nginx/certs:ro
      - /var/run/docker.sock:/tmp/docker.sock:ro
    labels:
    - "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy"
    restart: always
    environment:
      TZ: Asia/Tokyo
    networks:
      - front_bridge
  letsencrypt-nginx-proxy-companion:
    image: jrcs/letsencrypt-nginx-proxy-companion
    container_name: nginx-proxy-lets-encrypt
    restart: always
    depends_on:
      - "nginx-proxy"
    volumes:
      - certs:/etc/nginx/certs:rw
      - vhost:/etc/nginx/vhost.d
      - html:/usr/share/nginx/html
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      NGINX_PROXY_CONTAINER: nginx-proxy
    networks:
      - front_bridge
      
volumes:
  db-data:
  db-data2:
  certs:
  html:
  vhost:
  dhparam:

networks:
  front_bridge:
    external: true
  back_bridge:
    driver: bridge

```

## つまづいたところ
　ローカルのmac環境ではdbを所定のフォルダにマウントしてもうまくいっていたのですが、VPS環境だとwordpress経由のアップロードの際<font color="Red">" Error establishing a database connection "</font>に。dockerプロセスとrootプロセスの不一致が原因でしたが、いろいろこういった事象はあるようで、DBのvolumeはdockerに管理してもらうことにしました。

ポートの開き方などもDockerの癖が結構あることを知りました。firewalldのテストなどでも結構「？」ということは多かったです。

あとdocker-compose.ymlをいじっている最中は```-d```オプションなしで```docker-compose up```を行うことを強く推奨します。

## あとがき
　つまづくことはあったものの、コンテナの構成のこなれ感には感動。この構成であればCentOSではない方が良い気がします。慣れの問題で片付けていいものか悩みどころです。あとkubernetes等コンテナ管理については別途ちゃんと考えたいと思います。あとはCMS自作など。あと監視など。フロントとバックエンドをいろいろ考えるとまた新しい困りごとが出てきそうだなと感じてます。

## その他参考
- 書籍
  - [プログラマのためのDocker教科書](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AEDocker%E6%95%99%E7%A7%91%E6%9B%B8-%E3%82%A4%E3%83%B3%E3%83%95%E3%83%A9%E3%81%AE%E5%9F%BA%E7%A4%8E%E7%9F%A5%E8%AD%98-%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AB%E3%82%88%E3%82%8B%E7%92%B0%E5%A2%83%E6%A7%8B%E7%AF%89%E3%81%AE%E8%87%AA%E5%8B%95%E5%8C%96-%E9%98%BF%E4%BD%90-%E5%BF%97%E4%BF%9D/dp/479814102X)

- nginx-proxy関連

> - [jwilder/nginx-proxy readme](https://github.com/jwilder/nginx-proxy/blob/master/README.md)
- [docker使用時の無許可ポートへのアクセスについて](https://teratail.com/questions/60817)
- [docker nginx-proxyとnetwork構成](https://riina-k.net/programming/docker-compose-nginx-reverse-proxy-network/)
- [実践編ーDockerを使ってnginxでリバースプロキシを立ててみる](https://qiita.com/zawawahoge/items/d58ab6b746625e8d4457)
- [jwilder/nginx-proxyで{ホスト名}/{パス}でコンテナにルーティングする方法](https://qiita.com/Ayumu_Usu/items/0891f3f733e355ed1265)
 - ->パスでルーティングもできる。

- Docker操作関連

> - [一発ですべてのDockerコンテナを停止・削除、イメージの削除をする](https://qiita.com/shisama/items/48e2eaf1dc356568b0d7)
- [docker-volume について](https://qiita.com/74th/items/41393f506d223850f2c3)
- [CentOS7にDockerでWordPressを入れる](https://qiita.com/kaityo256/items/0236db8b3	d92ee45f77b)

docker-compose関連

> - [docker env](https://qiita.com/kimullaa/items/f556431b8103e686f356)
- [docker-compose v3のletsencryptについて](https://tyablog.net/2019/07/14/https-using-docker-compose-and-nginx-proxy/)
- [docker-compose v3のletsencryptについて②](https://aroundthedistance.hatenadiary.jp/entry/2018/07/31/161602)