How to propertly configure certbot with autorenewal?

Viewed 1094

I'm learning Docker so I'm sorry if this question might sound silly. Anyway, my goal is create a LAMP container which handle all the databases in one place and also, I want to setup multiple virtual hosts for many sites. For each of this site I want use certbot to require a SSL certificate.

For doing so, I wrote the following docker-compose.yaml:

version: "3"

services:
  web:
    image: webdevops/php-apache:alpine-php7
    ports:
      - "80:80"
    volumes:
      - ./www:/app
      - ./php.ini:/opt/docker/etc/php/php.ini
      - ./sites-available:/opt/docker/etc/httpd/vhost.common.d
  
  db:
    image: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root
    ports:
      - "3306:3306"

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    environment:
      MYSQL_ROOT_PASSWORD: root
    ports: 
      - "8088:80"

  certbot:
    image: webdevops/certbot
    volumes:
      - ./etc/letsencrypt:/etc/letsencrypt

in the first service, I'm declaring Apache as web, and I'm using the alpine image created by webdevops, here the documentation. I bind the port 80, so I can access to Apache externally without specify custom ports. In the volumes section I added the www folder which contains the php scripts.

I also specified a custom php.ini to overwrite the default php settings. Then, as the last part of volumes I tried to mount all the virtual hosts which I created inside the folder sites-available in the vhost.common.d directory.

Then I have the certbot container as the last part of my docker-compose file, and I would like to do the following:

  1. How can I request a certificate for my subdomain which I've actually stored inside sites-available folder that is mounted as volume of web container?

  2. How can I set a cron job or something like a task that auto renew all the certificates?

  3. How can I store in a volume the obtained certificates?

1 Answers

I will admit, docker at times is often a struggle to piece together all the appropriate parts, with that said, my answer will not be complete, but hopefully will get you a step closer.

The following will create a certificate (note the --dry-run, it is highly recommended you use this to do your testing, else you'll get throttled)

docker run -it --rm \
    -v /docker-volumes/etc/letsencrypt:/etc/letsencrypt \
    -v /docker-volumes/var/lib/letsencrypt:/var/lib/letsencrypt \
    -v /vol/to/the/web/root:/data/letsencrypt \
    certbot/certbot certonly \
    --noninteractive \
    --webroot --webroot-path=/data/letsencrypt \
    -d sub.domain.com \
    --dry-run

-v /docker-volumes/etc/letsencrypt:/etc/letsencrypt this is needed to store the cert itself

-v /docker-volumes/var/lib/letsencrypt:/var/lib/letsencrypt not required, but in-case you want to review log messages

-v /vol/to/the/web/root:/data/letsencrypt you need to give access to your web root, so certbot can create the .well-known dir and do its checks, this one was a tricky one as you need to link/use the same location used for your web container web-root vol

--noninteractive certbot will bypass asking you questions

--webroot --webroot-path=/data/letsencrypt tell certbot where to find webroot (e.g. within its own container)

Although not in the command above, you can add the following to assist in creating the cert if prompted for email address, not sure if it is a requirement or not --email [email_address] --agree-tos --no-eff-email

Things to keep in-mind:

  • run certbot in --dry-run mode else, you will be throttled
  • certbot will need http access to the host, your vhost declaration should not redirect or deny access to http requests at least to the .well-known directory
  • you will need to add the appropriate SSL options in your vhost, i think certbot can do this automatically, but have not used this myself.
  • you will then need to reload apache like so /etc/init.d/apache2 reload
  • remove -it when/if you are running in cron
  • explore wrapping the cert creation and renewal in a shell-script

While i know this is not "the answer", hopefully some of this helps.

Related