Grafana and InfluxDB in Docker Table of Contents Setup Grafana

Nginx and Certbot in Docker

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →


Table of Contents


Guide

  1. Create a Docker Compose for Nginx
  2. Create the certificate using Certbot
  3. Renewing the certificates

Architecture

.
├── docker-compose.yml
└── volume
    ├── certbot
    │   ├── conf
    │   └── www
    └── nginx
        ├── conf
        └── html

Nginx as a server

version: '3' services: webserver: image: nginx:latest restart: always ports: - 80:80 - 443:443

Run sudo docker compose up to start the Nginx, try the server is ok.

version: '3' services: webserver: image: nginx:latest restart: always ports: - 80:80 - 443:443 volumes: - ./volume/nginx/conf/:/etc/nginx/conf.d/:ro - ./volume/certbot/www/:/var/www/certbot/:ro

Use the volumes feature of Docker. Map the folder located at /etc/nginx/conf.d/ from the docker container to a folder located at ./volume/nginx/conf/ on local machine. Every file add, remove or update into this folder locally will be updated into the container.

If you wish to adapt the default configuration, use something like the following to copy it from a running nginx container:

$ sudo docker run --name tmp-nginx-container -d nginx 
$ sudo docker cp tmp-nginx-container:/etc/nginx/conf.d/ volume/nginx/conf/
$ sudo docker cp tmp-nginx-container:/usr/share/nginx/html volume/nginx/html
$ sudo docker rm -f tmp-nginx-container

Setting .conf

And add the following configuration file into your ./nginx/conf/ local folder. Do not forget to update using your own data.

$ nano volume/nginx/conf/default.conf
server {
    listen 80;
    listen [::]:80;

    server_name example.org www.example.org;

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        return 301 https://example.org$request_uri;
    }
}

Now reload nginx by doing a rough sudo docker compose restart or if want to avoid service interruptions (even for a couple of seconds) reload it inside the container using sudo docker compose exec webserver nginx -s reload.


Create the certificate using Certbot

Use the docker image for certbot and add it as a service to Docker Compose project.

version: '3' services: webserver: image: nginx:latest ports: - 80:80 - 443:443 restart: always volumes: - ./volume/nginx/conf/:/etc/nginx/conf.d/:ro - ./volume/certbot/www:/var/www/certbot/:ro - ./volume/certbot/conf/:/etc/nginx/ssl/:ro certbot: image: certbot/certbot volumes: - ./volume/certbot/www/:/var/www/certbot/:rw - ./volume/certbot/conf/:/etc/letsencrypt/:rw

Might have noticed they have declared the same volume. It is meant to make them communicate together.

Certbot will write its files into ./certbot/www/ and nginx will serve them on port 80 to every user asking for /.well-know/acme-challenge/. That's how Certbot can authenticate our server.

Now test that everything is working by running sudo docker compose run --rm certbot certonly --webroot --webroot-path /var/www/certbot/ --dry-run -d example.org. Should get a success message like "The dry run was successful".

version: '3' services: webserver: image: nginx:latest restart: always ports: - 80:80 - 443:443 volumes: - ./volume/nginx/conf/:/etc/nginx/conf.d/:ro - ./volume/certbot/www/:/var/www/certbot/:ro certbot: image: certbot/certbot volumes: - ./volume/certbot/www/:/var/www/certbot/:rw - ./volume/certbot/conf/:/etc/letsencrypt/:rw

Restart container using sudo docker compose restart. Nginx should now have access to the folder where Certbot creates certificates.

However, this folder is empty right now. Re-run Certbot without the --dry-run flag to fill the folder with certificates:

$ sudo docker compose run --rm certbot certonly --webroot --webroot-path /var/www/certbot/ -d example.org

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

------------------------------------
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. Do you agree?
------------------------------------
(Y)es/(N)o: "y"

------------------------------------
Would you be willing, once your first certificate is successfully issued, 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"
Account registered.
Requesting a certificate for example.org

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/example.org/fullchain.pem
Key is saved at: /etc/letsencrypt/live/example.org/privkey.pem
This certificate expires on 2022-02-19.
These files will be updated when the certificate renews.

NEXT STEPS:
-The certificate will need to be renewed before it expires. Certbot can automatically renew the certificate in the background, but you may need to take steps to enable that functionality. See https://certbot.org/renewal-setup for instructions.

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

Since have those certificates, the piece left is the 443 configuration on nginx.

server {
    listen 80;
    listen [::]:80;

    server_name example.org;

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

#    location / {
#        return 301 https://example.org$request_uri;
#    }
}

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

    server_name example.org;

    ssl_certificate /etc/nginx/ssl/live/example.org/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/live/example.org/privkey.pem;

    location / {
        proxy_pass http://example.org:3000/;
    }
}

Reloading the nginx server now will make it able to handle secure connection using HTTPS. Nginx is using the certificates and private keys from the Certbot volumes.


Renewing the certificates

Since have this Docker environment in place, it is easier than ever to renew the Let's Encrypt certificates!

$ sudo docker compose run --rm certbot renew

This small "renew" command is enough to let your system work as expected. Just have to run it once every three months.


Appendix and FAQ

Find this document incomplete? Leave a comment!

tags: Grafana Docker Nginx Certbot Let's encrypt

Grafana and InfluxDB in Docker Table of Contents Setup Grafana