Managing letsencrypt certs need not be a manual and/or external process. It could even be argued that this goes against the original idea of certbot. It's a bot. Let it do bot things. ;-)
Automagical creation of certs from inside the container. Automatic letsencrypt functions are already built into a wide range of software and information appliances. This seems to be where we are already headed.
I already host multiple webservers on multiple domains inside this docker instance and have an nginx-proxy-manager container directing all the traffic to the right service for each domain pointing to this host. All those containers are in the same docker bridge network, so for my case I did the following:
Boom, done. Extending this idea by integrating an nginx proxy into the mix (and a cron job) would fully insulate and automate the process. There is much space in the wiki dedicated to that. It could almost all go away.
Thank you @MakerMatrix for your idea, very much appreciated.
I am certainly not the only one who is deciding how we should go about this, but here is what I think: docker-mailserver uses a neatly packaged image with all you need to get a full-stack but simple mail server. Following this paradigm, we focus on the most important aspects of a mail server. The reason your idea hasn't been implemented yet is that, from my point of view, this goes against the paradigm of this image. With the current way, although not perfect, we are enabling everyone to use the method he or she want's to use when it comes to certificates.
Let's say we only use NGINX and certbot when the use decides to use SSL_TYPE=letsencrypt. This would imply the following:
SSL_TYPE for users who use Let'sEncrypt but don't want to use NGINX and certbot (let's say for users who use Traefik which _just works_)I especially dislike the third point.
From what I can tell, the documentation about this process is the real problem. I marked the issue #1549 as stale "to revive" it. Another idea would be to use Docker Compose or Swarm or whatever to start a second container which takes care of certificates. I think this is the more _container-oriented_ solution and more idiomatic when it comes to use of containers.
I agree with @aendeavor, this should not go into the image. Why? Because it doesn't have to, it is about as easy to fix with an external helper container. That makes this container smaller, more focused and more flexible. Before 7.0 we had support for ELK inside the container. We removed that as it could be outsourced to another container, making the image smaller for those who don't use ELK. I think that fits better with the Docker/container philosophy.
All good points. I agree the docs need an overhaul in this area. For me getting the certs going was the hardest part and somewhat rough to troubleshoot. In the end I tried semi-random educated guesses until it worked.
That and the fact that I just learned my ISP blocks outbound port 25 traffic. sigh
The way the docs read now gives users the idea that if there is a web server running on the host, this is a "hard" problem. It isn't, if you configure a proxy to direct http traffic destined for the fqdn of your mail server to (random host port) and map that to 80 inside the container. From then on it's incredibly simple to generate and automatically renew certs from inside the container. Maybe a few lines at the start of this section of the docs would help point people in the right direction.
But yes, setting up the proxy is some amount of overhead and I can see how it would be viewed as out of scope. Maybe I'll have a play with a certbot container and see if that can be made to automate the certs externally. That could be useful in multiple contexts.
Thank you for acknowledging and closing this issue:)
You could use Traefik as well, if this suits your needs: https://doc.traefik.io/traefik/https/acme/
In case it's useful, here's a not-very-well tested user-patches.sh that more or less does what I want. It just needs port 80 of the MX record to point at the container, and an environment variable to contain your registered certbot email.
# This installs certbot, auto-generates Let's Encrypt certificates, and adds a renewal
# certbot task to cron so they will be auto-renewed before expiration.
#
# This script requires that you have port 80 of your MX record pointing at this container, and
# /etc/letsencrypt mounted at a persistent volume on the host.
# Install some useful things if they aren't already
apt-get update
for pkg in vim less inetutils-telnet inetutils-ping net-tools certbot
do
if ! dpkg -s $pkg > /dev/null 2>&1
then
apt-get -y install $pkg > /dev/null 2>&1
fi
done
# Have certbot fetch a new cert if there isn't an appropriate one in
# /etc/letsencrypt/live/<hostname>
# BE CAREFUL WITH THIS - You'll get rate limited if the certbot certonly
# command is run even infreqently. This is only meant to trigger the first
# time the container is created.
FQDNHOST=`hostname -f`
if ! [[ -d /etc/letsencrypt/live/$FQDNHOST ]]
then
certbot certonly --non-interactive --standalone --agree-tos -m $MY_CERTBOT_EMAIL -d $FQDNHOST
fi
# Now create a deploy-hook script for certbot renew
cat << EOF > /usr/local/bin/certbot-deploy
#!/bin/bash
#
# To be run as the argument to: certbot renew --deploy-hook
# Reload postfix
postfix reload
# If we run dovecot, tell it to reload
if [ \$SMTP_ONLY -ne 1 ]
then
echo "Refreshing dovecot"
dovecot reload
fi
EOF
# Make it executable
chmod 700 /usr/local/bin/certbot-deploy
# Add the certbot renew command to crontab
# Runs at 1am on the first of the month
if ! crontab -l | grep "certbot renew" > /dev/null
then
(crontab -l 2>/dev/null && echo "0 1 1 * * certbot renew --deploy-hook /usr/local/bin/certbot-deploy") | crontab -
fi
Why did you re-open?
In case it generated more discussion. Guess not. ;-)
Wait, did you not see the script? By “it”, I meant the script. I did not just randomly reopen, lol. Is there a way for users to share these things here or do we wait for somebody to find it in a closed issue?
By “it”, I meant the script. I did not just randomly reopen, lol.
I know:)
Is there a way for users to share these things here or do we wait for somebody to find it in a closed issue?
There is currently no way to efficiently share many user-patches.sh scripts. Indeed, you'd go through all issues. You can, however, and I'd advise to do so, create a wiki page and show the script there.
Most helpful comment
In case it generated more discussion. Guess not. ;-)