Using Let's Encrypt with dockerized NGINX and Route53
Install CERTBOT and get your initial domain certificate
It’s best to run CERTBOT inside a docker container and make sure it issues the certificates to your host machine. You can use the following command to generate such a certificate:
docker run -it --rm --name certbot \
-v `pwd`/letsencrypt:/etc/letsencrypt certbot/certbot:latest \
certonly --server https://acme-v02.api.letsencrypt.org/directory \
--manual --preferred-challenges dns -d '*.example.com'
It will ask you some trivial questions, but the important part is that it generates a DNS challenge, so you should add a TXT record to the DNS of example.com. Add the proper record. You can check if the TXT record has propagated (if you have DIG) using the following command:
dig -t txt _acme-challenge.example.com '@8.8.8.8'
If it shows the value that has been provided by certbot, then you can complete the DNS and you’ll get the certificates.
Renew your certificates
The certificates from Let’s Encrypt are only valid for 90 days, so you need to renew them periodically. The best way is to use some kind of CRON job that runs every day and that checks if your certificates are soon to be renewed. If so, it will renew these certificates. Renewing the certificates is done using the certbot renew
command, but it doesn’t work for certificates that are created with the --manual
option. The actual problem is that the DNS needs to be updated and this requires manual intervention which doesn’t work well for automatic renewal.
In my case, the DNS is managed using AWS Route53 and there is a CERTBOT driver that can automate this process (if you have rights to manage Route53). I like to keep all my code inside docker containers, so I have created a small Dockerfile
that creates the image. It effectively only adds the correct driver to the certbot image, but it looks like this:
FROM certbot/certbot:v0.25.1
ENTRYPOINT [ "certbot" ]
EXPOSE 80 443
VOLUME /etc/letsencrypt /var/lib/letsencrypt
WORKDIR /opt/certbot
RUN pip install certbot_dns_route53==0.25.1
The pip install certbot_dns_route53==0.25.1
line is the only thing that is different from its base image. You can use newer versions, but make sure you update both the FROM
and RUN
lines so the versions match. You can create a new docker image using the following command: docker build . -t certbot-route53
.
Once you have created the docker image, you can create a script using the following command:
docker run -it --rm --name certbot \
-e AWS_ACCESS_KEY_ID=<your AWS access key> \
-e AWS_SECRET_ACCESS_KEY=<your AWS secret access key> \
-v `pwd`/letsencrypt:/etc/letsencrypt certbot-route53 \
certonly --server https://acme-v02.api.letsencrypt.org/directory \
--dns-route53 --email [email protected]
-d '*.example.com'
You can request certificates for all your domains, as long as they are managed via Route53. To renew the certificates, simply run the following command:
docker run -rm --name certbot \
-e AWS_ACCESS_KEY_ID=<your AWS access key> \
-e AWS_SECRET_ACCESS_KEY=<your AWS secret access key> \
-v `pwd`/letsencrypt:/etc/letsencrypt certbot-route53 \
renew
This will renew all certificates that are to be renewed.