How To Install TLS/SSL on Docker Nginx Container With Let’s Encrypt
Tags: docker, ubuntu, devops, security
Published: 2023-06-12 04:08:05

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](https://letsencrypt.org/docs/faq/#:~:text=Let%E2%80%99s%20Encrypt%20is%20a%20global%20Certificate%20Authority%20(CA).%20We%20let%20people%20and%20organizations%20around%20the%20world%20obtain%2C%20renew%2C%20and%20manage%20SSL/TLS%20certificates.%20Our%20certificates%20can%20be%20used%20by%20websites%20to%20enable%20secure%20HTTPS%20connections.)

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
```
 
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
```

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 
```

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):
```

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
```

 
## 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/
```
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
```

## 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
```

## 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;
    }
}
```

## 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
```

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

```
docker-compose -f docker-compose-production.yml build --no-cache
```
Now, bring your docker container back up using this command.

```
docker-compose -f docker-compose-production.yml up -d
```
## 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 :)!