Nginx and Letsencrypt with certbot in docker alpine

 In Docker, Nginx, Security

UPDATE 31/08/2020

As Nicolas ponted out in the comments, the alpine software repositories already include the certbot package and therefore can be updated directly with apk:

apk add certbot certbot-nginx

Original post

In this lab we will learn how to install certbot using the official nginx:alpine docker image and use it to create a SSL certificate for our domain. Note that in order to make it work you must own the domain for which you’ll be fetching a certificate and it must resolve to the public IP address where the docker container is exposed.


This is the most tricky part when running certbot in an alpine based image, to be able to install certbot module we need to sort out some dependencies first. To save you the trouble of writing your own Dockerfile I am providing you with a working one:

FROM nginx:alpine
RUN apk add python3 python3-dev py3-pip build-base libressl-dev musl-dev libffi-dev
RUN pip3 install pip --upgrade
RUN pip3 install certbot-nginx
RUN mkdir /etc/letsencrypt

You will probably appreciate that we also created a folder for letsencrypt. We’ll use this to mount a volume to make letsencrypt data persistent and avoid losing the certificate when we kill the container.

Setting up Nginx configuration

The configuration that we are going to use is very simple. In fact, it is the default.conf file that comes with Nginx but we will get rid of some unnecessary stuff first. So go ahead and create a file called “default.conf” and set the following contents:

server {
    listen       80;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;

Remember to replace the server_name value with your own domain. Now, open the Dockerfile and add a new line at the end:

COPY default.conf /etc/nginx/conf.d/default.conf

Building the Docker image

This step is easy and I assume you already know how to build a Dockerfile, but here’s the command anyway:

docker build -t nginx-certbot .

Creating the new certificate with certbot

First, we will run the container overriding the entrypoint to execute the shell. We’ll also mount the letsencrypt folder to make certificate data persistent.

Warning: I would also advice to mount the nginx folder to a persistent volume, but that is outside the scope of this lab.

docker run -v $(pwd)/letsencrypt:/etc/letsencrypt --name nginx -ti -p 8080:80 nginx-certbot sh

Next, run the certbot command replacing with your real domain (same as you used for servername). Also note that you can add the www domain, just add a “-d” flag for every additional entry you need in the certificate:

certbot --nginx -d -d

Now certbot will ask you for an e-mail address that will be used for recovery and after that it will try to verify that you own the given domain. Note that if your server is not reachable in this domain, you will receive an error. If domain verification is successful, certbot will ask you if you wish to enable the HTTP to HTTPS redirection in nginx configuration. I recommend doing so.

Finally, Nginx will be reloaded and you should receive a message with the location of your certificates. You can now do a backup of these certificates if you wish.

Automate certificate renewal

You don’t want to be manually checking and renewing these certificates when they get close to the expiration date, so we will be adding a cronjob to do this for you:

0 12 * * * /usr/bin/certbot renew --quiet


As you can see it was not so difficult to create the SSL certificates for your domain using certbot.

I picked the alpine docker image for this lab because it’s probably one of the most troublesome base images to be using along certbot, I had myself some problems making it work properly in the past due to dependency issues. If you pick up an ubuntu based image it will probably be a lot easier to set up certbot, but the point is that alpine images are a usual choice because of it’s minimalist nature.

I hope you enjoyed this lab.

Feel the Geko way!

Recommended Posts
Showing 15 comments
  • Nicolas

    Hi, FYI there’s a certbot package on alpine’s registry :
    Works like a charm for me, even on ARM.

    • Xavi Miranda

      Hi, Nicolas!

      Indeed, I’ve verified that certbot package exists in alpine repositories. I’m not sure why I couldn’t find the package when I first struggled with this. I will update the post with your contribution.

      Still, I hope that this post can be useful for anyone who need to setup https certs using docker images.


  • John

    crond is not started on nginx:alpine, so the renewal will not work, unless I am missing something

    • Xavi Miranda

      Indeed, you are right, the crond should be running in the container alongside nginx. The post was not meant to be a full step-by-step guide from the beggining but I might update it.

      Thanks for your reply!

  • Arnau G

    El cron et farà la punyeta així Xavi!

    • Xavi Miranda

      Si, ho sé! He d’actualitzar el post, s’hauria de fer un override de l’entrypoint per aixecar el dimoni del cron en background.

      Gràcies per comentar!

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.