Skip to content

v2.11.0: LAN Mode, Daemon Groups, and Auto-Trust

Choose a tag to compare

@mise-en-dev mise-en-dev released this 17 May 14:48
· 61 commits to main since this release
Immutable release. Only release title and notes can be modified.
2f28797

Pitchfork v2.11.0 opens the proxy up to the rest of your LAN, automates HTTPS trust on first start, and adds two long-requested config primitives: daemon groups and configurable ready_http status codes.

Highlights

  • The proxy is no longer loopback-only: LAN mode publishes <slug>.local over mDNS and binds to 0.0.0.0, while wildcard subdomain matching makes multi-tenant URLs like tenant.myapp.localhost "just work".
  • HTTPS now trusts itself: the supervisor installs the pitchfork CA into the system trust store on startup, and a new proxy untrust command cleanly removes it.
  • Batch operations got friendlier — define named [groups.*] once and reuse them across start, stop, and restart.

Added

  • LAN mode with mDNS (#430) — @gaojunran. Set proxy.lan = true (or pin a specific IP with proxy.lan_ip) and the proxy:

    • forces the TLD to .local (mDNS requirement),
    • binds to 0.0.0.0 instead of 127.0.0.1,
    • publishes each registered slug as an mDNS address record so other devices resolve it on the LAN,
    • auto-detects your LAN IP and re-publishes records if it changes (every 5s),
    • exposes PITCHFORK_LAN=1 to daemons so they know to bind on all interfaces.
    [settings.proxy]
    enable = true
    lan = true

    Then from another device on the same network, open the slug URL (e.g. myapp.local). Other devices need to trust the pitchfork CA (run pitchfork proxy trust on each, or set https = false for plain HTTP). pitchfork proxy add/remove now also notifies the supervisor via IPC so mDNS records update without a restart. See the LAN mode guide.

  • Wildcard subdomain matching (#426) — @gaojunran. With proxy.wildcard = true (default), the proxy progressively strips left-most subdomain labels until it finds a registered slug. So with myapp registered, both myapp.localhost and tenant.myapp.localhost route to the same daemon — perfect for multi-tenant local development. Exact matches always win over wildcard fallback. Browsers auto-resolve .localhost subdomains in Chrome/Firefox; Safari and custom TLDs still need dnsmasq for the DNS side.

  • Auto-trust the proxy CA (#431) — @gaojunran. When the proxy starts with HTTPS enabled, pitchfork now automatically installs its self-signed CA into the system trust store (proxy.auto_trust = true by default). On macOS this triggers a one-time Touch ID / password prompt; on Linux it silently skips if it lacks write access to the system CA directory and logs a warning. The release also adds:

    • pitchfork proxy untrust to cleanly remove the CA from macOS keychains or the distro CA dir,
    • a "Trusted: yes/no" line in pitchfork proxy status,
    • an is_ca_trusted check that queries the OS trust store directly, so manual removal is detected.
  • Daemon groups (#442) — @gaojunran. Define named groups in any pitchfork.toml and operate on them in batch:

    [groups.backend]
    daemons = ["api", "worker", "scheduler"]
    pitchfork start --group backend
    pitchfork stop --group backend
    pitchfork restart --group backend

    Groups support cross-namespace references via qualified IDs (e.g. "other-project/api"), and undefined daemons in a group produce a clear error with suggestions.

  • ready_http accepts specific status codes (#437) — @jkker. The shorthand string form still accepts any 2xx response, but the new object form lets you list exact accepted statuses — useful for authenticated endpoints that return 401 when the service is up. For example, point ready_http at a /health URL and set status = [200, 401] so pitchfork treats either response as ready. CLI --http overrides preserve the configured status list. Statuses outside 100–599 are rejected at config-parse time.

Changed

  • Faster Procs::new() and refreshes (#441) — @gaojunran. Several hot paths (supervisor start, wait, the TUI, the web UI, the stop loop) were calling refresh_processes(), which scans the entire system PID tree. They now refresh only the specific PIDs they need via refresh_pids(&[pid]) or the new refresh_daemon_pids(state) helper. Fixes #439.
  • [settings.web] docs clarified (#438) — @sargunv-headway. Web UI (and other supervisor-owned settings like [settings.proxy]) are resolved when the supervisor starts, so they need to live in global config (~/.config/pitchfork/config.toml). Project-level pitchfork.toml values only apply when the supervisor is started from that directory.

Fixed

  • Compile on non-Windows/macOS/Linux targets (#429) — @gaojunran. boot_manager previously emitted a compile_error! on unsupported targets, breaking builds on platforms like FreeBSD. It now provides a stub implementation that returns a clear runtime error from each method. Fixes #428.

New Contributors

Full Changelog: v2.10.0...v2.11.0

💚 Sponsor pitchfork

pitchfork is built by @jdx at en.dev — an independent studio shipping developer tools like mise, aube, hk, pitchfork, and more. Development is sustained by sponsorships.

If pitchfork has a place in your dev workflow, please consider sponsoring at en.dev. Individual and company sponsorships are what keep the project healthy and moving forward.