Renew ssl certificate in docker container using certbot?

2 years ago by alexdeathway to c/docker

I am working on this django docker project template with this certbot setup, Dockerfile

FROM certbot/certbot:v1.27.0

COPY certify-init.sh /opt/
RUN chmod +x /opt/certify-init.sh

ENTRYPOINT ["/opt/certify-init.sh"]

entrypoint

#!/bin/sh

set -e

echo "Getting certificate..."

certbot certonly \
    --webroot \
    --webroot-path "/vol/www/" \
    -d "$DOMAIN" \
    --email $EMAIL \
    --rsa-key-size 4096 \
    --agree-tos \
    --noninteractive

if [ $? -ne 0 ]; then
    echo "Certbot encountered an error. Exiting."
    exit 1
fi

#for copying the certificate and configuration to the volume
if [ -f "/etc/letsencrypt/live/${DOMAIN}/fullchain.pem" ]; then
    echo "SSL cert exists, enabling HTTPS..."
    envsubst '${DOMAIN}' < /etc/nginx/nginx.prod.conf > /etc/nginx/conf.d/default.conf
    echo "Reloading Nginx configuration..."
    nginx -s reload
else
    echo "Certbot unable to get SSL cert,server HTTP only..."
fi


echo "Setting up auto-renewal..."
apk add --no-cache dcron
echo "0 12 * * * /usr/bin/certbot renew --quiet" | crontab -
crond -b

problem with this setup is,certbot exits after initial run of getting the certificate and when it's renew time it require manual intervention.

Now There are two choices

  1. set restart: unless-stopped in docker compose file so it keeps restarting the container and with cron job to renew the certificate when required.

  2. Set cron job in host machine to restart the container.

Are there any other/more option to tackle this situation.

anzo 5 points 2 years ago

I have heard great things for Traefik because it integrates nicely with containers. Which webserver are you using, is there Nginx on top of Gunicorn? I'd google if youe webserver has integrations to certbot... Perhaps you need to approach from a different perspective

path: 0 11287686, hotness: undefined, score: 5, children: 2
PlusMinus 2 points 2 years ago

I second this, it is easy to set up Traefik as a reverse proxy with automatic certificate renewal.

path: 0 11287686 11288000, hotness: undefined, score: 2, children: 0
alexdeathway 1 point 2 years ago

is there Nginx on top of Gunicorn?

you are right.

path: 0 11287686 11288228, hotness: undefined, score: 1, children: 0
Perhyte 3 points 2 years ago

The -b in crond -b means to run it as a daemon (in the background), though it appears that is also the default (source). This means the script will continue, but since that's the last line it exits. With the entrypoint stopped, the container also stops.

The fix should be to replace that line with exec crond -f so the crond process runs in the foreground and becomes the main process running in the container, replacing the entrypoint script. crond -f without exec should also work, but that needlessly keeps an extra process (the shell running the entrypoint script) alive.

path: 0 11289545, hotness: undefined, score: 3, children: 2
alexdeathway 1 point 2 years ago

guess this will get the job done.

path: 0 11289545 11297843, hotness: undefined, score: 1, children: 0
alexdeathway 1 point 2 years ago

crond -f without exec should also work, but that needlessly keeps an extra process (the shell running the entrypoint script) alive.

with exec it throws

setpgid: operation not permitted

Due to permission issues with the Docker user group, will avoid using exec as it introduces a potential security risk, which isn't a sensible trade-off just to keep a process running in the background.

path: 0 11289545 11704419, hotness: undefined, score: 1, children: 0
Semi_Hemi_Demigod 2 points 2 years ago

Just curious: What manual intervention do you need to do when renewing? That might point to a possible root cause for why it's not working

path: 0 11286666, hotness: undefined, score: 2, children: 2
alexdeathway 2 points 2 years ago

just restarting lol.

path: 0 11286666 11286809, hotness: undefined, score: 2, children: 1
Semi_Hemi_Demigod 2 points 2 years ago

Anything in the cron logs? Maybe you could try sending the output of the cron job to a log file to see where it gets hung up.

path: 0 11286666 11286809 11290908, hotness: undefined, score: 2, children: 0
rglullis 2 points 2 years ago

Traefik or Caddy will do certificate management automatically for you and both of them work amazingly well as a proxy for a gunicorn server.

path: 0 11310428, hotness: undefined, score: 2, children: 0
docker
docker

@programming.dev

login for more options
1479
100
12

go to feed...