blumeops/docs/reference/services/caddy.md
Erich Blume dc46eb7def Update all docs titles to human-readable (#117)
## Summary
- Updated frontmatter `title:` in all 63 doc cards from slug-case to human-readable (e.g. `borgmatic` → `Borgmatic`, `ai-assistance-guide` → `AI Assistance Guide`)
- Titles now closely match file stems so `[[wiki-links]]` render naturally without alternate anchor text
- Corrected titles that diverged from stems (e.g. `host-inventory` → `Hosts`, `grafana-alloy` → `Alloy`, `argocd-applications` → `Apps`)
- Deleted `title-test-alpha.md` and `title-test-beta.md` test cards and removed their reference index entry

## Deployment and Testing
- [x] `docs-check-links` passes — all wiki-links valid
- [x] `docs-check-index` passes
- [x] `docs-check-filenames` passes
- [ ] Verify titles render correctly on docs site after deploy

Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/117
2026-02-07 21:44:57 -08:00

2.7 KiB

title tags
Caddy
service
networking
tls

Caddy

Reverse proxy for *.ops.eblu.me services with automatic TLS via ACME DNS-01.

Quick Reference

Property Value
Domain *.ops.eblu.me
HTTPS Port 443
Config ansible/roles/caddy/templates/Caddyfile.j2
Binary Custom build with Gandi DNS plugin

Why Caddy?

Caddy provides a single TLS termination point for all BlumeOps services:

  • Wildcard certificate for *.ops.eblu.me via Let's Encrypt
  • DNS-01 challenge using Gandi API (no port 80 needed)
  • Unified access from k8s pods, containers, and tailnet clients

See routing for when to use *.ops.eblu.me vs *.tail8d86e.ts.net.

Proxied Services

Indri-Local Services

Subdomain Backend Service
forge.ops.eblu.me localhost:3001 forgejo
registry.ops.eblu.me localhost:5050 zot
jellyfin.ops.eblu.me localhost:8096 jellyfin

Kubernetes Services

K8s services are proxied via their Tailscale Ingress endpoints:

Subdomain Backend Service
grafana.ops.eblu.me grafana.tail8d86e.ts.net grafana
argocd.ops.eblu.me argocd.tail8d86e.ts.net argocd
docs.ops.eblu.me docs.tail8d86e.ts.net docs
feed.ops.eblu.me feed.tail8d86e.ts.net miniflux
... ... (see defaults/main.yml for full list)

TCP Services (Layer 4)

Port Backend Service
2222 localhost:2200 Forgejo SSH
5432 pg.tail8d86e.ts.net:5432 postgresql

Configuration

Caddy is managed via the caddy Ansible role:

# Deploy caddy changes
mise run provision-indri -- --tags caddy

Key files:

  • ansible/roles/caddy/defaults/main.yml - Service definitions
  • ansible/roles/caddy/templates/Caddyfile.j2 - Caddy config template

Secrets

Secret Source Description
GANDI_BEARER_TOKEN 1Password API token for DNS-01 challenges

The token is written to ~/.config/caddy/gandi-token (chmod 0600) and sourced by the Caddy wrapper script.

Custom Build

Caddy is built from source with the Gandi DNS plugin:

# Build location
~/code/3rd/caddy/bin/caddy

The build includes the github.com/caddy-dns/gandi plugin for ACME DNS-01 challenges.

  • gandi - DNS hosting and ACME DNS-01 provider
  • routing - Service routing architecture
  • forgejo - Git forge (proxied by Caddy)
  • zot - Container registry (proxied by Caddy)
  • tailscale-operator - K8s services use Tailscale Ingress, then Caddy