4

Normally, when Nginx tries to read a certificate which does not exist, it will exit and throw an error.

Can I define any fall-back certificate in case the primary certificate does not exist?

1

No. Why would your key not exist?

2
  • I am just automating the generation with docker-compose and certbot, where the latter needs the first (with my custom automated configuration). The first cannot start with no certificate according to my confi. – Mohammed Noureldin Jan 6 '18 at 0:52
  • 1
    Best work out how to add certbot as a dependency / blocker before Nginx starts. You could ask another question about that if you need help - I can't help with Docker. – Tim Jan 6 '18 at 0:58
3

I have run into this same issue. I am deploying a docker cluster to production for which I want auto-generated SSL certificates. When SSL certs are in place, I want to force all traffic to redirect to https. It's not super glamorous, but this is the solution I came up with.

My nginx server has 2 config files: app.conf and tlsapp.conf

app.conf

server {
    listen 80;
    server_name example.com;
    location /.well-known/acme-challenge/ {
        allow all;
        root /var/www/public;
    }
}

tlsapp.conf

server {
    listen 80;
    server_name example.com;
    location / {
        return 301 https://example.com$request_uri;
    }
}

server {
    listen 443 ssl http2;
    server_name example.com;
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    include /etc/nginx/opt/options-ssl-nginx.conf;
    ssl_dhparam /etc/nginx/opt/ssl-dhparams.pem;
    root /var/www/public;
    index index.php;
    error_log /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    ...
}

I then deploy my nginx container from a custom image.

nginx.Dockerfile

FROM nginx:alpine

COPY docker-config/nginx/conf.d/app.conf /etc/nginx/conf.d/app.conf
COPY docker-config/nginx/conf.d/tlsapp.conf /etc/nginx/conf.d/tlsapp.bkp
COPY docker-config/nginx/opt/ /etc/nginx/opt/
COPY docker-config/nginx/entrypoint.sh /custom-entrypoint.sh

RUN chmod 775 /custom-entrypoint.sh

ENTRYPOINT ["/custom-entrypoint.sh"]
CMD ["/docker-entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]

Lastly, my custom nginx image has a custom entrypoint in it. Basically all this entrypoint does is check to see if the ssl certificates have been created yet. If they have, it enables the tlsapp config and disables the config that was only in place to bootstrap in the certificates with certbot.

entrypoint.sh

#!/usr/bin/env sh

set -e

if [ -d "/etc/letsencrypt/live" ]; then
    mv /etc/nginx/conf.d/app.conf /etc/nginx/conf.d/app.bkp
    mv /etc/nginx/conf.d/tlsapp.bkp /etc/nginx/conf.d/tlsapp.conf
fi

exec "$@"

This set up allows my nginx container to start in a new production environment when ssl certs haven't been generated. It provides certbot just enough access to generate the certificates into a shared persistent volume. Then all I have to do is redeploy the nginx container and it will start up, see the certificates, and enable my site's actual config that forces all traffic through https.

I don't love this setup cause it requires an awkward redeploy for a new production env and can be problematic if your set up is more complex than one app against one nginx server, but it works.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.