Skip to content

v2.10.0: Templates, hosts sync, and a sharper logs view

Choose a tag to compare

@mise-en-dev mise-en-dev released this 05 May 14:55
· 73 commits to main since this release
Immutable release. Only release title and notes can be modified.
cea18d7

Pitchfork v2.10.0 brings configuration templating so daemons can reference each other's resolved ports, a much smarter reverse proxy that manages /etc/hosts and injects framework-friendly env vars, and a refreshed pitchfork logs UI. It also fixes a long-standing macOS boot-start bug where root installs landed in the wrong launchd directory.

Added

  • Tera templates in daemon config (#419) -- @gaojunran. run, env values, hooks.*, and ready_cmd can now use {{ ... }} template expressions that resolve at start time, following the dependency graph. This finally makes port = { expect = [...], bump = N } composable: daemons that depend on a port can read its actual resolved value instead of hardcoding it.

    [daemons.redis]
    run = "redis-server"
    port = { expect = [6379], bump = 10 }
    
    [daemons.api]
    run = "server --redis-port {{ daemons.redis.port }}"
    env = { DATABASE_URL = "redis://localhost:{{ daemons.redis.port }}/0" }
    depends = ["redis"]

    Available variables include self metadata (name, namespace, id, slug, dir), daemons.<name>.{port,ports,id,slug,dir,...} for same-namespace references, daemons["ns.name"] for cross-namespace, settings.proxy.*, and proxy_url. Undefined variables produce strict errors at start time. Full guide: Configuration Templates.

  • Proxy syncs /etc/hosts automatically (#418) -- @gaojunran. With proxy.sync_hosts = true (default), pitchfork maintains a marked block in /etc/hosts for every registered slug, e.g. 127.0.0.1 myapp.localhost. This removes the need for dnsmasq and per-OS resolver configuration in most setups, and finally makes Safari .localhost resolution and custom TLDs (e.g. .test) work out of the box. Entries are cleaned up on proxy shutdown. Writing to /etc/hosts may require running pitchfork with sudo; set proxy.sync_hosts = false to opt out.

  • Proxy env vars for routed daemons (#418) -- @gaojunran. Daemons with a registered slug now receive useful env vars automatically:

    • HOST=127.0.0.1 so frameworks bind to loopback
    • PITCHFORK_URL set to the daemon's public proxy URL (e.g. the https URL for its slug)
    • NODE_EXTRA_CA_CERTS pointing at the pitchfork CA when HTTPS is enabled, so Node backends trust internal proxy traffic
    • __VITE_ADDITIONAL_SERVER_ALLOWED_HOSTS=.<tld> so Vite dev servers accept the proxy hostname without manual server.allowedHosts config
  • HTTP/2 and graceful proxy shutdown (#418) -- @gaojunran. The HTTPS proxy now advertises h2 and http/1.1 via ALPN, eliminating the browser's 6-connections-per-host bottleneck. The supervisor cancels and drains in-flight proxy connections on shutdown (with a 10-second timeout) instead of dropping them mid-request. Plain HTTP requests on the HTTPS port now receive a 302 redirect to the HTTPS equivalent, and plain-HTTP WebSocket upgrades on the TLS port are rejected with 400 instead of stalling.

  • Daemon running info in templates (#419) -- Already-running daemons contribute their resolved ports to the template context, so a freshly started daemon can reference a sibling that was started in a previous batch.

  • Refined pitchfork logs display (#420) -- @gaojunran. Multi-daemon output now uses deterministic per-daemon colors and a width-aligned name column so messages line up across daemons. Tail mode (--tail, and pitchfork wait) was rewritten to use a 200ms polling loop that tracks bytes consumed rather than BufReader::stream_position, fixing dropped lines when writers used buffered I/O. New log files that appear after --tail starts are now picked up automatically.

Fixed

  • macOS root boot-start uses LaunchDaemons (#423) -- @gaojunran. sudo pitchfork boot enable previously installed to /Library/LaunchAgents/, which is the wrong directory for system-level launchd jobs and caused boot start to silently misbehave. Root installs now correctly use /Library/LaunchDaemons/pitchfork.plist. On enable, pitchfork detects and migrates legacy LaunchAgents entries from older versions; boot status warns if both user- and system-level entries are present.

  • boot disable reports incomplete cleanup (#423) -- Running boot disable without sufficient privileges to remove a system-level entry no longer reports false success; it now bails with a message indicating elevated privileges are required.

Changed

  • Smaller release binaries via serious profile (#424) -- @gaojunran. Release builds now use a new Cargo profile that enables LTO, codegen-units = 1, and symbol stripping for noticeably smaller binaries on all platforms.

Full Changelog: v2.9.1...v2.10.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.