Caddy Routing
Single config: /etc/caddy/Caddyfile. Every app is bound to 127.0.0.1 and
Caddy is the only public listener (:80, :443, admin :2019).
Domain → upstream map
| Domain / path | Upstream | Container | App |
|---|---|---|---|
sportstlm.com, www |
127.0.0.1:9000 |
sportstlm |
Main hub |
sportstlm.com/livenba/* |
127.0.0.1:8126 |
livenba |
NBA in-run |
sportstlm.com/liveinrun2/* |
127.0.0.1:9000 |
sportstlm (sidecar) |
in-run hub |
sportstlm.com/ops/* |
127.0.0.1:9600 |
opsd |
Ops dashboard (basic auth) |
sportstlm.com/pz/api/predictz/ingest* |
127.0.0.1:9600 |
opsd |
Predictz ingest (key-gated) |
lottery.sportstlm.com |
127.0.0.1:4422 |
lottery |
Lottery |
racing.sportstlm.com |
127.0.0.1:4433 |
racing |
Horse racing |
ufc.sportstlm.com |
127.0.0.1:8080 |
ufc |
UFC |
snooker.sportstlm.com |
127.0.0.1:8091 |
snooker |
Snooker |
nba.sportstlm.com |
127.0.0.1:8092 |
nba |
NBA |
tennis.sportstlm.com |
127.0.0.1:8093 |
tennis |
Tennis |
nfl.sportstlm.com |
127.0.0.1:8094 |
nfl |
NFL |
nhl.sportstlm.com |
127.0.0.1:8095 |
nhl |
NHL |
mlb.sportstlm.com |
127.0.0.1:8096 |
mlb |
MLB |
badminton.sportstlm.com |
127.0.0.1:8097 |
badminton |
Badminton |
livenbais served under the main domain (/livenba/), not its own subdomain.
inlive2has a Dockerfile/container but no Caddy route — it is Exited (see VPS/Containers).
Shared hardening (every site block)
Each site applies the same guards before proxying:
@srcfiles→ 404 on/server.js,/package.json,Dockerfile,docker-compose.yml,insert.js, etc.@datafiles→ 404 on*.db,*.sqlite*,*.bak,*.sql.gz.@probes→ 403 on scanner paths:wp-*,xmlrpc.php,phpmyadmin*,.env*,.git*,backup*,install.php,setup.php,shell*.encode zstd gzip.@assets(/assets/*,/_next/static/*,/static/*) →Cache-Control: immutable, max-age=31536000.@fresh(HTML/API) →Cache-Control: no-cache(so a new bundle isn't held stale on mobile).
Special routes
/ops/*—basic_authuserwt(hash in Caddyfile), proxied toopsd:9600./pz/api/predictz/ingest*—uri strip_prefix /pz, key-gated insideopsd(no basic auth), because the fetch runs off-box (Cloudflare blocks this IP range)./liveinrun2and/livenba—redir ... 308to force trailing slash.
Logs
sportstlm.com→/var/log/caddy/access.log(roll 20 MiB, keep 5, 336 h).- Each subdomain →
/var/log/caddy/<name>.log, same rolling policy.
Change discipline
- A candidate probe-block config is staged at
/opt/supervision/staged/Caddyfile.probe-block(NOT active). - Snapshot + rollback via VPS/Supervision:
bash /opt/supervision/backup.sh <label> /opt/supervision/rollback.sh --list /opt/supervision/rollback.sh latest - Invalid Caddyfile is deliberately never auto-healed.