Traefikでリバースプロキシ on Docker

# Traefikとは
https://traefik.io/traefik/
サービスの公開が簡単で楽しいものになるオープンソースのエッジ―ルーター。
Path,Host,Headerなどでリクエストをルーティングしてくれます。
後、WebUIやら負荷分散などもあったり多機能。

![](https://doc.traefik.io/traefik/v2.3/assets/img/traefik-concepts-1.png)

# やりたいこと
今回はRaspberryPi4上で動いているhttps-portalからTraefikに移行します。
ちなみにhttps-portalもリバースプロキシで自動でSSLの証明書の発行などをしてくれるnginx-proxyという感じ。
設定ファイルの記述などで混乱したので備忘録。

# 環境

- RaspberryPi 4
- Traefik 2.3.4
- docker-compose

https://hub.docker.com/_/traefik
https://github.com/traefik/traefik/

## docker-compose.yml (Traefik)
```yaml:docker-compose.yml
version: '3'
services:
  traefik:
    image: traefik:v2.3.4
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik.yml:/etc/traefik/traefik.yml
      - /data/ssl_certs/traefik/acme.json:/etc/traefik/acme.json
    networks:
      - traefik
    env_file:
      - dns_challenge_secrets.env
networks:
  traefik:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.30.0.0/24
```
### ポート
  8080 はダッシュボード用です。

### ストレージ
```yaml
    volumes:
      # Docker全体のイベントを監視するため
      - /var/run/docker.sock:/var/run/docker.sock:ro
      # Traefikの設定ファイル
      - ./traefik.yml:/etc/traefik/traefik.yml
      # ACME認証情報が保存されるファイル
      - /data/ssl_certs/traefik/acme.json:/etc/traefik/acme.json
```

### ネットワーク
```yaml
networks: # Traefikが管理するネットワーク。よしなに。
  traefik:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.30.0.0/24
```

## traefik.yml
```yaml:traefik.yml
api:
  dashboard: true
  insecure: true

entryPoints:
  http: # エントリーポイント名
    address: ":80"
  https:
    address: ":443"

providers:
  docker:
    network: sample_traefik
    exposedByDefault: false

certificatesResolvers:
  letsencrypt: # resolver名
    acme:
      email: admin@example.com
      storage: /etc/traefik/acme.json
      dnsChallenge:
        provider: cloudflare

```
ポイントは

- entryPoints ... エントリーポイントを設定。 docker-compose側も忘れずに。
- providers: docker: ... プロバイダをDockerに設定。
- network ... ネットワーク名
- exposedByDefault ... 有効にしていると、ポートがexposeされている全てのサービスを登録されてしまいます。
                       今回は無効にするので各サービスにtraefik.enable=trueすることで管理してもらいます。
certificatesResolvers ... SSLの認証関係。 今回はLet's EncryptでcloudflareのドメインをDNS-01チャレンジで証明書を発行します。
プロバイダ一覧
https://doc.traefik.io/traefik/https/acme/#providers


## docker-compose.yml (サービス)
最後にサービス側の設定

```yaml:docker-compose.yml
services:
  web:
      build: .
      ports:
        "8000:80"
      labels:
        - traefik.enable=true
        - traefik.http.routers.servicename.rule=Host(`blabla.example.com`)
        - traefik.http.routers.servicename.entrypoints=https
        - traefik.http.routers.servicename.tls=true
        - traefik.http.routers.servicename.tls.certresolver=letsencrypt

networks:
  default:
    externa:
      name: sample_traeeafik
```

とりあえずTreafikのネットワークに接続します。
そしてTraefikの各種設定を labelsに追加していきます。

- traefik.enable ... exposedByDefault: false の時に必須。
- traefik.http.routers.servicename.rule ... ルーティングのルールを設定します。
  - Host(`blabla.example.com`) ... Hostでフィルタリングします。
- traefik.http.routers.servicename.entrypoints ... 設定したエントリーポイントのどれを使うか
- traefik.http.routers.servicename.tls ... tlsを有効に
- traefik.http.routers.servicename.tls.certresolver ... 設定した認証のリゾルバ名

これで後はTraefikが勝手にやってくれます。

# 最後に
nginx-proxyよりも多機能で、SSLの証明書の再発行などもこれ一つで勝手にやってくれます。
更新も頻繁なこともあり、ネット上に微妙に違う設定の情報が多くややこしかったのでメモ。

### 参考
https://doc.traefik.io/traefik/v2.3/providers/docker/
https://dev.to/cedrichopf/get-started-with-traefik-2-using-docker-compose-35f9