docker-compose + Nginx Proxy Manager でマルチドメインアクセス（SSL）可能なWebサーバ環境を構築する（Nextcloud）

#目的
Nginx Proxy Managerにリバースプロキシさせその後ろにdocker-composeで立ち上げたWebアプリをぶら下げていく事ができる環境を構築する。

#構想
![構想イメージ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2312436/977787be-f6e5-03c4-9227-8056072a0093.png)

#環境
Ubuntu 20.04.1 LTS
名前解決できるドメイン所持

#概要
1. Docker、Docker Compose のインストール
1. docker-compose.ymlの作成
1. Nginx Proxy Managerの設定
1. 動作確認

##1. Docker、Docker Compose のインストール
###Dockerのインストール
公式が用意しているシェルスクリプトを実行しDockerをインストールします。

```
 curl https://get.docker.com | sh
```
Dockerが常時起動するようにします。

```
sudo systemctl start docker
sudo systemctl enable docker
```
正常にインストール出来ているか確認します。

```
$ docker --version
Docker version 20.10.11, build dea9396
```
###Docker Compose のインストール
Dockerプラグインディレクトリを作成します。

```
mkdir -p $HOME/.docker/cli-plugins
```
Docker Composeのgithub上のリリースページから最新バージョンを確認します。(執筆時 v2.1.1)
以下の2.1.1の部分を確認したバージョンに置き換えてください。↓

https://github.com/docker/compose/releases

```
curl -Lf -o $HOME/.docker/cli-plugins/docker-compose "https://github.com/docker/compose/releases/download/v2.1.1/docker-compose-linux-x86_64"
```
バイナリに対して実行権限を付与します。

```
sudo chmod +x /usr/local/bin/docker-compose
```
正常にインストール出来ているか確認します。

```
$ docker compose version
Docker Compose version v2.1.1
```

##2. docker-compose.ymlの作成
コンテナ間を接続するためにネットワークを作ります。

```
sudo docker network create front
```
作業ディレクトリを作成します。

```
mkdir docker
mkdir docker/{nginx-proxy,nextcloud}
```
nginx-proxy、nextcloudそれぞれのディレクトリにdocker-compose.ymlを作成し実行していきます。
###Nginx Proxy Managerコンテナ

```
cd docker/nginx-proxy
sudo vim docker-compose.yml
```

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

services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'
    restart: always
    ports:
      - '80:80'
      - '443:443'
      - '81:81'
    environment:
      DB_MYSQL_HOST: "db"
      DB_MYSQL_PORT: 3306
      DB_MYSQL_USER: "npm"
      DB_MYSQL_PASSWORD: "npm"
      DB_MYSQL_NAME: "npm"
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
    depends_on:
      - db
    networks:
      - front
      - back

  db:
    image: 'jc21/mariadb-aria:latest'
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: 'npm'
      MYSQL_DATABASE: 'npm'
      MYSQL_USER: 'npm'
      MYSQL_PASSWORD: 'npm'
    volumes:
      - ./mysql:/var/lib/mysql
    networks:
      - back

volumes:
  data:
  letsencrypt:
  mysql:

networks:
  front:
    external: true
  back:
```
Docker Composeを実行します。

```
sudo docker-compose up -d
```
コンテナが正常に動作しているか確認します

```
$ sudo docker-compose ps
      Name             Command       State                   Ports                
----------------------------------------------------------------------------------
nginxproxy_app_1   /init             Up      0.0.0.0:443->443/tcp,:::443->443/tcp,
                                             0.0.0.0:80->80/tcp,:::80->80/tcp,    
                                             0.0.0.0:81->81/tcp,:::81->81/tcp     
nginxproxy_db_1    /scripts/run.sh   Up      3306/tcp       
```

###Nextcloudコンテナ

```
cd docker/nextcloud
sudo vim docker-compose.yml
```

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

services:

  nextcloud-app:
    image: nextcloud:latest
    restart: always
    environment:
       MYSQL_HOST: "db"
       MYSQL_USER: "nextcloud"
       MYSQL_PASSWORD: "nextcloud"
       MYSQL_DATABASE: "nextcloud"
       # PHP_MEMORY_LIMIT=5120M 
       # PHP_UPLOAD_MAX_FILESIZE=512M
       # PHP_POST_MAX_SIZE=512M
    volumes:
      - ./data:/var/www/html
    networks:
      - front
      - back

  db:
    image: mariadb
    restart: always
    environment:
       MYSQL_USER: "nextcloud"
       MYSQL_ROOT_PASSWORD: "nextcloud"
       MYSQL_PASSWORD: "nextcloud"
       MYSQL_DATABASE: "nextcloud"
    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW --innodb_read_only_compressed=OFF
    volumes:
      - ./db:/var/lib/mysql
    networks:
      - back

volumes:
  nextcloud-data:
  nextcloud-db:

networks:
  front:
    external: true
  back:
```
Docker Composeを実行します。

```
sudo docker-compose up -d
```
コンテナが正常に動作しているか確認します。

```
$ sudo docker-compose ps
          Name                         Command               State    Ports  
-----------------------------------------------------------------------------
nextcloud_db_1              docker-entrypoint.sh --tra ...   Up      3306/tcp
nextcloud_nextcloud-app_1   /entrypoint.sh apache2-for ...   Up      80/tcp 
```


```:最終的なファイルツリー
docker
├── nextcloud
│   ├── data
│   ├── db
│   ├── docker-compose.yml
│   └── mysql
└── nginx-proxy
    ├── data
    ├── docker-compose.yml
    ├── letsencrypt
    └── mysql

```

##3. Nginx Proxy Managerの設定
ブラウザのアドレスバーに`localhost:81`と入力し、Nginx Proxy Managerを開く。
![nginx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2312436/322eebeb-c263-0a62-ef9f-bd437ec3a2fb.png)
デフォルトのメールアドレスとパスワードを入力しログインする。
`Email:    admin@example.com
Password: changeme`
![nginx2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2312436/c97a9afd-eb25-b831-956d-42cfd9d5c1da.png)
ユーザ情報変更を促されるので変更します。
メールアドレスは証明書発行の際に使うので架空のものはやめたほうが良いと思います。
Save後、右上のアイコンをクリックしChangePasswordからパスワードを変更しておきます。
次回から変更したメールアドレスとパスワードでログインするので忘れないようにしましょう。

「Dashboard > Proxy Host > Add Proxy Host」からプロキシの設定を行う。
![nginx3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2312436/127cc4bb-ca78-122f-c164-c7d22968779c.png)
Domain Namesには取得しているドメインを入力してください。
このドメインへアクセスすると、今回立ち上げたnextcloudへ接続されるようになります。
次にSSL証明書を発行しSaveします。
![nginx4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2312436/6e479460-29ce-0835-c91f-a93f4833a0a6.png)

##4. 動作確認
先程入力したドメインにアクセスしhttps接続になっていることを確認します。
![nginx5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2312436/8cd8389d-3ab6-f97a-c709-dc419ab8170a.png)
お疲れさまでした。

#一応
余計な情報は表示させたくないので
Nginx Proxy ManagerのSettingsからNginxのデフォルトページをNotFoundに変更しておく。
![nginx6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2312436/40392020-8b6f-5ce4-214e-e2c7d3c5485f.png)

#引っ掛かりそうなところ
- ファイアウォールを設定している場合80,443ポートを開けていない
- ルーターのポート開放をしていない
- ヘアピンNAT非対応のルーターを使っている（宅内からWAN側にアクセス出来ない）

#あとがき
追加でnextcloud以外のアプリをぶら下げたい場合は同じネットワークに所属させてあげれば良いです。

```
networks:
  front:
    external: true
```

#参考
https://docs.docker.jp/linux/step_one.html

https://zenn.dev/ciffelia/articles/dc2f8acb33ace6

https://nginxproxymanager.com/setup/#running-the-app

[Docker-nextcloud](https://hub.docker.com/_/nextcloud)

#更新履歴
- 2021/11/24: 初版