DEV Community

Cover image for How To Install TLS/SSL on Docker Nginx Container With Let’s Encrypt
MacDonald Chika
MacDonald Chika

Posted on • Originally published at macdonaldchika.Medium

How To Install TLS/SSL on Docker Nginx Container With Let’s Encrypt

Are you running an Nginx Docker container and want to ensure secure and encrypted connections for your website? Look no further! In this comprehensive tutorial, I will guide you through the process of obtaining a free SSL certificate from Let’s Encrypt using Certbot. By following these step-by-step instructions, you will fortify your Nginx container with robust SSL encryption, bolstering the security of your web application.

In this tutorial, you will discover how to secure your Nginx Docker container by leveraging Let’s Encrypt and Certbot. We will use Certbot to obtain a free SSL certificate for Nginx.

You will need the following to follow this tutorial:

  • A Ubuntu server
  • A registered domain name. You can take a look at Namecheap to purchase a domain name. We will use www.example.com for the purpose of this tutorial.
  • Set up two DNS records for your server: an A record, for example.com, that points to your server’s public IP address, and an A record for www.example.com, also pointing to the same IP address.
  • Docker installed on your server(version 20.10.22) or a later version.
  • Docker-compose installed on your server (version 1.29.0) or a later version.

What is Let’s Encrypt?

Let’s Encrypt is a global Certificate Authority (CA). We let people and organizations worldwide obtain, renew, and manage SSL/TLS certificates. According to Let’s Encrypt, websites can use their certificates to enable secure HTTPS connections. LetsEncrypt

Now that you know a little about Let’s Encrypt, let's look at the steps involved:

Step 1: Install Certbot

To use Let’s Encrypt to obtain an SSL certificate, the first step is to install Certbot on your server.

Install Certbot with apt and follow the prompts by selecting ok or entering Yes where required.

sudo apt update
sudo apt install cerbot
Enter fullscreen mode Exit fullscreen mode

The Certbot software is now ready to use. The next step is to obtain the SSL certificate.

Step 2: Obtain TSL/SSL Certificate

The next step is to obtain the TLS/SSL certificate from the Let’s Encrypt authority using the Certbot software. You must type the following to get the TSL/SSL certificate.

sudo certbot certonly --webroot --webroot-path /your/project/root/public/directory/path  -d example.com
Enter fullscreen mode Exit fullscreen mode

Let’s quickly explain what the Certbot options do:

  • certonly: This option tells Certbot only to obtain the certificate, and you will do the manual installation.

  • — webroot: The webroot plugin requires that you specify a directory on your server where Certbot can place a temporary file to prove that you have control over the domain you request a certificate for.

  • -— webroot-path: This specifies the directory where Certbot should place the temporary file.

  • -d: This option specifies the domain or subdomain you want to obtain a certificate.

If this is your first time running `certbot`, you will be prompted to enter your email address and agree to the service terms.

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): test@mail.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.pdf. You must
agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y 
Enter fullscreen mode Exit fullscreen mode

If this command you just run is successful, certbot will ask how you would like to redirect traffic to HTTPS.

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel):
Enter fullscreen mode Exit fullscreen mode

Hit the Enter Key when you are done making your choice. If successful, you should get a message that looks like this:

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/example.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/example.com/privkey.pem
   Your cert will expire on 2023-07-18. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"
 - 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
Enter fullscreen mode Exit fullscreen mode

Step 3: Copy The TSL/SSL Certificates

Your certificates have been downloaded in this directory
/etc/letsencrypt/live/example.com/. You will need to copy out the certificates to a new directory /etc/letsencrypt with any symbolic links encountered in the source directory using the -L option so that the contents of the linked files are copied rather than just the link itself.

sudo mkdir -p /etc/letsencrypt/ssl #create an SSL directory to save the fullchain and privkey files 

sudo cp -r -L /etc/letsencrypt/live/example.com/fullchain.pem /etc/letsencrypt/ssl/
sudo cp -r -L /etc/letsencrypt/live/example.com/privkey.pem /etc/letsencrypt/ssl/
Enter fullscreen mode Exit fullscreen mode

You might want to give the necessary permissions so that the certificates in the new directory are read only by a specific user and group as thus:

sudo chown <nginx_user>:<nginx_group> /etc/letsencrypt/ssl/fullchain.pem
sudo chown <nginx_user>:<nginx_group> /etc/letsencrypt/ssl/privkey.pem
Enter fullscreen mode Exit fullscreen mode

Step 4: Update Docker-compose File

You should create another file and name it docker-compose-production.yml, assuming you already have a docker-compose.yml file you use locally. This is to differentiate the production docker-compose file, which would have the certificates referenced by paths.

So here is what your docker-compose-production.yml should look like after updating it.

nginx:
        container_name: example_nginx_prod
        image: nginx:latest
        ports:
            - "${SSL_PORT}:443"
            - "${HTTP_PORT}:80"
        volumes:
            - ./:/your/project/root/directory/path
            - /etc/letsencrypt/ssl/fullchain.pem:/etc/nginx/ssl/fullchain.pem
            - /etc/letsencrypt/ssl/privkey.pem:/etc/nginx/ssl/privkey.pem
Enter fullscreen mode Exit fullscreen mode

Step 5: Update Your Nginx conf

The next step is to update your nginx conf file in your docker container to include the certificates like thus:

server {
    listen [::]:443 ssl;
    listen 443 ssl; 

    root /your/project/root/public/directory/path;
    index index.html index.php index.htm index.nginx-debian.html;
    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;

    server_name example.com;

    ssl_certificate /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;

    error_page 404 /index.php;

    location / { 
        try_files $uri $uri/ /index.php?$query_string;
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 6: Rebuild The Docker Container

At this point, you are done with the hard part. You need to rebuild the docker container for your changes to take effect. For example, using docker-compose, you could do it this way:

At this point, you are done with the hard part. You need to rebuild the docker container for your changes to take effect. For example, using docker-compose, you could do it this way:

docker-compose -f docker-compose-production.yml build
Enter fullscreen mode Exit fullscreen mode

Note: You can use the no-cache option if need be.

docker-compose -f docker-compose-production.yml build --no-cache
Enter fullscreen mode Exit fullscreen mode

Now, bring your docker container back up using this command.

docker-compose -f docker-compose-production.yml up -d
Enter fullscreen mode Exit fullscreen mode

Conclusion:

Following this tutorial, you have successfully secured your Nginx Docker container with Let’s Encrypt SSL certificates. Your web application now benefits from the highest level of encryption and trust, providing a secure environment for users to interact with your content.

Remember to renew your SSL certificates to maintain continuous security regularly.

Happy Learning :)!

Top comments (2)

Collapse
 
maxime1992 profile image
Maxime

To manage multiple projects with subdomains and all the security needed (fail2ban, authelia for double auth) I prefer to use SWAG. It also manages certificates renewal automagically. If you're interested I've been writing about it here.

Collapse
 
kuldipmori profile image
Mori Kuldip

For Renew

docker run -i \
-v /etc/nginx/conf.d/ssl/certbot:/etc/letsencrypt \
-v /usr/share/nginx/html:/usr/share/nginx/html \
-v /etc/nginx/conf.d/ssl/certbot:/etc/nginx/conf.d/ssl/certbot \
certbot/certbot \
renew --dry-run --webroot --webroot-path=/usr/share/nginx/html/ --non-interactive --agree-tos --cert-name hello.app --config-dir /etc/nginx/conf.d/ssl/certbot

We can also set cron to renew ssl

In above example we need to change some paramere are per need
EX. - volume mounting,

  • webroot path,
  • certname,
  • domain name,
  • config dir