🐥

TraefikでHTTPS化した複数コンテナを運用する

2024/07/04に公開

概要

TraefikでHTTPS化した複数コンテナを運用する方法に関する備忘録です。

https://github.com/traefik/traefik

背景

これまで、jwilder/nginx-proxyjrcs/letsencrypt-nginx-proxy-companionを使い、以下のような構成で運用していました。

プロキシ

docker-compose.yml
version: '3'
# proxy
services:

  nginx-proxy:
    image: jwilder/nginx-proxy
    container_name: nginx-proxy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - html:/usr/share/nginx/html
      - dhparam:/etc/nginx/dhparam
      - vhost:/etc/nginx/vhost.d
      - certs:/etc/nginx/certs:ro
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - /srv/docker/nginx-proxy-with-encrypt/log:/var/log/nginx
    labels:
      - "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy"
    restart: always

  letsencrypt:
    image: jrcs/letsencrypt-nginx-proxy-companion
    container_name: nginx-proxy-lets-encrypt
    depends_on:
    - "nginx-proxy"
    volumes:
    - certs:/etc/nginx/certs:rw
    - vhost:/etc/nginx/vhost.d
    - html:/usr/share/nginx/html
    - /var/run/docker.sock:/var/run/docker.sock:ro

volumes:
  certs:
  html:
  vhost:
  dhparam:

networks:
  default:
    external:
      name: common_link

コンテナ

以下は、Djangoの例です。

docker-compose.yml
version: "3"
services:
  nginx:
    image: nginx:latest
    ports:
      - "18001:80"
    volumes:
      - ./default.conf:/etc/nginx/conf.d/default.conf
      - ./.htpasswd:/etc/nginx/.htpasswd
    depends_on:
      - dns    
    environment:
      VIRTUAL_HOST: django.yyy.zzz
      LETSENCRYPT_HOST: django.yyy.zzz
      LETSENCRYPT_EMAIL: xxx
  dns:
    build:
      context: ../
      dockerfile: ./docker/Dockerfile # Dockerfileのディレクトリを指定します
    volumes:
      - "../web:/mysite"
    container_name: dns
    tty: true # ポート待受とかしていないコンテナの場合、trueに設定しておくとコンテナが起動し続けます
    working_dir: "/mysite"

networks:
  default:
    external:
      name: common_link

Basic認証をかけるにあたり、djangoに加えて、nginx:latestも使用していました。

Traefikの利用

Traefikでは、以下のような構成に変わりました。

プロキシ

docker-compose.yml
services:
  traefik:
    image: traefik:latest
    container_name: traefik
    restart: always
    ports:
      - 443:443
      - 80:80
    networks:
      - traefik-network
    environment:
      TZ: Asia/Tokyo
    labels:
      traefik.enable: true
      traefik.http.routers.dashboard.rule: Host(`proxy.yyy.zzz`)
      traefik.http.routers.dashboard.entrypoints: websecure
      traefik.http.routers.dashboard.tls.certresolver: myresolver

      traefik.http.routers.dashboard.middlewares: auth
      traefik.http.middlewares.auth.basicauth.users: xxxxxxxxx

    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./letsencrypt:/letsencrypt
      - ./traefik.yml:/etc/traefik/traefik.yml:ro

networks:
  traefik-network:
    external: true
traefik.yml
log:
  # level: DEBUG

entryPoints:
  web:
    address: :80
    http:
      redirections:
        entryPoint:
          to: websecure
          schema: https
          permanent: true
  websecure:
    address: :443

api:
  dashboard: true

providers:
  docker:
    exposedByDefault: false

certificatesResolvers:
  myresolver:
    acme:
      email: aaa@bbb
      storage: /acme.json
      caServer: https://acme-v02.api.letsencrypt.org/directory
      # caServer: https://acme-staging-v02.api.letsencrypt.org/directory
      httpChallenge:
        entryPoint: web

コンテナ

Traefikのミドルウェアを使って、Basic認証を実現するようにしました。

docker-compose.yml
services:
  dns:
    build:
      context: ../
      dockerfile: ./docker/Dockerfile # Dockerfileのディレクトリを指定します
    volumes:
      - "../web:/mysite"
    ports:
      - "18001:8000"
    container_name: dns
    tty: true # ポート待受とかしていないコンテナの場合、trueに設定しておくとコンテナが起動し続けます
    working_dir: "/mysite"
    networks:
      - traefik-network
    restart: always
    labels:
      traefik.enable: true
      traefik.http.routers.dns.rule: Host(`django.yyy.zzz`)
      traefik.http.routers.dns.entrypoints: websecure
      traefik.http.routers.dns.tls.certresolver: myresolver

      traefik.http.routers.dns.middlewares: dns
      traefik.http.middlewares.dns.basicauth.users: xxxxxxxxx

networks:
  traefik-network:
    external: true

この設定をコンテナごとに作成することで、複数のコンテナを同様の環境で運用することができます。

まとめ

間違った理解、および考慮が足りない点もあるかもしれませんが、HTTPS化(+Basic認証)したコンテナを複数運用する方法として、参考になりましたら幸いです。

Discussion