For anyone who runs more than one service on localhost and forgets which port does what.

Ferrule

One binary answers for every local service you run.

Ferrule terminates TLS for made-up local domains like api.local, routes them to whatever is listening on your machine, and restarts the process when it falls over. No Docker, no nginx.conf, no fourth terminal tab running node worker.js that you'll forget about by Thursday.

Diagram: a browser request to api.local passes through Ferrule on port 443, which proxies to three local services and supervises a background worker process. browser https://api.local ferrule :80 / :443 · local CA web app.local → :5173 api api.local → :4000 worker no host · supervised restart: on-failure backoff: 2s .. 30s
01 — what it actually does

Four jobs, one process tree

Ferrule doesn't try to be a service mesh. It does the four things a local multi-service setup actually needs, and stops there.

01

Name-based routing

Give each service a host in ferrule.toml and Ferrule answers for it — api.local, admin.local, whatever you like. No /etc/hosts editing beyond the one-time wildcard entry the installer offers to add for you.

02

Real TLS, not a browser warning

Ferrule runs a local certificate authority the first time you start it, and asks once to install its root into your system trust store. After that, every *.local host gets a certificate your browser already trusts — no exceptions to click through.

03

Process supervision

Services can be a command instead of a proxy_to. Ferrule starts it, restarts it on the policy you set (never, on-failure, or always), and applies exponential backoff so a crash loop doesn't pin a core.

04

One place to look

ferrule up opens a small terminal dashboard with every service's status, port, and last log line. ferrule logs api tails just one. You stop hunting across terminal tabs for the process that died twenty minutes ago.

02 — the whole config

This is not an abbreviated example

A three-service local stack — a frontend, an API with a health check, and a supervised worker — fits in fifteen lines.

ferrule.toml
# started with `ferrule init`, edited by hand
[server]
bind = "127.0.0.1"
http_port = 80
https_port = 443
local_ca = true

[[service]]
name = "web"
host = "app.local"
proxy_to = "127.0.0.1:5173"

[[service]]
name = "api"
host = "api.local"
proxy_to = "127.0.0.1:4000"
health_check = "/healthz"

[[service]]
name = "worker"
command = "node worker.js"
restart = "on-failure"
backoff = "2s..30s"

Every key, its type, and its default → is in the configuration reference.

03 — where it fits

Compared to what you'd reach for instead

Ferrule is scoped for local development and small single-box deployments. It is not trying to replace Traefik in a Kubernetes cluster.

Ferrule nginx + systemd Traefik + Compose Plain Caddy
Config format one ferrule.toml nginx.conf + unit files YAML labels + compose file one Caddyfile
TLS for *.local built-in local CA, on by default manual, usually mkcert manual or a plugin built-in, on-demand
Runs your processes yes — restart policies, backoff no, needs systemd units no, needs containers no
Needs Docker no no yes no
Footprint ~9 MB, one binary part of the OS already Traefik + Docker Engine ~40 MB, one binary
Best fit solo devs / small teams, local machines production Linux hosts container-native teams simple static & prod proxying

Fifteen minutes, start to routed

Install the binary, write the config above, run ferrule up. The quick start walks through it on macOS, Linux, and Windows, including the one-time step of trusting the local CA.