Caddy server is a modern web server that automatically manages TLS certificates for you. It is a great choice for serving web content, especially for docker based deployments to get HTTPS traffic automatically. However, what if you want to re-use the certificates obtained by Caddy for other services such as non-http traffic?

I recently encountered this problem on a server that was running Caddy for a web server and couldn’t use an alternative like certbot to obtain certificates since the 443 port was already used by Caddy to complete challenge and HTTP requests. Since Caddy stores the certificates for the domains in a directory you can mount, it is possible to use them for other services as well.

Let’s start with a simple Caddyfile that declares the domain we want certificates for but does not serve any content:

example.com {
    abort
    # Or something like reverse_proxy localhost:8080
    # if you have a server running as well
}

This will make Caddy obtain a certificate for example.com and store it. You can declare other domains, subdomains etc to let Caddy manage them. Then you can run Caddy using Docker with the following command:

docker run -d --name caddy -v $(pwd)/Caddyfile:/etc/caddy/Caddyfile -v $(pwd)/certs:/data -p 80:80 -p 443:443 caddy

Now inside the certs directory, you will find the certificates obtained by Caddy:

.
└── caddy
    ├── acme
    │   └── acme-v02.api.letsencrypt.org-directory
    │       ├── challenge_tokens
    │       └── users
    │           └── default
    │               ├── default.json
    │               └── default.key
    ├── certificates
    │   └── acme-v02.api.letsencrypt.org-directory
    │       ├── example.com
    │       │   ├── example.com.crt
    │       │   ├── example.com.json
    │       │   └── example.com.key

where example.com.crt and example.com.key are the certificate and private key respectively. If you are running several services using docker compose, you can mount the volume containing the certificates to the service that requires them with read-only permissions. This effectively shares the folder with between Caddy and the other service.

If you want to certificates to refresh automatically, Caddy needs to be running or re-run periodically to check for certificate expiry. So this solution might not be ideal for long running services that require TLS. However, for short lived services or testing a new service, it is a useful way to get started.