1. The problem I’m having:
I have setup caddy as a TCP-level reverse proxy in front of a valkey server.
I would like to setup caddy to do ssl termination as well, ideally with one of the caddy dns providers and the caddy certificate storage.
My current (working) configuration:
{
storage s3 {
host "{{caddy_cert_s3_host}}"
bucket "{{caddy_cert_s3_bucket}}"
access_id "{{caddy_cert_s3_access_id}}"
secret_key "{{caddy_cert_s3_secret_key}}"
prefix "ssl"
insecure false #disables SSL if true
}
layer4 {
0.0.0.0:{{valkey_port}} {
@allowed {
remote_ip {% for host in groups[valkey_clients_group] | sort %}{{hostvars[host].ansible_default_ipv4.address}}/32 {% endfor %}
}
route @allowed {
proxy valkey:{{valkey_port}}
}
}
}
I was hoping naively this would work:
route @allowed {
proxy valkey:{{valkey_port}}
tls {
dns cloudflare {{cloudflare_caddy_api_token}}
resolvers 1.1.1.1
}
}
I now understand that this cannot work because the tls module in layer4 does not support the caddy certificate providers.
My question then is: is there a way to do what I want with caddy ? Namely, can I setup caddy so that it automatically gets certificates from letsencrypt with the cloudflare dns provider and uses it to do tls termination before doing tcp-level reverse proxy to my valkey server ?
2. Error messages and/or full log output:
The above target configuration file triggers this log output:
Error: adapting config using caddyfile: parsing caddyfile tokens for 'layer4': wrong argument count or unexpected line ending after 'dns', at /etc
3. Caddy version:
Built from:
FROM caddy:2.8.4-builder AS builder
RUN xcaddy build \
--with github.com/ggicci/caddy-jwt@latest \
--with github.com/caddy-dns/cloudflare \
--with github.com/ss098/certmagic-s3 \
--with github.com/mholt/caddy-l4
FROM caddy:2.8.4
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
4. How I installed and ran Caddy:
ansible + docker
a. System environment:
root@hive-dev-valkey-1:/opt/caddy/caddy.toplevel.d# lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 12 (bookworm)
Release: 12
Codename: bookworm
root@hive-dev-valkey-1:/opt/caddy/caddy.toplevel.d# docker version
Client: Docker Engine - Community
Version: 27.4.1
API version: 1.47
Go version: go1.22.10
Git commit: b9d17ea
Built: Tue Dec 17 15:45:56 2024
OS/Arch: linux/amd64
Context: default
Server: Docker Engine - Community
Engine:
Version: 27.4.1
API version: 1.47 (minimum version 1.24)
Go version: go1.22.10
Git commit: c710b88
Built: Tue Dec 17 15:45:56 2024
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.7.24
GitCommit: 88bf19b2105c8b17560993bee28a01ddc2f97182
runc:
Version: 1.2.2
GitCommit: v1.2.2-0-g7cb3632
docker-init:
Version: 0.19.0
GitCommit: de40ad0
root@hive-dev-valkey-1:/opt/caddy/caddy.toplevel.d#
b. Command:
$ docker container inspect caddy |jq -r '.[].Config.Cmd[]' |tr '\n' ' '
caddy run -c /etc/caddy/Caddyfile
c. Service/unit/compose file:
ansible role:
49 - name: Install caddy
50 community.docker.docker_container:
51 name: caddy
52 image: "{{docker_registry}}/library/caddy:latest"
53 state: present
54 restart_policy: unless-stopped
55 command: caddy run -c /etc/caddy/Caddyfile
56 ports:
57 - 443:443
58 volumes:
59 - /opt/caddy/:/etc/caddy:ro
60 networks:
61 - name: hive-local-ipv6
62 etc_hosts:
63 host.docker.internal: host-gateway
64 recreate: true
d. My complete Caddy config:
{
storage s3 {
host "{{caddy_cert_s3_host}}"
bucket "{{caddy_cert_s3_bucket}}"
access_id "{{caddy_cert_s3_access_id}}"
secret_key "{{caddy_cert_s3_secret_key}}"
prefix "ssl"
insecure false #disables SSL if true
}
layer4 {
0.0.0.0:{{valkey_port}} {
@allowed {
remote_ip {% for host in groups[valkey_clients_group] | sort %}{{hostvars[host].ansible_default_ipv4.address}}/32 {% endfor %}
}
route @allowed {
proxy valkey:{{valkey_port}}
}
}
}