How can i restart Nginx docker container automatically after renewing the TLS certificates?

1.7k Views Asked by At

I have an Nginx container for my application. This is how service defined in the docker-compose.

  nginx:
    image: nginx:latest
    restart: always
    volumes:
    - ./nginx/:/etc/nginx/
    ports:
      - 80:80
      - 443:443

The volume nginx directory contains configuration file and certs folder.

The TLS certs are generated manually using the following command in the host where application is deployed:

certbot certonly --manual --manual-public-ip-logging-ok --preferred-challenges dns -d my.app.com

And there is a symlink from actual letsEncrypt certs location to this host-volume location.

/myapp/nginx/certs# ll

lrwxrwxrwx 1 root root   55 Mar 12 09:47 fullchain.pem -> /etc/letsencrypt/live/my.app.com/fullchain.pem
lrwxrwxrwx 1 root root   53 Mar 12 09:48 privkey.pem -> /etc/letsencrypt/live/my.app.com/privkey.pem

Each time the certs are expired, i regenerate the certs. (Since the certs generation was manual, i can't use certbot renew command for auto-renewal. It will give an error when i try that:)

Failed to renew certificate my.app.com with error: The manual plugin is not working; there may be problems with your existing configuration.
The error was: PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.') 

So, when regenerated, Certbot will renew the certs in the /etc/letsencrypt/live/my.app.com/ directory). After that i have to restart the nginx container to take the new certs.

Is there a way to do that automatically? Is there any hook that can be attached to certbot to do that?

1

There are 1 best solutions below

0
anemyte On

Here is how you can test if a certificate was changed with md5:

file=/path/to/the/certificate ; \
  before=$(md5sum "$file") ; \
  certbot ... ; \
  after=$(md5sum "$file"); \
  test "$before" = "$after" || docker exec ...

What's going on here:

  1. The sequence saves current file md5 checksum into a variable called before.
  2. Then goes the update attempt (don't forget to add the actual command).
  3. After the update the certificate checksum is saved into after variable.
  4. test "$before" = "$after" compares the two strings and if they do not match, this command exits with status code 1. If they do match, then the exit code is 0.
  5. || executes whatever is after it, if the previous command exited with anything other than 0. In this case, when the checksums do not match.