さくらVPSで独自ドメインをSSL化と更新の自動化をした。docker-composeのリバースプロキシにて。

2024-06-17

さくらVPS上で、DockerComposeにてリバースプロキシを立ち上げ、独自ドメインをSSL化および、自動更新されるように設定をしていきます。

本記事は、以下記事の摘要及び続きの自動化の部分を記します。

前回までの記事

DockerコンテナでCertbotを使ってHTTP-01 チャレンジする方法(無停止更新の準備)

Docker ComposeのリバースプロキシでHTTP-01 チャレンジからHTTPSでアクセスするまでの方法。

①独自ドメインのDNS設定

取得したドメインのネームサーバをさくらで使われているネームサーバに向けます。
https://help.sakura.ad.jp/domain/2302/

DNS設定1

さくらのDNS設定

次にさくらの会員メニューから、ドメインコントロールセンターを開きます。
リストにあるネームサーバサービスから「ネームサーバ新規登録」をクリックします。

DNS設定2

登録するドメイン名を入力します。
サブドメインであれば、サブドメインを入力しましょう。

DNS設定3

以下の画像のように追加されました。
当該ドメインの右端にある「ゾーン」をクリックします。

DNS設定4

次にDNSレコードを編集するため、「さくらのDNSに設定する(詳細設定)」にある「追加して設定」をクリックします。

DNS設定5

Aレコードを追加します。
エントリ名は、ドメイン(サブドメイン等)を入力します。
IPアドレスは、さくらVPSの管理画面の当該サーバのリストにあるIPアドレスを入力します。

それぞれ入力したら、「追加」をクリックします。

DNS設定6

追加されたのを確認できたら「保存」をクリックし完了です。

②HTTPアクセスさせる

リバースプロキシのnginx構成ファイルを編集します。
以下のようにserver_nameにドメインを取得して、プロキシパスに内部リソースを指定します。

server {
    listen 80;
    server_name example.com;
    location / {
         proxy_pass http://webapp01-web-1/;
         proxy_redirect off;
    }
}

構成やdocker-compose.ymlは前回までの記事と同様のため詳細は、以下よりご参照ください。
https://it.hasethblog.com/archives/267

confに上記記述をした後、リバースプロキシのnginxサービスを再起動すれば反映されます。
これでhttpにおいて指定のドメインでアクセスして期待するページが表示されれば成功です。

③証明書を発行・更新確認

以下の通りCertbotのインストールし、証明書をHTTP01チャレンジにて発行します。
https://it.hasethblog.com/archives/267

sudo certbot certonly --webroot -w /home/docker/reverse-proxy/certbot/www -d example.com

発行された証明書やシンボリックリンクが本来配置したい場所からズレてしまうので、それぞれバインドマウントしているホストディレクトリに移動させます。

そして、アクセス権限やrenewalにて証明書の設定を一部修正します。
詳細は以下ページにて記してあります。
https://it.hasethblog.com/archives/286

以下コマンドで更新処理を実行できます。更新は期限30日前以降しかできないため、その旨の警告が表示されるだけで実際は更新されません。

sudo certbot renew --cert-name example.com

--force-renewal オプションを使用することで強制的に更新します。
更新された後変更したパスにて処理が走れば成功です。

④HTTPSでアクセス

リバースプロキシのnginxのconfファイルにhttpsアクセスの記述を行います。
証明書の場所はリバースプロキシのコンテナ内でのパスを参照します。

server {
    listen 80;
    server_name example.com;
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }
    location / {
        return 301 https://$host$request_uri;
    }
}
server {
    listen 443 ssl;
    server_name example.com;
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    location / {
        proxy_pass http://webapp02-web-1/;
        proxy_redirect off;
    }
}

これで、https://example.com のようにアクセスすれば問題なくアクセスでき、
http://example.com でアクセスをするとhttpsに301転送されます。

⑤自動更新の設定

Let'sEncryptは、90日毎に証明書有効期限があります。手動で更新は煩雑すぎるため自動にて設定します。

docker-composeにて、以下を記述します。
私は、リバースプロキシの記述のあるdocker-compose.ymlに追記しました。

certbot:
  image: certbot/certbot
  volumes:
    - ./certbot/conf/live:/etc/letsencrypt/live
    - ./certbot/www:/var/www/certbot
    - ./certbot/conf/archive:/etc/letsencrypt/archive
  entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew --webroot -w /var/www/certbot; sleep 12h & wait $${!}; done;'"
  networks:
    - reverse-proxy-network
  restart: always

reverse-proxyと同様に、live及びarchive、acmeチャレンジ用のバインドマウントをします。

スクリプトの処理は、12時間毎にwebrootにて証明書更新を試みるようになっています。
(証明書更新の試行し、12時間スリープ、再度試行の無限ループ)

更新試行は証明書の有効期限30日前までは自動でキャンセルされ、30日前になると更新されるような仕組みです。

関連記事

DockerコンテナでCertbotを使ってHTTP-01 チャレンジする方法(無停止更新の準備)

Docker ComposeのリバースプロキシでHTTP-01 チャレンジからHTTPSでアクセスするまでの方法。