Hi all! I fell in love with caddy when I started getting seriously into selfhosting about a year ago. I’ve thought many times about switching to NGINX since a lot of selfhosting docs provide explicit instructions for it, but the powerful simplicity of caddy keeps me here.
There are a few things I’m still figuring out, but given I don’t want to migrate, I feel like I should invest in expanding my caddy knowledge and take advantage of the community where documentation might be more sparse.
1. The problem I’m having:
In honesty, my Caddyfile is currently working, albeit cobbled together. I don’t want to waste anyone’s time, but before I start making posts about adding features to my setup, I want to make sure I’m going about my current configuration the most efficient way that’s easiest to build on. I’d love if folks could give me tips on things to change/add/optimize.
Specifically, later on, I’m hoping to:
- Insert some custom HTML into matched URLs (e.g. banners to provide service updates, or extra usage instructions on a specific app page all my users all have trouble with).
- Monitor logs for intrusions with something like Fail2Ban, hence the common log transformer you’ll see. I haven’t gotten that going yet.
- Lock things down a bit more—I don’t think I’m taking full advantage of security features, like blocking requests that don’t come through Cloudflare.
- Or maybe migrate to Cloudflare Tunnels completely?? Thoughts??
2. Error messages and/or full log output:
N/A
3. Caddy version:
2.7.6
4. How I installed and ran Caddy:
ASUS AX86U router running AsusMerlin firmware, using the tutorial I wrote.
Compiled with xcaddy
to include the Cloudflare and log transformer plugins.
My service diagram is basically:
- Cloudflare (unproxied CNAMEs)
- to Afraid dynDNS
- to Caddy on my router
- to services (mostly running on Docker)
(plus a few Cloudflare tunnels, as a treat)
a. System environment:
uname -a:
Linux {hostname} 4.1.52 #2 SMP PREEMPT {date} aarch64 ASUSWRT-Merlin
b. Command:
From the init.d script:
caddy start --config /opt/etc/caddy/Caddyfile
c. Service/unit/compose file:
/opt/etc/init.d/S98caddy:
#!/bin/sh
ENABLED="yes"
PROCS="caddy"
ARGS="start --config /opt/etc/caddy/Caddyfile"
WORK_DIR="/opt/share/caddy"
DESC=$PROCS
PREARGS=""
PRECMD=""
POSTCMD=""
d. My complete Caddy config:
{
storage file_system {
root /opt/share/caddy
}
# Why'd I ever put this in here??? Seriously it's caused me so much pain
# auto_https disable_redirects
servers {
trusted_proxies static 10.0.0.0/25
}
}
adguardhome:80 {
reverse_proxy 10.0.0.1:14711
}
homeassistant:80 {
reverse_proxy 10.0.0.10:8123
}
# Note to forum folks: I forgot why I put the cors stuff in here—
# I think because I was having issues with Organizr
# (server dashboard) iframe'ing HTTP tabs through the HTTPS connection
(cors) {
@origin{args.0} header Origin {args.0}
header @origin{args.0} Access-Control-Allow-Origin "{args.0}"
}
*.alchemy.lgbt, alchemy.lgbt {
tls {
dns cloudflare nB0S2hAqKPmEXv457T0iKLww10Jwvn8g_vDLTcUo
}
log {
output file /opt/var/log/caddy/alchemy-lgbt-access.log
format transform "{common_log}"
}
handle /meetings* {
redir https://powers.notion.site/Meetings-bd30dec237e4471eb1a816050a93cb7e?pvs=4
}
handle /equipment* {
redir https://powers.notion.site/aaf804a8b7a24db2a66b60af509c8900?v=542610798236418ebb5a59a0696876b4&pvs=4
}
handle /weather* {
redir https://weather.com/weather/tenday/l/4b278ae41ffbc63dc108baa22ab29eaed39fad1daf03fdda0349e1e31f1285e8136cf0ab2d0e6cb208d67603c663c07e
}
handle /stuff* {
redir https://docs.google.com/spreadsheets/d/1iFaKwf26t2xtfmMGuGNASyh8nCktyh4jz96cuyZtnM8/edit?usp=sharing&_sm_nck=1
}
handle /people* {
redir https://powers.notion.site/080fc268d9a04645a8df95deda179bf5?v=19e38629dd9c4fedb8fce6856e5ecf81&pvs=4
}
handle /tasks* {
redir https://powers.notion.site/5ed4fa70351e423cac2ecf46ba14ede4?v=87805f8cce7f49c590983aba45be4fec&pvs=4
}
handle /data* {
redir https://powers.notion.site/Data-0e758ab8f65a4b3a90007c7b4df964d0?pvs=4
}
handle {
redir https://powers.notion.site/Wish-U-Were-Queer-1d83c29d1c7c49d4b4221cd325a9d68f?pvs=4
}
}
*.badkitty.zone {
tls {
dns cloudflare nB0S2hAqKPmEXv457T0iKLww10Jwvn8g_vDLTcUo
}
log {
output file /opt/var/log/caddy/star-badkitty-zone-access.log
format transform "{common_log}"
}
@start host start.badkitty.zone
handle @start {
redir https://powers.notion.site/Bad-Kitty-Media-Server-ef82bfe8d71a405692fefc10a036861a?pvs=4
}
@pebbles host pebbles.badkitty.zone
handle @pebbles {
redir https://badkitty.mmm.page/pebbles
}
@hass host hass.badkitty.zone
handle @hass {
reverse_proxy 10.0.0.10:8123
}
@plex host plex.badkitty.zone
handle @plex {
reverse_proxy 10.0.0.100:32400
}
@watch host watch.badkitty.zone
handle @watch {
import cors *
reverse_proxy 10.0.0.100:8088
}
@print host print.badkitty.zone
handle @print {
reverse_proxy 10.0.0.100:9191
}
@home host home.badkitty.zone
handle @home {
reverse_proxy 10.0.0.100:8088
}
@tv host tv.badkitty.zone
handle @tv {
reverse_proxy 10.0.0.100:8989
}
@stats host stats.badkitty.zone
handle @stats {
reverse_proxy 10.0.0.100:8181
}
@movies host movies.badkitty.zone
handle @movies {
reverse_proxy 10.0.0.100:7878
}
@trackers host trackers.badkitty.zone
handle @trackers {
reverse_proxy 10.0.0.100:9696
}
@jellyfin host jellyfin.badkitty.zone
handle @jellyfin {
reverse_proxy 10.0.0.100:8096
}
@justwatch host justwatch.badkitty.zone
handle @justwatch {
reverse_proxy 10.0.0.100:8096
}
@alchemy host alchemy.badkitty.zone
handle @alchemy {
redir https://powers.notion.site/Wish-U-Were-Queer-1d83c29d1c7c49d4b4221cd325a9d68f?pvs=4
}
}
*.powe.rs {
tls {
dns cloudflare nB0S2hAqKPmEXv457T0iKLww10Jwvn8g_vDLTcUo
}
log {
output file /opt/var/log/caddy/powers-access.log
format transform "{common_log}"
}
@docs host docs.powe.rs
handle @docs {
reverse_proxy 10.0.0.100:7215
}
@auth host auth.powe.rs
handle @auth {
reverse_proxy 10.0.0.100:7214
}
@s3 host s3.powe.rs
handle @s3 {
reverse_proxy 10.0.0.100:7216
}
}
*.x.powe.rs, x.powe.rs {
tls {
dns cloudflare nB0S2hAqKPmEXv457T0iKLww10Jwvn8g_vDLTcUo
}
log {
output file /opt/var/log/caddy/x-powers-access.log
format transform "{common_log}"
}
@agh host adguard.x.powe.rs
handle @agh {
reverse_proxy 10.0.0.1:14711
}
@hass host hass.x.powe.rs
handle @hass {
reverse_proxy 10.0.0.10:8123
}
@movies host movies.x.powe.rs
handle @movies {
reverse_proxy 10.0.0.100:7878
}
@torrents host torrents.x.powe.rs
handle @torrents {
reverse_proxy 10.0.0.100:55555
}
@start host start.x.powe.rs
handle @start {
reverse_proxy 10.0.0.100:5690
}
@transmission host transmission.x.powe.rs
handle @transmission {
reverse_proxy 10.0.0.100:9091
}
@plex host plex.x.powe.rs
handle @plex {
reverse_proxy 10.0.0.100:32400
}
@subtitles host subtitles.x.powe.rs
handle @subtitles {
reverse_proxy 10.0.0.100:6767
}
@home host home.x.powe.rs
handle @home {
reverse_proxy 10.0.0.100:8088
}
@downloads host downloads.x.powe.rs
handle @downloads {
reverse_proxy http://localhost:8080
}
@trackers host trackers.x.powe.rs
handle @trackers {
reverse_proxy 10.0.0.100:9696
}
@tv host tv.x.powe.rs
handle @tv {
reverse_proxy 10.0.0.100:8989
}
@watch host watch.x.powe.rs
handle @watch {
reverse_proxy 10.0.0.100:5055
}
@x host x.powe.rs
handle @x {
root * /opt/share/www
file_server
}
# Fallback for otherwise unhandled domains
handle {
root * /opt/share/www
file_server
}
}
Thanks for your time!! <3