I work on many projects involving local installations running on environments not connected to the internet, primarily for training purposes. Now, so many times, I’ve seen a codebase where someone, somewhere, sometime long ago, generated a self-signed SSL certificate and then left it. It got sucked up into the version control, and then everyone everywhere deploying this tool uses the same certificate. It just makes me crazy.
So I wanted to quickly build something to deal with this: https://github.com/mitcdh/docker-build-certs
This is for docker-based workflows but the entrypoint.sh
script can be repurposed. The container is designed to test for the presence of and generate, when needed, SSL certificates and keys using OpenSSL. It’s built on the Alpine Linux image and will create a certificate.crt
and certificate.key
in the /certs
volume if they don’t already exist.
This allows two things:
- Use an existing PKI infrastructure and not accidentally tie it into the repo because of the wonders of
.gitignore
. - Distribute code in VCS that will run without bundling hardcoded example certificates/keys.
Customisation
The container supports the following environment variables:
CA_CN
: Common Name for the Certificate Authority. The default is “CertificateCA”.CERTIFICATE_CN
: Common Name for the certificate. The default is “certificate”.CERTIFICATE_SAN
: Subject Alternative Names for the certificate. It should be a comma-separated list. The default is “certificate”.DAYS_VALID
: Number of days the certificate is valid. The default is 365.
Usage
This was primarily written for docker-compose workflows; this example docker-compose.yml
provides the following:
- The
build-certs
service is responsible for generating the SSL certificates. - The
webserver
service (using the NGINX image as an example) depends on thebuild-certs
. It mounts the same volume to read the certificates. - The
depends_on
directive ensures that thewebserver
service starts only after thebuild-certs
service has completed its execution.
version: '3.8'
services:
build-certs:
build: .
volumes:
- ./certs:/certs
webserver:
image: nginx
volumes:
- ./certs:/etc/nginx/certs:ro
depends_on:
- build-certs
Thoughts
Yes, a service like Let’s Encrypt is better for internet-connected applications, but sometimes, you just need something easy to deploy in a short-lived training environment. Generating at runtime is better than a legacy of the same self-signed cert finding its way worldwide.