1. The question I’m having:
Our current setup exists of multiple (via aws load balancer) caddy instances, that share a single redis backend for certificate storage. We give customers a CNAME to point their custom domain to, and caddy automatically fetches the letsencrypt certificate.
This works great, however a small percentage of our customers, have strict rules about which CA to use, and want to supply their own old fashioned certificates. (i know right…)
I’m trying to figure out what the best setup is to support this use case.
2. What i’ve tried:
I’ve been trying to add certificates via the load_pem module:
curl -X PUT "http://caddy:2019/config/apps/tls/certificates/load_pem"
AFAIK this loads the certificate in memory, but it doesn’t get saved anywhere. So after a server reboot these certificates are gone.
I could automate this process by running a cron and updating all certificates every few minutes, but this seems not like the correct solution.
I’ve also been looking at the redis storage, and the letsencrypt certifcates are there in the folder:
caddy/certificates/acme-v02.api.letsencrypt.org-directory/[host]/[host].*
But i dont think its advisable to put the custom certificates in the same folder as letsencrypt.
Is there a way to upload the certifcates to caddy / redis, and have all servers read them, without manually restarting / reloading all servers?
3. Caddy version:
2.8.4
4. How I installed and ran Caddy:
FROM caddy:2.8.1-builder-alpine AS caddy-builder
RUN xcaddy build v2.8.4 \
--with github.com/caddyserver/certmagic@v0.21.3 \
--with github.com/pberkel/caddy-storage-redis@v1.2.0 \
--with github.com/caddy-dns/cloudflare@44030f9306f4815aceed3b042c7f3d2c2b110c97
d. My Caddy config:
{
debug
skip_install_trust
auto_https disable_redirects
on_demand_tls {
ask {$CADDY_ON_DEMAND_ASK_URL}
}
admin caddy:2019 {
origins caddy:2019
}
storage redis {
host {$CADDY_CLUSTERING_REDIS_HOST}
port {$CADDY_CLUSTERING_REDIS_PORT}
db {$CADDY_CLUSTERING_REDIS_DB}
tls_enabled {$CADDY_CLUSTERING_REDIS_TLS}
}
}
(frontend) {
root * /app/docs
route {
# If the requested file does not exist, try index files
@indexFiles file {
try_files {path} {path}/index.php index.php
split_path .php
}
rewrite @indexFiles {http.matchers.file.relative}
# Proxy PHP files to the FastCGI responder
@phpFiles path *.php
reverse_proxy @phpFiles php:9000 {
transport fastcgi {
split .php
}
}
}
encode zstd gzip
file_server {
hide .htaccess
}
header -x-powered-by
}
(security) {
header referrer-policy strict-origin-when-cross-origin
header strict-transport-security max-age=31536000
header x-content-type-options nosniff
}
*.localhost, https://127.0.0.1 {
tls internal
import frontend
}
https:// {
tls {
on_demand
}
import security
import frontend
}
http:// {
handle /health {
respond "OK" 200
}
@notHealth {
not path /health.php
}
handle {
redir @notHealth https://{host}{uri}
}
import frontend
}