huruyosi’s blog

プログラミングとかインフラとかのメモです。

Dockerコンテナで稼動しているnginxを使ってLet's Encrypt の証明書を発行する - 実践

前回思いついたことを実際に試して見ました。

huruyosi.hatenablog.com

目次

実際にやってみる

webroot用のコンテナを作成

/usr/share/nginx/html/ディレクトリを管理するためのコンテナを作成します。 Dockerfileを

FROM centos:centos7

MAINTAINER huruyosi<huruyosi@example.co.jp>

RUN mkdir -p /usr/share/nginx/html
ADD nginx/usr/share/nginx/html/ /usr/share/nginx/html/
VOLUME ["/usr/share/nginx/html"]

にして、

$ sudo docker build -t nginx_data .
$ sudo docker run -it --name nginx_data nginx_data ls

を行ってnginx_dataという名前のコンテナを作成します。

nginxのコンテナの起動オプションを変更

$ /usr/bin/docker run -v /etc/letsencrypt/:/etc/letsencrypt/ --volumes-from nginx_data  -p 443:443 -p 80:80 --name nginx nginx:latest

--volumes-fromオプションを使ってwebroot用のデータコンテナをマウントします。また、ホストの/etc/letsencryptディレクトリもマウントしておきます。

更新用Let's Encryptのコンテナ作成

Dockerfileを

FROM centos:centos7

MAINTAINER huruyosi<huruyosi@example.co.jp>

# set timezone
RUN echo 'ZONE="Asia/Tokyo"' > /etc/sysconfig/clock
RUN rm -f /etc/localtime
RUN ln -fs /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

RUN yum install -y git && \
    cd /root && \
    git clone https://github.com/letsencrypt/letsencrypt && \
    cd /root/letsencrypt && \
    ./letsencrypt-auto --help


ENTRYPOINT ["/root/letsencrypt/letsencrypt-auto"]
CMD ["certonly","--webroot","-w","/usr/share/nginx/html","-d","www.example.co.jp","--renew-by-default"]

letsencrypt-autoコマンドに--renew-by-defaultオプションを指定します。 これを docker build -t letsencrypt .でビルドします。

証明書の更新を行う

webroot用のデータコンテナとホストの/etc/letsencryptをマウントして実行します。letsencrypt-autoコマンドの引数はDockerfileの CMD にある通りです。

$ sduo docker run -i -t --rm --name letsencrypt --volumes-from nginx_data -v /etc/letsencrypt/:/etc/letsencrypt/ infra/letsencrypt
$ sudo systemctl restart nginx

結果は

Updating letsencrypt and virtual environment dependencies......
Requesting root privileges to run with virtualenv: /root/.local/share/letsencrypt/bin/letsencrypt certonly --webroot -w /usr/share/nginx/html -d www.example.co.jp --renew-by-default

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/mng.akky.org/fullchain.pem. Your cert will
   expire on 2016-04-08. To obtain a new version of the certificate in
   the future, simply run Let's Encrypt again.
 - If you like Let's Encrypt, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

となり、証明書の更新が成功しました。/etc/letsencrypt/archive/ディレクトリを見ると新しい証明書が作成されていました。

cronで更新する

/etc/cron.monthly/letsencrypt_update.sh を作成して、月初に実行します。 letsencrypt_update.shの中身は上で実行した証明書を更新するコマンドと同じです。

#!/bin/sh

docker run -i -t --rm --name letsencrypt --volumes-from infra_nginx_data -v /etc/letsencrypt/:/etc/letsencrypt/ infra/letsencrypt
systemctl restart nginx

やった後に気づいたこと

--tls-sni-01-portオプションと--http-01-portオプションでポートを変更すればnginxに手を出さなくても実現できるんじゃないかな。

参考サイト

Let’s Encrypt サーバー証明書の取得と自動更新設定メモ | あぱーブログ