Berth

Setting up

brew tap dps/berth https://github.com/dps/berth
brew trust dps/berth
brew install berth
berth init --domain example.com

berth init takes about three minutes. Here's what it does:

  1. Checks the Mac and installs anything missing (container, caddy, cloudflared).
  2. Starts Apple's container system. The first time, it downloads a small Linux kernel.
  3. Logs in to Cloudflare in your browser. Pick example.com when it asks which zone. Berth makes a tunnel called berth and points *.example.com at it, so every app you create later gets its hostname without touching DNS. No API token needed.
  4. Logs in to GitHub in your browser. The page wants a one-time code, which Berth has already put on your clipboard: paste it and click Authorize. (No browser? Berth uses your logged-in gh CLI, or asks for a classic token with the repo and admin:repo_hook scopes.)
  5. Installs three background services (launchd agents): berthd, Caddy and cloudflared. They start at login and restart if they die.
  6. Asks before the two things that need sudo: keeping the Mac awake and restarting after a power cut (pmset), and trusting Caddy's local certificate authority so https://*.local gets a padlock in Safari.
  7. Explains the FileVault trade-off (more below) and runs a health check.

You can run init again any time. It keeps your settings and logins and only changes what the flags say.

Some variations:

You want Run
LAN only, no Cloudflare berth init --no-tunnel
No browser at all berth init --domain example.com --github-token ghp_… --yes (Cloudflare still needs one browser login, or a copied ~/.berth/secrets/cloudflared/)
Only GitHub's servers can reach the webhook URL berth init --cf-ip-filter --cf-token … (the one thing that needs a Cloudflare API token, with Zone · WAF · Edit)
Come back from power cuts with nobody home berth init --unattended (read this first)
Public repos only, no GitHub login berth init --skip-github
Set up a replacement Mac from your backups berth init --restore (how)

--yes never runs sudo. Do the power settings yourself with sudo pmset -a sleep 0 disksleep 0 womp 1 autorestart 1.

Edit this page on GitHub (it's a section of the README)