Nginx+Let's Encrypt(Certbot) on Docker

Alpine版NginxコンテナのSSL対応

Let’s EncryptによるSSL認証用ファイルをCertbot(Automatic Certificate Management Environment : ACME Client)により獲得し、NginxによるウェブサーバをSSL対応させます。

NginxのDockerイメージ作成時にDockerfileによりCertbotのインストールを指定します。

Alpine版Certbot(Nginx)

https://pkgs.alpinelinux.org/package/edge/community/x86/certbot-nginx

RUN apk add --no-cache bash nano awstats apache2-utils certbot-nginx

または、Nginxコンテナ稼働後、インストールして下さい。

# apk add certbot-nginx

Nginx設定ファイルの異なるserver_nameを持つserverセクション毎に、SSL認証ファイルを獲得するため、Nginxコンテナ内で以下コマンドを実行します。

# certbot --nginx -d www.testsite1.com -d www.testsite2.com

各サーバセクションにSSLアクセス(443)時に必要な認証ファイルディレクトリなどが追加されます。

server {
    listen 80;
    server_name www.testsite1.com;

    location / {
        proxy_pass http://your_server_ip:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
    listen 443 ssl;
    ssl_certificate /etc/letsencrypt/live/www.testsite1.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.testsite1.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
server {
    listen 80;
    server_name www.testsite2.com;

    location / {
        proxy_pass http://your_server_ip:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
    listen 443 ssl;
    ssl_certificate /etc/letsencrypt/live/www.testsite2.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.testsite2.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}

Nginx設定ファイルをリロードして動作を確認します。

# nginx -s reload

<参考サイト>

certbot renewコマンドによる証明書更新

crontabによる更新

nginxコンテナにインストールしたcertbotで更新する場合は、ホストマシンからcrontabで実行スケジュールを指定します。

毎週月曜日1:00,1:05に実行

$ sudo crontab -e

#certbot in nginx docker
0 1 * * 1 docker exec nginx bash -c "certbot renew >> /var/log/letsencrypt/renew.log"
5 1 * * 1 docker exec nginx bash -c "nginx -s reload"

証明書の削除 “certbot delete”

# certbot delete
Saving debug log to /var/log/letsencrypt/letsencrypt.log

Which certificate(s) would you like to delete?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: www.test001.com
2: www.test002.com
3: www.test001.org
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): c

または、

# certbot revoke --cert-name www.test001.com
# certbot --help
manage certificates:
    certificates    Display information about certificates you have from Certbot
    revoke          Revoke a certificate (supply --cert-path or --cert-name)
    delete          Delete a certificate

Certbot-Dockerhub

Dockerコンテナによる運用

スタンドアローンモード(オプション)
ウェブサーバ以外の用途で認証を取得する場合のオプションです。
認証取得には、ポート:80をオープンにする必要があるため、ウェブサーバ等は停止してから実行すること。

certonly:単に指定ドメインの認証を取得したいだけの場合

$ sudo docker run -it --rm --name certbot \
            -v "$PWD/letsencrypt:/etc/letsencrypt" \
            -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
            -p 80:80 \
            certbot/certbot certonly --standalone -d stun.example.com

コンテナ内の /etc/letsencrypt/live ディレクトリに証明書が作成されるため、-vオプションによりホスト側のアプリ指定のディレクトリと共有させます。