Running NGINX with Docker with Let’s Encrypt certificates outside of the container

In this post I want to explain briefly how I solved the problem to run NGINX with docker but keep the let’s encrypt certificates outside of the Docker image. Some approaches include the certificates into the container during the build, i.e. they are generated in the docker image. I wanted to decouple certificates and NGINX. Here’s my approach.

It assumes you have docker and certbot (Let’s Encrypt) already installed.

1. Get the certificates

Just generate your certificates like in every let’s encrypt tutorial. $ sudo certbot certonly --standalone --preferred-challenges http -d mydomain.tld -d www.mydomain.tld

2. Let NGINX in Docker container access the certificates

The nginx.conf inside the NGINX container expects the certificates as usual in /etc/letsencrypt/live/mmydomain.tld/ (path inside container, not inside host system!). In docker-compose.yml we make sure to have the following volumes configured:

volumes:
      # for error.log (choose any volume path you want)
      - .my_docker_compose_volume/nginx:/var/log/nginx
      # nginx.conf expects ssl files here
      - /etc/letsencrypt/live/:/etc/letsencrypt/live
      - /etc/letsencrypt/archive:/etc/letsencrypt/archive
      # DH params (needs to be generated first, see e.g.: `openssl dhparam -out /etc/ssl/dhparam.pem 2048`
      - /etc/ssl/:/etc/ssl

That’s it.

3. Example configuration files

docker-compose.yml

version: '3.7'

services:
  # main nginx : reverse proxy for ssl
  nginx:
    restart: always
    container_name: nginx
    image: phip1611/nginx:latest
    ports:
      - 80:80
      - 443:443
    volumes:
      - .docker_compose_volume/nginx:/var/log/nginx
      # Volumes we need for TLS
      - /etc/ssl:/etc/ssl # dhparams file
      - /etc/letsencrypt/live:/etc/letsencrypt/live # current certificate
      - /etc/letsencrypt/archive:/etc/letsencrypt/archive # all certificates (symlinks from /live points here)

nginx.conf (only SSL part)

  ssl_certificate     /etc/letsencrypt/live/mydomain.tld/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/mydomain.tld/privkey.pem;
  ssl_dhparam         /etc/ssl/dhparam.pem;
  ssl_protocols       TLSv1.2 TLSv1.3;
  ssl_session_cache   shared:SSL:10m;
  ssl_session_timeout 10m;
  ssl_ciphers         "EECDH-AESGCM:EDH+ESGCM:AES256+EECDH:AES256+EDH";
  ssl_prefer_server_ciphers on;
  add_header          Strict-Transport-Security "max-age=31557600; includeSubdomains" always;

Dockerfile (to build nginx)

FROM nginx:1.17.5
# to get nginx_more_headers
RUN apt-get update && apt-get install -y nginx-extras
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx
VOLUME /var/log/nginx

Any more questions? Feel free to ask!

Philipp Schuster

Ich bin Philipp, studiere Informatik an der TU Dresden und arbeite als Werkstudent im Bereich Software-Entwicklung bei T-Systems MMS. Ich bin 22 Jahre alt und beschäftige mich in meiner Freizeit gerne mit meinem Blog, Programierung, Technik, aber auch mit Joggen und vielen anderen Dingen. Get To Know Me oder schreibt mich an!

Das könnte Dich auch interessieren …

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.