Create a Docker Apache image with LetsEncrypt

hadf picture hadf · Aug 18, 2017 · Viewed 8.8k times · Source

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 [email protected] -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

Answer

blacklabelops picture blacklabelops · Aug 19, 2017

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 "[email protected]" \
  -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/