1. Output of caddy version
:
2.5.2
2. How I run Caddy:
Ansible configures docker and runs it on the server
a. System environment:
docker
b. Command:
Not relevant
c. Service/unit/compose file:
Not relevant
d. My complete Caddy config:
NOTE: Caddyfile.j2 ansible template file
*.{{ domain }} {
log {
level INFO
output file /logs/caddy.log {
roll_size 10MB
roll_keep 10
}
}
tls {
dns cloudflare {{ cloudflare_dns_token }}
}
encode zstd gzip
header {
# Enable HTTP Strict Transport Security (HSTS)
Strict-Transport-Security "max-age=31536000;"
# Enable cross-site filter (XSS) and tell browser to block detected attacks
X-XSS-Protection "1; mode=block"
# Disallow the site to be rendered within a frame (clickjacking protection)
X-Frame-Options "DENY"
# Prevent search engines from indexing (optional)
X-Robots-Tag "none"
# Server name removing
-Server
}
@vault host vault.{{ domain }}
handle @vault {
# allow access to the admin interface only from local networks
@insecureadmin {
not remote_ip 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8
path /admin*
}
redir @insecureadmin /
# The negotiation endpoint is also proxied to Rocket
reverse_proxy /notifications/hub/negotiate 10.10.40.10:{{ vaultwarden_http_port }}
# notifications redirected to the websockets server
reverse_proxy /notifications/hub 10.10.40.10:3012
# proxy the Root directory to Rocket
reverse_proxy 10.10.40.10:{{ vaultwarden_http_port }} {
# Send the true remote IP to Rocket, so that vaultwarden can put this in the
# log, so that fail2ban can ban the correct IP.
header_up X-Real-IP {remote_host}
}
}
@portainer {
host portainer.{{ domain }}
remote_ip 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8
}
handle @portainer {
reverse_proxy 10.10.40.10:9000
}
@home {
host home.{{ domain }}
remote_ip 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8
}
handle @home {
reverse_proxy 10.10.40.10:{{ homer_http_port }}
}
@overseerr {
host overseerr.{{ domain }}
remote_ip 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8
}
handle @overseerr {
reverse_proxy 10.10.40.10:5055
}
@bazarr {
host bazarr.{{ domain }}
remote_ip 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8
}
handle @bazarr {
reverse_proxy 10.10.40.2:6767
}
@radarr {
host radarr.{{ domain }}
remote_ip 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8
}
handle @radarr {
reverse_proxy 10.10.40.2:7878
}
@sonarr {
host sonarr.{{ domain }}
remote_ip 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8
}
handle @sonarr {
reverse_proxy 10.10.40.2:8989
}
@prowlarr {
host prowlarr.{{ domain }}
remote_ip 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8
}
handle @prowlarr {
reverse_proxy 10.10.40.2:9696
}
@torrent {
host torrent.{{ domain }}
remote_ip 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8
}
handle @torrent {
reverse_proxy 10.10.40.2:{{ bittorrent_http_port }}
}
@tautulli {
host tautulli.{{ domain }}
remote_ip 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8
}
handle @tautulli {
reverse_proxy 10.10.40.10:8181
}
# Fallback for otherwise unhandled domains
handle {
abort
}
}
3. The problem I’m having:
Not really a problem, but I’m wondering if there’s a way to remove duplicate code from the Caddyfile above. If you notice, a lot of entries are repeats to make sure they are only accessible on the local network. All websites except for vault.{{ domain }}
are accessible only from the LAN
Is it possible to put remote_ip
in a variable and reference it instead of repeating it over and over? I suppose since I’m using ansible anyways I could throw those @handle sections in an ansible variable and loop over the j2 template, but I’m wondering if Caddy itself has a better way to write this without the repeated copy-paste
4. Error messages and/or full log output:
N/A
5. What I already tried:
N/A