coredns + caddy + dockerで開発環境的なhttps

# 問題

1. httpsがないと動かない機能とかある
1. let's encryptですら面倒で自前でやりたくない
1. IPベースでなくサブドメインとかも含めた名前解決でアクセスしたい

# 解決

## docker + coredns

https://qiita.com/nomunomu0504/items/8bd03343072146e8bf27

これでhostsファイルベースで管理できるようにする。

## docker + caddy

これは素でcaddyのdocker版を使っても色々面倒なので[caddy-docker-proxy][1]を使う。
これを使うと、まずcaddy-docker-proxyを立てて、全く別のdocker-compose.ymlでcaddy用の設定をすると自動的に認識してくれて勝手にcaddyを設定してくれる。

### caddy-docker-proxy

```
$ docker network create caddy
```

した後に

```yml:docker-compose.yml（caddyを動かすだけ）
version: "3.7"
services:
  caddy:
    image: lucaslorentz/caddy-docker-proxy:2.3-alpine
    ports:
      - 80:80
      - 443:443
    environment:
      - CADDY_INGRESS_NETWORKS=caddy
    networks:
      - caddy
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./caddy/data:/data
    restart: unless-stopped

networks:
  caddy:
    external: true
```

### local https

開発環境なので、正式なドメイン名はない。このため[caddyが自己証明書を生成、設定][2]してくれる。
（このdocker-composeを動かした途端、上のcaddyが反応して勝手にCaddyfileを生成）

```yml:docker-compose.yml（local-https使う版）
version: "3.7"
services:
  whoami:
    image: jwilder/whoami
    networks:
      - caddy
    labels:
      caddy: test.domain.dev # ping出来ることは事前に確認しておく
      caddy.reverse_proxy: "{{upstreams 8000 }}"
      caddy.tls: "internal"
```

`caddy.tls: "internal"`が重要。

> Local HTTPS does not use ACME nor does it perform any DNS validation. It works only on the local machine and is trusted only where the CA's root certificate is installed.  

とあって、`ローカル`マシン上ではROOT CAが入っているので鍵マークはグリーンだと思う。しかしながら、これはあくまでも`ローカル`なので、ここの場合はこのコンテナ内ということになり、dockerのホストですらリモートアクセスしているのと変わらない（dockerホストにはROOT CAは入らない）

caddy用のdockerで`- ./caddy/data:/data`とvolume設定をしていて大切なデータはここに入ってる。

```
# apk add tree
# tree /data
...
...
    └── pki
        └── authorities
            └── local
                ├── intermediate.crt
                ├── intermediate.key
                ├── root.crt
                └── root.key
```

こうやってみると`root.crt`が`/data`内にあるのが分かるので、コンテナの中に入って

```
# cp /data/caddy/pki/authorities/local/root.crt /data/
```

とでもして、あとはdockerホスト側で

```
$ sudo chown $(whoami):$(whoami) data/root.crt
```

とかして自分がアクセスできるようにする。

これをMacであれば`Keychan Access`を開いて`System`にドロップする。そのままだと信頼されていないので、

![Screen_Shot_2021-05-17_at_10_06_59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16757/196d2479-759a-d2dd-a8eb-4f73a6728bce.png)

右クリックで`Get Info`から`Always Trust`してやる。

![Screen Shot 2021-05-17 at 10.05.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16757/327c7d4d-e01b-3346-e390-cfdc0336c645.png)

そうするとリモートアクセスしても鍵がグリーンで表示できる。

![Screen Shot 2021-05-17 at 9.55.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16757/6cbd18fa-46c1-08c5-d98d-fad636926859.png)

#### Firefoxの場合

![Screen Shot 2021-05-17 at 10.42.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16757/41f3e655-263a-0a30-515e-b0e74f0f418e.png)

設定でcertificateを検索して表示して、`Authorities`タブからroot.crtをインポートする。

![Screen Shot 2021-05-17 at 10.42.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16757/ef172a7d-070f-6042-f987-b034ac497b2f.png)

### というか、httpだけでいい

httpsなんか要らないよ、という場合は以下のように設定する。

```yml:docker-compose.yml
version: "3.7"
services:
  whoami:
    image: jwilder/whoami
    networks:
      - caddy
    labels:
      caddy: http://domain.tld
      caddy.reverse_proxy: "{{upstreams http 8000 }}"
```

`.tld`は架空のTLD。これが`.dev`など[HSTSプレロードリスト][3]に入っていないものを使わないとだめ。
最初、[`.dev`を使ってみて][4]どうしてもhttpsに転送されてた。

`http://...`と`upstreams http`が重要。この設定で`http://domain.tld`にアクセスするとhttpsにリダイレクトされず、通常のhttpで表示される。


[1]: https://github.com/lucaslorentz/caddy-docker-proxy
[2]: https://caddyserver.com/docs/automatic-https#local-https
[3]: https://www.itmedia.co.jp/enterprise/articles/1709/28/news053.html
[4]: https://en.wikipedia.org/wiki/.dev