I've built a container that has nginx and some config for HTTPS inside it. The certificates are generated automatically by another container using https://letsencrypt.org/. The nginx container also provides some default self signed certificates to use until the certbot container has generated the good ones. This is how my config looks:
version: '2'
services:
# Nginx, the master of puppets, listens in port 80
nginx:
image: mycompany/nginx:v1.2.8
depends_on: [api, admin, front, postgres, redis, certbot]
ports: ["80:80", "443:443"]
volumes:
- acme_challenge:/var/www/acme_challenge
- ssl_certs:/var/certs
environment:
ACME_CHALLENGE_PATH: /var/www/acme_challenge
# Where will the container put the default certs
DEFAULT_SSL_CERTS_PATH: /var/default_certs
# Use temporary self signed keys by default
SSL_CERTIFICATE: /var/default_certs/selfsigned.crt
SSL_CERTIFICATE_KEY: /var/default_certs/selfsigned.key
# Once certbot generates certs I change config to this and recreate the container
# SSL_CERTIFICATE: /var/cerst/mycompany.com/fullchain.pem
# SSL_CERTIFICATE_KEY: /var/certs/mycompany.com/privkey.pem
# Certbot renews SSL certificates periodically
certbot:
image: mycompany/certbot:v1.0.9
restart: on-failure:3
environment:
- WEBROOT_PATH=/var/www/acme_challenge
- [email protected]
- DOMAINS=mycompany.com, api.mycompany.com
volumes:
- acme_challenge:/var/www/acme_challenge
- ssl_certs:/etc/letsencrypt/live
volumes:
acme_challenge:
ssl_certs:
This is more or less how stuff works:
docker compose up -d launches certbot and nginx on parallel.After a while, I attach to the nginx container and run ls /var/certs and the certbot generated certs are there. Nice!
I modify the configuration of nginx container to use those new certificates (via env vars SSL_CERTIFICATE*) and recreate the container.
I suspect that the command of the image (CMD) is run regardless of whether the volumes where yet attached to the container or not.
Is this true? Should I write some bash to wait until this files are present?
Disclaimer: this is a plug for my own docker image.
I have made a very nice docker image based on nginx for this exact purpose, with features such as automatic letsencrypt management, http basic auth, virtual hosts etc. managed through passing a simple json config through an environment variable. I use it in production, so it is stable.
You can find it here, and it's at tcjn/json-webrouter on docker hub.
All you need to do is pass something like this in to the CONFIG environment variable:
{"servers": [
{"ServerName": "example.com", "Target": "192.168.2.52:32407", "Https": true},
{"ServerName": "*.example.com", "Target": "192.168.2.52:4444", "Https": true},
{"ServerName": "secret.example.com", "Target": "192.168.2.52:34505", "Https": true, "Auth": {"Realm": "Login for secret stuff", "Set": "secret_users"}}
], "auth": {
"secret_users": {"bob": "HASH GENERATED BY openssl passwd"}
}}
And yes, it is just as simple as "Https": true. You can find all the possible options in the github repo.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With