Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save jesugmz/4570a40b1dcae9f18aa209fb8503db72 to your computer and use it in GitHub Desktop.
Save jesugmz/4570a40b1dcae9f18aa209fb8503db72 to your computer and use it in GitHub Desktop.
Let’s Encrypt certificate for dockerized Nginx under Cloudflare

Let’s Encrypt certificate for dockerized Nginx under Cloudflare

Real example about how to generate and add a Let's Encrypt SSL/TLS certificates to a dockerized Nginx under a running Docker Swarm using Cloudflare DNS to enable HTTPS.

https://certbot.eff.org/docs/using.html#dns-plugins

https://certbot-dns-cloudflare.readthedocs.io/en/stable/

1. Generate the certificate

It does not need to be generated in the real webserver itself.

Execute the following command after populate the Cloudflare credencials properly - in this example is located in /tmp/cloudflare-credentials.ini into the container:

docker run -it --rm \
  --name certbot \
  -v $(pwd)/cloudflare-credentials.ini:/tmp/cloudflare-credentials.ini \
  -v "/etc/letsencrypt:/etc/letsencrypt" \
  -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
  -p 443:443 \
  certbot/dns-cloudflare certonly --dns-cloudflare-credentials /tmp/cloudflare-credentials.ini --server https://acme-v02.api.letsencrypt.org/directory

The output of the previous should be like this one for the first time - in this case we want to generate certificates for the root domain and wildcard domains aka *.domain.tld:

Saving debug log to /var/log/letsencrypt/letsencrypt.log

How would you like to authenticate with the ACME CA?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Obtain certificates using a DNS TXT record (if you are using Cloudflare for
DNS). (dns-cloudflare)
2: Spin up a temporary webserver (standalone)
3: Place files in webroot directory (webroot)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-3] then [enter] (press 'c' to cancel): 1
Plugins selected: Authenticator dns-cloudflare, Installer None
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): jesus.gomez@pepecos.es

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: N
Please enter in your domain name(s) (comma and/or space separated)  (Enter 'c'
to cancel): pepecos.es, *.pepecos.es
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for pepecos.es
dns-01 challenge for pepecos.es
Unsafe permissions on credentials configuration file: /tmp/cloudflare-credentials.ini
Waiting 10 seconds for DNS changes to propagate
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/pepecos.es/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/pepecos.es/privkey.pem
   Your cert will expire on 2019-02-22. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

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

2. Build the new Docker image for Nginx

Copy the generated certificate into your project folder:

cp /etc/letsencrypt/live/pepecos.es/fullchain.pem my-project/docker/webserver/ssl-certificates/fullchain.pem
cp /etc/letsencrypt/live/pepecos.es/privkey.pem my-project/docker/webserver/ssl-certificates/privkey.pem

Add them into your Nginx Dockerfile:

# ...
COPY ./docker/webserver/config/web.prod.conf /etc/nginx/conf.d/pepecos.conf
COPY ./docker/webserver/ssl-certificate/fullchain.pem /etc/letsencrypt/live/pepecos.es/fullchain.pem
COPY ./docker/webserver/ssl-certificate/privkey.pem /etc/letsencrypt/live/pepecos.es/privkey.pem

A minimal configuration needs to be append into the Nginx server block. In this case we put the minimal needed configuration:

server {
  # Let’s Encrypt certificates
  # https://www.nginx.com/blog/free-certificates-lets-encrypt-and-nginx/
  listen      443 ssl default_server;

  # ...

  ssl_certificate /etc/letsencrypt/live/pepecos.es/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/pepecos.es/privkey.pem;

  # ...
}

Build your image and push it to your registry.

Repeat the process for each Docker image where you want to use the previous certificate.

3. Release the new Docker image

Update the service in Docker Swarm adding the port exposure for HTTPS:

docker service update --with-registry-auth --publish-add published=443,target=443 --image registry.gitlab.com/pepecos/web/webserver:prod-v1.1.0 web-webserver

Renewing the certificate

Just repeat the steps from 1 to 3.

Notes

  • If your Nginx service is back to a firewall keep in mind to open the port
  • Let's Encrypt certificates need to be updated after 3 month
  • The certificate does not need to be generated in the real webserver itself
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment