2025年2月24日月曜日

dockerコンテナのswagを通してLet's encryptを利用したhttps対応


背景

webサーバーのhttpsの設定をdockerのコンテナにまとめて管理を容易にしたかったので、それが実現できるコンテナswagを使ってみました。
備忘録として実施内容と関連リンクを記事に残します。

使ったもの

  • ドメインを割り当てたサーバー
    この記事では some-subdomain.some-host.com を割り当てたサーバーを例にして解説します。
  • docker compose
  • サーバー上でlocalhost:3000で動いているwebアプリ

swagとは: Let's encryptとやりとりしてくれる便利なgatewayコンテナ

swagはサーバープログラムnginxでgatewayを構成しながら、Let's encryptとやりとりするプログラムCertbotも動かして必要な認証情報を配置してくれる便利なgatewayコンテナです。

hub.docker.com/r/linuxserver/swag
github.com/linuxserver/docker-swag

以前はletsencryptという名前で作られていたコンテナがswagに名称変更されて開発が続けられているようです。

hub.docker.com/r/linuxserver/letsencrypt
github.com/linuxserver-archive/docker-letsencrypt

設定方針: サブドメインのurlに対してhttpsリクエストを有効にしつつ、localhost:3000で動いているサーバーに繋ぐ

図示するとこうです。

swagのコンテナにLet's encryptと連携するプログラムcertbotとリクエスト管理サーバーであるnginxが含まれているので、下記の処理をさせます。
  • Ler's encryptから認証鍵を取得
  • http:(80ポート)へのアクセスをhttpsに転送
  • https(443ポート)へのアクセスをlocalhost:3000に接続

上記の処理のための設定方法を解説します。

docker-composeと関連ファイルを設定

swagのdocker-composeの説明を参考にしながらファイルを作ります。
docker-compose.yml
services:
swag:
image: lscr.io/linuxserver/swag
container_name: swag
cap_add:
- NET_ADMIN
environment:
- PUID=1000
- PGID=1000
- TZ=Asia/Tokyo
- URL=some-subdomain.some-host.com
# - SUBDOMAINS=www,
- VALIDATION=http
# - CERTPROVIDER= #optional
# - DNSPLUGIN=cloudflare #optional
# - EMAIL=<e-mail> #optional
# - ONLY_SUBDOMAINS=false #optional
# - EXTRA_DOMAINS=<extradomains> #optional
- STAGING=false #optional
volumes:
- ./config:/config
ports:
- 443:443
- 80:80 #optional
restart: unless-stopped
extra_hosts:
- "host.docker.internal:host-gateway"

今回はサブドメインに対して設定したかったので、HOSTにサブドメインのurlを設定し、SUBDOMAINSを空にしました。
      - URL=some-subdomain.some-host.com
# - SUBDOMAINS=www,

dockerからlocalhostを呼び出すためのhost.docker.internalの設定を有効にしました。
これを利用してnginxの設定でlocalhost:3000で動いているサーバーにリクエストを転送します。
    extra_hosts:
- "host.docker.internal:host-gateway"

docker-compos.ymlと同じ階層にあるconfigディレクトリをswagに置きます。
後ほど作成するnginsの設定ファイルはこの中に置きます。
    volumes:
- ./config:/config

httpのhttpsへの転送とhttpsをlocalhost:3000に繋ぐnginxの設定

swagのnginxの標準設定やnginxの説明を参考にしつつ設定ファイルを作成します。
config/nginx/proxy-confsにあるconfファイルは読み込まれる設定になっているので、ファイルを置いてコンテナを起動すれば反映されます。

[docker-compose.ymlがあるのと同じディレクトリ]/config/nginx/proxy-confs/some-subdomain.some-host.com.conf
# redirect all traffic to https
server {
listen 80;
listen [::]:80;
server_name some-domain.some-host.com;

location / {
return 301 https://$host$request_uri;
}
}

# main server block
server {
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate /config/keys/cert.crt;
ssl_certificate_key /config/keys/cert.key;

server_name some-domain.some-host.com;
include /config/nginx/ssl.conf;

location / {
proxy_set_header Host $http_host;
proxy_pass http://host.docker.internal:3000;
}
}

http://some-domain.some-host.com(80ポート)への要求は301応答でhttpsに転送しています。
server {
listen 80;
listen [::]:80;
server_name some-domain.some-host.com;

location / {
return 301 https://$host$request_uri;
}
}

https://some-domain.some-host.com(443ポート)への要求はdockerのhost.docker.linternalを通してlocalhost:3000で動くサーバーに接続しています。
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name some-domain.some-host.com;

location / {
proxy_set_header Host $http_host;
proxy_pass http://host.docker.internal:3000;
}
}

解説は以上です。

おわり

swagを通してLet's encryptを利用したhttps対応ができました。
便利なコンテナの提供がありがたいです。

参考

Swag docker-compose
hub.docker.com/r/linuxserver/swag
github.com/linuxserver/docker-swag
nginx/site-confs/default.conf.sample

0 件のコメント :