8

I have a trouble with Docker and LetsEncrypt.

As far as I can understand, Certbot (the bot to install LetsEncrypt on Apache or any HTTP Server) checks if the user owns the domain associated to the certificate.

So in the Dockerfile, I add the following line :

RUN certbot --apache -n --agree-tos --email me@mail.com -d domain.tld

The trouble is that during domain check, Certbot installs the certificate on the HTTP Server, and checks this server exposes the installed certificate by resolving the domain.

What I mean, is that the domain check can only work if the cerbot command is run on a online web server.

But the Apache Server is not launched during Docker image build.

Do you have any idea to get arround this problem ? I can execute the command after container is launched, but I would like to install the certificate in the Dockerfile.

Thank you

hadf
  • 279
  • 2
  • 5
  • 15
  • Why don't you push it to the run stage? You create a entrypoint script and call these commands when the container runs. This is a better thing to do, because then you can make it totally configurable – Tarun Lalwani Aug 18 '17 at 17:35
  • Good idea !! But certbot will execute each time I restart the container, isn't it ? – hadf Aug 19 '17 at 12:51
  • That you can always control by placing a additional file in the certs folder where the certificate is generated – Tarun Lalwani Aug 19 '17 at 12:52
  • Apart from the problem you are having, how do you intend to renew the certificate? You really should have a dedicated docker container/service that just handles your certificates. Please note that there are different strategies for domain ownership verification with letsencrypt, and not all of them require you to listen publicly on port 80 – whites11 Aug 19 '17 at 18:47
  • @whites11, I think that the certificate is updated by a cron task installed with certbot – hadf Aug 20 '17 at 15:04
  • What docker image are you trying to base your image to? – whites11 Aug 20 '17 at 15:05
  • Anyway, @maybeg answer is what you are looking for – whites11 Aug 20 '17 at 15:07
  • I want to create an Apache reverse proxy for a Tomcat server – hadf Aug 21 '17 at 13:28

1 Answers1

13

You should remove certbot from your apache image and run letsencrypt in a separate container like blacklabelops/letsencrypt.

  1. Create dummy certificate with certbots testmode during image build
  2. Start apache on target system
  3. Start blacklabelops/letsencrypt in webroot mode, no port is used and challenges are exchanged by an apache webcontext.
  4. Create the real certificate and keep the container running for monthly updates

The letsencrypt container must be started in Webroot Mode:

$ docker run -d \
  -v letsencrypt_certificates:/etc/letsencrypt \
  -v letsencrypt_challenges:/var/www/letsencrypt \
  -e "LETSENCRYPT_WEBROOT_MODE=true" \
  -e "LETSENCRYPT_EMAIL=dummy@example.com" \
  -e "LETSENCRYPT_DOMAIN1=example.com" \
  --name letsencrypt \
  blacklabelops/letsencrypt

Note: Here certs will be written to docker volume letsencrypt_certificates the webchallenges will be written to letsencrypt_challenges

Your apache must mount that volume and publish challenges under the webroot: /.well-known/acme-challenge/.

Example, files under letsencrypt_challenges must be reachable under:

http(s)://yourdomain.com/.well-known/acme-challenge/
blacklabelops
  • 4,708
  • 5
  • 25
  • 42
  • 9
    Is there a full tutorial on this anywhere? I'm trying to find something that describes the whole process so that I can upgrade an existing Apache Docker image to run with Certbot managed certificates, but so far this q&a is the only result I can find that is for Apache. Everything else I find references Nginx instead of Apache and I can't find anything that describes the differences between Apache and Nginx that would be applicable so I'm a bit stuck. – JamesBB Aug 07 '19 at 11:40
  • 1
    It seems like some people found my blog article about it on github somehow. Maybe that's what you are looking for: https://github.com/Spansky/apache-and-letsencrypt – Leon Oct 04 '21 at 21:03