Docker + Free SSL/TLS Certs (Let’s Encrypt)
By: Gary Ascuy
Tags: Docker, Nginx, Lets Encrypt, Ssl Certificate, Free

Long time ago I’ve deploy an API to use into a mobile application, reviewing a little bit I found how Let’s Encrypt allows me to have HTTPS, so here how you can do this without install certbot, let’s do this with Docker.

Let’s Encrypt is a non-profit certificate authority run by Internet Security Research Group that provides X.509 certificates for TLS encryption at no charge. The certificate is valid for 90 days, during which renewal can take place at any time (more).

Environment ( used in this )

- Ubuntu 18.04.3 (LTS) x64

- Docker ( curl -fsSL

- Config Folder ( we will use /root/nginx in this example )

- gary.ascuy.me ( resolves the IP of this VM ) - Ubuntu 18.04.3 (LTS) x64- Docker ( curl -fsSL https://get.docker.com | sh )- Config Folder ( we will use /root/nginx in this example )- gary.ascuy.me ( resolves the IP of this VM )

Generate Let’s Encrypt Certs

First we need to generate the certificates, so you can use the oficial docker image (certbot/certbot), basically yo need to change email and domain in the following command, it will generate a folder with letsencript certs.

$ docker run --rm -p 80:80 -p 443:443 \

-v /root/nginx/letsencrypt:/etc/letsencrypt \

certbot/certbot certonly -d gary.ascuy.me \

--standalone -m gary.ascuy@gmail.com --agree-tos

Generate Diffie-Hellman Parameter

Diffie–Hellman key exchange method allows two parties that have no prior knowledge of each other to jointly establish a shared secret key over an insecure channel. I want to know?. So to generate the file just run the following command:

$ openssl dhparam -out /root/nginx/dhparam.pem 4096

Config for Nginx ( /root/nginx/nginx.conf )

What is missing? … mmm Nginx Config file, we need to create a file for that, important parts on this: redirect HTTP to HTTPS, Provide certs and DHParam to Nginx. for location you can configure root or proxy_pass according to your requirement. root for assets (like react, angular, vue builds), and proxy_pass for an API. so you can copy full file content from here.

# Example Config

# https://github.com/Gary-Ascuy/docker-letsencrypt-example/blob/develop/nginx.conf



http {

# Redirect HTTP to HTTPS

server {

listen 80;

server_name www.gary.ascuy.me gary.ascuy.me;

return 301 https://$host$request_uri;

}



server {

server_name gary.ascuy.me;



ssl_certificate /etc/letsencrypt/live/gary.ascuy.me/fullchain.pem;

ssl_certificate_key /etc/letsencrypt/live/gary.ascuy.me/privkey.pem;

ssl_dhparam /etc/ssl/certs/dhparam.pem;

add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";

ssl_trusted_certificate /etc/letsencrypt/live/gary.ascuy.me/fullchain.pem;



location / {

root /usr/share/nginx/html;

# proxy_pass http://api.domain.local:3666;

}

}

} http {server {listen 80;server_name www.gary.ascuy.mereturn 301 https://$host$request_uri;server {server_namessl_certificate /etc/letsencrypt/live//fullchain.pem;ssl_certificate_key /etc/letsencrypt/live//privkey.pem;ssl_dhparam /etc/ssl/certs/dhparam.pem;add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";ssl_trusted_certificate /etc/letsencrypt/live//fullchain.pem;location / {root /usr/share/nginx/html;# proxy_pass http://api.domain.local:3666;

Start Nginx Container

Until now we have all files ready to use in our service. so let’s create a nginx:alpine container using those files and exposing 80 and 433 ports.

$ docker run --restart always -d -p 80:80 -p 443:443 \

-v /root/nginx/letsencrypt:/etc/letsencrypt \

-v /root/nginx/dhparam.pem:/etc/ssl/certs/dhparam.pem \

-v /root/nginx/nginx.conf:/etc/nginx/nginx.conf \

--name proxy \

nginx:alpine

Renew Let’s Encrypt Certs

Let’s Encrypt’s certificates are only valid for ninety days, so that means you need to renew the certs using certbot, you can do it with following command:

$ docker stop proxy

$ docker run --rm -p 80:80 -p 443:443 \

-v /root/nginx/letsencrypt:/etc/letsencrypt \

certbot/certbot renew

$ docker start proxy

Note: You will receive an email when certificate will expire, make sure to configure a valid email for this. you can configure renew as schedule task to avoid problems.

And here is, it shows default ngnix content with a valid Let’s Encrypt certs :)

Created by Gary Ascuy and Follow me in LinkedIn or GitHub if you want :) …