
Install Caddy with Homebrew on macOS and use it as a local HTTPS reverse proxy for an app on localhost:3000.
What is this setup for?
Caddy can sit in front of a local app. It accepts requests at https://localhost and passes them to the app running at localhost:3000. This gives a local project HTTPS without making the app manage certificates itself.
Install Caddy
Install the Homebrew package:
brew install caddyHomebrew’s Caddyfile is $(brew --prefix)/etc/Caddyfile. That resolves to /opt/homebrew/etc/Caddyfile on Apple Silicon Macs and /usr/local/etc/Caddyfile on Intel Macs.
Add the reverse proxy
Create or edit that file:
nano "$(brew --prefix)/etc/Caddyfile"Use this Caddyfile:
localhost {
reverse_proxy localhost:3000
}Start the app on port 3000, then check the Caddyfile before using it:
caddy validate --config "$(brew --prefix)/etc/Caddyfile" --adapter caddyfileReuse common configuration for several domains
A named snippet keeps shared settings in one place. Each site imports it and keeps only its own address and upstream port.
(common_proxy) {
encode zstd gzip
reverse_proxy localhost:{args[0]}
}
app.localhost {
import common_proxy 3000
}
api.localhost {
import common_proxy 4000
}Any hostname ending in .localhost uses Caddy’s local HTTPS. Use a public domain only when its DNS points to this Mac and ports 80 and 443 are reachable from the internet.
Run Caddy as a service
Start it at login:
brew services start caddyAfter changing the Caddyfile, reload the running service:
caddy reload --config "$(brew --prefix)/etc/Caddyfile" --adapter caddyfileUseful service commands:
brew services list
brew services restart caddy
brew services stop caddy
tail -f "$(brew --prefix)/var/log/caddy.log"Administrator access
You need an administrator password for sudo caddy trust, which adds Caddy’s local root certificate to the macOS trust store. macOS may also require administrator help before Caddy can use ports 80 and 443. Do not run sudo brew services start caddy: Homebrew services should run as your normal user.
Trust local HTTPS
A localhost site makes Caddy use its local certificate authority. Caddy normally offers to trust its root certificate on first use. If that did not happen, run:
sudo caddy trustThen open https://localhost. If a browser was already open when trust was added, restart it. Firefox may need the Caddy root certificate imported separately because it can use its own certificate store.
Test it
With the app and Caddy running, these should reach the proxied app:
curl -I http://localhost
curl -I https://localhostCaddy redirects HTTP to HTTPS for this hostname. If port 80 or 443 is already in use, stop the conflicting local server or choose a different site address and port.
Related
The same basic idea is described in Apache HTTPD reverse proxy notes. Caddy is placed under Programs because it is the server program being installed; reverse proxy is the networking role it performs.
Ai disclosure: written with the help of AI (ChatGPT). You are encouraged to point out errors and omissions.



