2025年6月19日木曜日

certbot を docker compose で使う

certbot を docker compose で使う

概要

これでホスト側に certbot やら nginx をインストールしないで済みます
今回は renew でかつ webroot モードを使います

P.S あとから気づいたのですが nginx-proxy 1.7.0 であればデフォルトで .well-known/acme-challenge/ へのアクセス経路は /etc/nginx/conf.d/default.conf に定義されているので nginx/default は不要です (あっても OK)
なので proxy コンテナへの nginx/default のマウントは不要です

環境

certbot の compose.yml

certbot:
  image: certbot/certbot
  volumes:
    - /etc/letsencrypt:/etc/letsencrypt
    - /var/lib/letsencrypt:/var/lib/letsencrypt
  command: renew --non-interactive --agree-tos --webroot -w /var/lib/letsencrypt
  restart: "no"
  • 発行された証明書はホスト側の /etc/letsencrypt に保存します
  • /var/lib/letsencrypt は webroot モードで発行される acme-challenge ファイルを配置するパスです、ホスト側にも acme-challenge ファイルを渡すことで各種アプリからも acme-challenge ファイル を参照できるようにします

nginx-proxy の compose.yml

proxy:
  image: jwilder/nginx-proxy
  restart: always
  ports:
    - "80:80"
    - "443:443"
  environment:
    - SSL_POLICY=AWS-TLS-1-2-2017-01
  volumes:
    - "/var/run/docker.sock:/tmp/docker.sock:ro"
    - "/var/lib/letsencrypt:/usr/share/nginx/html:ro"
    - "/home/your_domain/nginx:/etc/nginx/vhost.d"
    - "/etc/letsencrypt/live/your_domain.com/privkey.pem:/etc/nginx/certs/your_domain.com.key"
    - "/etc/letsencrypt/live/your_domain.com/fullchain.pem:/etc/nginx/certs/your_domain.com.crt"
  • /var/lib/letsencrypt を /usr/share/nginx/html にマウントすることで nginx から acme-challenge ファイルを見えるようにします
  • /home/your_domain/nginx/default ファイルを /etc/nginx/vhost.d/default にマウントします、こうすることですべての VirtualHost の設定に対してルールが適用されます

/home/your_domain/nginx/default ファイル

location ^~ /.well-known/acme-challenge/ {
    root /usr/share/nginx/html;  # docker run 時にボリュームマウントする
    try_files $uri =404;
}
  • 各アプリの /.well-known/acme-challenge/ へのアクセスを /usr/share/nginx/html にします
  • certbot の webroot モードでは /.well-known/acme-challenge/ にアクセスが来て acme-challenge ファイルが見えれば認証 OK となります
  • 基本は 404 にしておきます

cron 設定

5 0 5,16 * * cd /home/your_domain; docker compose start certbot

定期的に certbot コンテナを実行するようにしておけば OK です

動作確認

  • docker compose up -d

or

  • docker compose start certbot

で実際にコンテナを動かせば OK です
あとは acme-challenge テキストが見れるかどうかを curl などでテストしておいてもいいかもです

  • docker compose run --rm --entrypoint="" certbot mkdir -p /var/lib/letsencrypt/.well-known/acme-challenge
  • docker compose run --rm --entrypoint="" certbot touch /var/lib/letsencrypt/.well-known/acme-challenge/test.txt
  • docker compose exec proxy cat /usr/share/nginx/html/.well-known/acme-challenge/test.txt
  • curl http://your-domain.com/.well-known/acme-challenge/test

最後に

certbot をコンテナで実行し証明書を更新する方法を紹介しました
これでホスト側で certbot をインストールしたりする必要がなくなります
初回時のみ以下のように certonly する必要があるので注意しましょう

docker compose run --rm certbot \
  certonly --webroot -w /var/lib/letsencrypt \
  -d your_domain.com \
  -d www1.your_domain.com \
  --email your@email.com \
  --agree-tos --non-interactive

またモード (nginx など) によってやり方がだいぶ変わるのでその辺りも注意してください
今回紹介したのは webroot モードといって既存のアプリを使って ACME チャレンジする方式となっています

参考サイト

0 件のコメント:

コメントを投稿