プログラムを中心とした個人的なメモ用のブログです。 タイトルは迷走中。
内容の保証はできませんのであしからずご了承ください。

2022/06/14

Docker + Traefik でリバースプロキシサーバーを立てる

event_note2022/06/14 1:34

最初 nginx でリバースプロキシサーバーを構築していたのですが、いろいろ調べていく中で Traefik というサーバーの存在を知りました。

公式ではエッジルーターという言い方がされていますが、要はリバースプロキシ+ロードバランサーという感じらしいです。
nginx より後発で、Docker との親和性が高いとのことで試しに使ってみました。

環境

  • Docker: 20.10.12
  • Traefik: v2.7

Traefik 自身も Docker で動かします。

docker network の作成

アプリと Traefik で共通で使用するネットワークを作成しておきます。

$ docker network create sample-network

Traefik の設定

Traefik の設定は /etc/traefik/traefik.yml に記述する方法と、docker-compose.yml で指定する方法があるようです。
前者の例が多いですが、後者の方が docker-compose.yml 一つで設定が完結して良いと思うのは私だけでしょうか?

設定ファイルに記述する例

traefik.yml というファイルを作成して、以下のように記述します。

# Providers config
providers:
  # Docker との連携を有効にする
  docker:
    # false に指定することで Label 付けしていない docker コンテナを Traefik が無視するようになる
    exposedByDefault: false
    # 使用するネットワーク
    network: sample-network
entryPoints:
  # http という任意の名前のエントリーポイントを定義し、80番ポートをリッスンするよう指定
  http:
    address: ':80'
  https:
    address: ':443'
# API/Dashboard config
api:
  # WebUI にアクセスできるように設定
  insecure: true

Trafik を起動します。
ネットには docker-compose を使った例が多いですが、とりあえず docker run で動かしてみます。

$ docker run -it --rm \
        --name reverse-proxy \
        --network sample-network \
        -v /var/run/docker.sock:/var/run/docker.sock \
        -v $(pwd)/traefik.yml:/etc/traefik/traefik.yml \
        -p 80:80 \
        -p 8080:8080 \
        traefik:v2.7

とりあえずこれで、http://localhost:8080 にアクセスすると Traefik の WebUI が表示されるかと思います。

docker-compose.yml で設定する例

上記の設定を docker-compose.yml のみで行った場合の例です。

version: '3.9'
services:
  reverse-proxy:
    image: traefik:v2.7
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      # ファイルで設定する場合は以下
      #- type: bind
      #  source: ./traefik.yml
      #  target: /etc/traefik/traefik.yml
    ports:
      - 80:80
      - 8080:8080
    networks:
      - sample-network
    command:
      # traefik.yml の代わりに command で設定
      - --providers.docker.exposedByDefault=false
      - --providers.docker.network=sample-network
      - --entryPoints.http.address=:80
      - --entryPoints.https.address=:443
      - --api.insecure=true
networks:
  sample-network:
    external: true

アプリケーション側の設定

ルーティングの設定などは全てコンテナのラベルで設定します。 他のサーバーだとサーバー側の設定を変更する必要がありますが、 Traefik+Docker だとコンテナの増減に対して対応しやすいなと思いました。

とりあえず docker run で動かしてみます。

docker run -it --rm \
       --network sample-network \
       -l "traefik.enable=true" \
       -l "traefik.http.routers.api.entrypoints=http" \
       -l "traefik.http.routers.api.rule=Host(\"api.localhost\")"
       sample_app

これで http://api.localhost/ に該当のアプリにアクセスすれば繋がると思います。
解説は次に書いてあります。

docker-compose での例

上記の設定は、docker-compose.yml で以下のように設定します。
コメントで簡単な解説をつけておきました。

labels:
  # Traefik の有効化(exposedByDefault:false に設定した場合に必要)
  - traefik.enable=true
  # api という名前のルーターを定義し、
  # エントリーポイント http (traefik.yml で定義した名前) と関連付け
  - traefik.http.routers.api.entrypoints=http
  # ルーター api のホスト名を "api.localhost" に設定
  - traefik.http.routers.api.rule=Host(`api.localhost`)

基本は以上です。
他の詳細な設定については追々記事を書こうかなと思っています。