Dockerでnginx-proxyを使ったhttps(http2)リバースプロキシで開発環境を便利にする

# Docker で nginx-proxy を使った https(http2) リバースプロキシで開発環境を便利にする

## 前置き

諸先輩方のお知恵を拝借して、楽に開発環境を構築できる時代になりました。良い時代だなぁ〜

とはいえ、自分のやりたい事にジャストな情報というのは意外とないもので・・・

Mac / Win どちらでもとなると希少価値はグンと跳ね上がります！

そこで、個人的なローカル環境をいい感じに構築してみた内容をご紹介します。

## 内容

- [nginxを使ったリバースプロキシ on Docker - Qiita](https://qiita.com/ka2asd/items/372d30be64c57a8a81b1)
- [ローカル環境用SSLサーバ証明書を簡単に発行する(mkcert) - Qiita](https://qiita.com/rkunihiro/items/530b5dc685bd3bff2082)
- [Docker の nginx オフィシャルイメージで http2 を有効にするには - Qiita](https://qiita.com/ktateish/items/49ccb8d1cf622f65c8fc)
- [PlantUML Server を Docker で動かすときの URL ルート設定](https://blog.kteru.net/plantuml-server-path/)
- [docker-compose.ymlでDockerfileを指定したい - Qiita](https://qiita.com/kai_kou/items/eaafa3cb15e1496f50ec)

(順不同)を参考に

- [plantuml/plantuml-server - Docker Hub](https://hub.docker.com/r/plantuml/plantuml-server/) <- メイン
- [ianw/quickchart - Docker Hub](https://hub.docker.com/r/ianw/quickchart) <- サブ

のローカル環境を Docker で構築してみました。

## ポイント

- 極力楽に
- 極力最新に
- 極力環境依存ナシに
- 極力汎用的(自由度高)に

## 苦労した点

- Win (Windows10 WSL1) と Mac では工夫しないと共通化出来ない
    - `docker-compose` でわざわざ `Dockerfile` を呼んで、ファイルのマウントから `COPY` に変更
- SSLサーバ証明書は Let’s Encrypt が公式にも世の中的にも推されているが、ローカル環境では Too Match
    - `mkcert` で楽々証明書発行

## 構成

```
~/local
|--.gitignore
|--LICENSE
|--README.md
|--nginx-proxy
|  |--Dockerfile
|  |--certs
|  |  |--.gitkeep
|  |  |--plantuml.docker.crt
|  |  |--plantuml.docker.key
|  |  |--quickchart.docker.crt
|  |  |--quickchart.docker.key
|  |--docker-compose.yml
|  |--my_proxy.conf
|--plantuml-server
|  |--Dockerfile
|  |--docker-compose.yml
|  |--docker-entrypoint-custom.sh
|--quickchart
|  |--docker-compose.yml
```

### nginx-proxy

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

services:
  nginx-proxy:
#    image: jwilder/nginx-proxy:alpine
    build:
      context: .
      dockerfile: Dockerfile
    container_name: nginx-proxy
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
#      - ./my_proxy.conf:/etc/nginx/conf.d/my_proxy.conf:ro
#      - ./certs:/etc/nginx/certs:ro
    environment:
      - TZ=Asia/Tokyo

networks:
  default:
    external:
      name: nginx-proxy
```

コメントアウトした箇所を Dockerfile へ移動

```dockerfile:Dockerfile
FROM jwilder/nginx-proxy:alpine

COPY ./my_proxy.conf /etc/nginx/conf.d/my_proxy.conf
COPY ./certs /etc/nginx/certs
```

### plantuml-server

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

services:
  plantuml-server:
#    image: plantuml/plantuml-server:jetty
    build:
      context: .
      dockerfile: Dockerfile
    container_name: plantuml-server
    restart: always
#    volumes:
#      - ./docker-entrypoint-custom.sh:/docker-entrypoint-custom.sh
    entrypoint: /docker-entrypoint-custom.sh
    environment:
      - TZ=Asia/Tokyo
      - VIRTUAL_HOST=www.plantuml.docker
      - VIRTUAL_PORT=8080
      - CERT_NAME=plantuml.docker

networks:
  default:
    external:
      name: nginx-proxy
```

コメントアウトした箇所を Dockerfile へ移動

```dockerfile:Dockerfile
FROM plantuml/plantuml-server:jetty

COPY ./docker-entrypoint-custom.sh /docker-entrypoint-custom.sh
```

※ 公式の https://www.plantuml.com/plantuml に合わせる対応

```bash:docker-entrypoint-custom.sh
#!/bin/sh

mv /var/lib/jetty/webapps/ROOT.war /var/lib/jetty/webapps/plantuml.war
exec /docker-entrypoint.sh "$@"
```

### quickchart

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

services:
  quickchart:
    image: ianw/quickchart
    container_name: quickchart
    restart: always
    environment:
      - TZ=Asia/Tokyo
      - VIRTUAL_HOST=quickchart.docker
      - VIRTUAL_PORT=3400
      - CERT_NAME=quickchart.docker

networks:
  default:
    external:
      name: nginx-proxy
```

## 事前準備

```diff:/etc/hosts
+127.0.0.1    www.plantuml.docker
+127.0.0.1    quickchart.docker
```

```diff:NoProxy
+, *.docker
```

- `mkcert` (例: plantuml)

```bash:sh
cd certs
mkcert "*.plantuml.docker" plantuml.docker
mv _wildcard.plantuml.docker+1-key.pem plantuml.docker.key
mv _wildcard.plantuml.docker+1.pem plantuml.docker.crt
```

- 初回(無い場合)

```bash:sh
docker network create --driver bridge nginx-proxy
```

## ビルド(nginx-proxy, plantuml-server)

```bash:sh
docker-compose build
```

## 起動

```bash:sh
docker-compose up -d
```

## 停止

```bash:sh
docker-compose down -v --remove-orphans
```

### その他利用ツール類(参考)

- [oldj/SwitchHosts: Switch hosts quickly!](https://github.com/oldj/SwitchHosts#install)
    - hostsファイル編集ツール
- [Cntlmを使ってNTLMv2認証Proxy環境をやっつける - Qiita](https://qiita.com/yohskeey/items/6f17ea051fbe5568f3bf)
    - proxyツール

## 終わりに

リバースプロキシとそれ以外を分離しているので、network さえ繋げてしまえば他の docker 達も `environment` 設定だけで勝手に振り分けてくれます！素晴らしい！

```bash:sh
docker network connect nginx-proxy {コンテナ名}
```

モチロン上記の例の様に yaml ファイルで同名のネットワークを定義してもOK！