Demonic deployment tool that embraces systemd
0

Configure Feed

Select the types of activity you want to include in your feed.

at master 3 folders 5 files
README.md

proxy App#

Edge proxy stack: caddy-tls (TLS termination + Let's Encrypt), caddy-proxy (internal routing), anubis (PoW gate), and frps (reverse-tunnel server). All routing and identity data is per-Host — the operator supplies it; the committed repo carries only an hosts/example/ skeleton.

Services#

Service Image Role
proxy-caddy-tls library/caddy TLS termination, ACME, route to PoW / internal
proxy-caddy-proxy library/caddy Internal HTTP routing on :3001
proxy-anubis ghcr.io/techarohq/anubis PoW challenge gate
proxy-frps snowdreamtech/frps frp server (reverse tunnel + dashboard)

Quadlets reference config/ paths and stay host-agnostic; real data lands on the server via the hosts/<host>/config/ overlay applied by deploy-to.sh.

Setup (new host)#

The proxy has no .env — all user-supplied values live in per-Host data files under hosts/<host>/. To stand up a new host:

  1. Copy the skeleton to a host dir named after your VPS (the SSH alias that matches a server in servers/):

    cp -r hosts/example hosts/<my-host>
    
  2. Fill every CHANGE_ME in the three data files:

    • hosts/<my-host>/caddy-tls/Caddyfile — your apex domain. Replace every CHANGE_ME with it. The skeleton defines four routes; the subdomains (direct., mail., frps.) are wired to the right upstreams, so only the domain changes:

      CHANGE_ME                       → example.com        (apex, via Anubis PoW)
      direct.CHANGE_ME                → direct.example.com (no PoW)
      mail.CHANGE_ME                  → mail.example.com   (no PoW: JMAP/OAuth/SSE)
      frps.CHANGE_ME                  → frps.example.com   (dashboard, via PoW)
      

      The apex CHANGE_ME must DNS-resolve to the VPS so Caddy can obtain Let's Encrypt certs automatically.

    • hosts/<my-host>/caddy-proxy/Caddyfile — the same apex domain, used by internal routing. Replace every CHANGE_ME and the "Hello from CHANGE_ME" test banner:

      frps.CHANGE_ME   → frps.example.com     (→ proxy-frps:7500)
      mail.CHANGE_ME   → mail.example.com     (→ mail-stalwart / mail-bulwark)
      

      Leave the mail.* JMAP/bulwark reverse-proxy blocks as-is unless your mail App's upstreams differ.

    • hosts/<my-host>/frps/frps.toml — the frps dashboard password:

      webServer.password = "CHANGE_ME"   →   webServer.password = "<your-password>"
      

      The remaining frps settings (bindPort, vhostHTTPPort, dashboard port / addr / user) are static; change them only if your topology requires it.

  3. Deploy:

    ./deploy-to.sh <my-host>
    

    deploy-to.sh rsyncs config/ (scaffolding) then hosts/<my-host>/ (your reals) to ~/apps/proxy/config/ on the server, then runs deploy.sh.

What never gets committed#

Real host dirs are gitignored (hosts/* with !hosts/example/ negated). Only the hosts/example/ skeleton and the config/anubis/.gitkeep scaffolding are tracked. See apps/README.md → "Host-specific config" and ADR 0002 for the model.

Deploy-time safety#

deploy.sh greps every synced real file under config/ for a surviving CHANGE_ME and fails the deploy with a clear message listing the offending file. Run a local grep -r CHANGE_ME hosts/<my-host> before deploying to self-check.