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
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
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
3. Example configuration files
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!