README
¶
caddyui
A small terminal UI for giving the services in a monorepo real HTTPS hostnames on your own machine —
example.test, api.example.test — instead of remembering which one is on localhost:3001.
It keeps the three things that have to agree in sync for you:
Caddyfile |
hostname → 127.0.0.1:<port> reverse proxy |
/etc/hosts |
hostname → 127.0.0.1 |
certs/ |
one mkcert cert covering the apex + *.domain, trusted by your browser |
caddyui · example.test
▸ https://example.test → 127.0.0.1:3000
https://api.example.test → 127.0.0.1:3001
https://admin.example.test → 127.0.0.1:5173
a add · e edit · d delete · D domain · A apply · X stop caddy · q quit
✓ applied — try https://example.test
Install
Linux or macOS. You need caddy and mkcert on your PATH whichever way you install caddyui itself:
brew install caddy mkcert nss # macOS
sudo pacman -S caddy mkcert nss # Arch
nss is optional — without it curl trusts the local CA but Firefox and Chrome don't.
Download a release — no Go toolchain needed:
curl -sSfL https://github.com/RizkyChandra/caddyui/releases/latest/download/caddyui_$(uname -s)_$(uname -m).tar.gz \
| tar xz caddyui && install -m755 caddyui ~/.local/bin/
With Go:
go install github.com/RizkyChandra/caddyui@latest
From source — also checks your dependencies and tells you what's missing:
git clone https://github.com/RizkyChandra/caddyui && cd caddyui
./install.sh
Builds to ~/.local/bin/caddyui; override with PREFIX=/usr/local/bin. The installer prints the
package command for anything missing — it never installs system packages for you.
Use
Run it from your monorepo root:
caddyui
D sets the domain, a adds a service (subdomain + port), A applies. Edits are written to
caddyui.json immediately; nothing touches your system until you press A.
{
"domain": "example.test",
"services": [
{ "sub": "", "port": 3000 },
{ "sub": "api", "port": 3001 }
]
}
caddyui.json is meant to be committed — teammates run caddyui and press A. Caddyfile and
certs/ are generated and gitignored; certs/ holds a private key, never commit it.
Prompts prefill the current value — ctrl+u clears, esc cancels.
Use a .test domain
.test is reserved by the IETF for exactly this. If you point example.com at 127.0.0.1 instead,
that mapping is machine-wide — every program on your box loses the real example.com.
What A actually does
Each step runs with the TUI suspended, so sudo and mkcert can prompt on your terminal:
mkcert -install— first run only, adds a local CA to your system (and Firefox/Chrome) trust storemkcert— one cert fordomain+*.domain, intocerts/- writes
Caddyfile sudo cpa new/etc/hosts— your existing lines are untouched; ours live between# BEGIN caddyui/# END caddyuimarkers and are rewritten in place, so applying twice changes nothing. The original is backed up once to/etc/hosts.caddyui.bakcaddy reload, orsudo caddy startif caddy isn't running yet (root only to bind :80/:443 — caddy daemonizes itself)
X stops caddy. Hosts entries are left alone; they're harmless without a server listening.
Undoing it
caddy stop
sudo cp /etc/hosts.caddyui.bak /etc/hosts # or just delete the marked block
mkcert -uninstall # removes the local CA from your trust stores
rm -rf certs Caddyfile
Limits
- HTTP services only. A database gets no hostname — stock caddy can't proxy raw TCP, that needs
the
layer4plugin and a custom build. Postgres stays onlocalhost:5432. - Subdomains are one label deep.
apiworks,a.bdoesn't — the wildcard cert only covers one level. - Ports 80 and 443 must be free. If
caddy startsays "address already in use", something else has them — on Linux most likely a system caddy:sudo systemctl stop caddy.
Development
go test ./...
gen.go is pure (config, Caddyfile text, hosts splicing), apply.go stages files and returns the
commands that need a terminal, main.go is the TUI. The tests cover hosts splicing being idempotent
and non-destructive, caddy accepting the generated Caddyfile, and the keys that mutate config.
Documentation
¶
There is no documentation for this package.