Less time configuring. Less time debugging.

Configuration that catches typos before production does. Correlated logs and trace IDs that turn debugging into a simple lookup — so you know why a backend failed, not just that it did.

$ cat /var/log/ferron/access.log /var/log/ferron/error.log | grep 6dea16fb9aa089a37bd163a5dc232785

[2026-08-17 06:20:27.487 WARN] [trace=6dea16fb9aa089a37bd163a5dc232785] Reverse proxy: TCP connect to 127.0.0.1:5000 failed: Connection refused (os error 111)

[2026-08-17 06:20:27.487 WARN] [trace=6dea16fb9aa089a37bd163a5dc232785] Reverse proxy: backend failed, retrying with another — upstream: http://localhost:5000: Connect failed: TCP connect failed: Connection refused (os error 111)

[2026-08-17 06:20:27.487 WARN] [trace=6dea16fb9aa089a37bd163a5dc232785] Reverse proxy: TCP connect to [::1]:5000 failed: Connection refused (os error 111)

[2026-08-17 06:20:27.487 ERROR] [trace=6dea16fb9aa089a37bd163a5dc232785] Reverse proxy: Bad gateway — upstream: http://localhost:5000: Connect failed: TCP connect failed: Connection refused (os error 111)

Watch how Ferron turns debugging into a simple lookup with correlation.

Web servers shouldn't feel like this

Your web server should be clear and predictable — not something you have to wrestle with to find out what went wrong.

Configuration sprawl

One minor directive change silently breaks unrelated routes. As your configuration grows over time, every deployment feels like a roll of the dice.

No trail to follow

Tracing a single failure across distributed services is a nightmare. Without log correlation, you're left grepping timestamps just to guess what went wrong.

Operational uncertainty

When production dips, you shouldn't have to play detective. Did the config reload succeed? Is the backend healthy? You have to SSH just to see the server status.

No fast path to root cause

When the circuit breaker gets tripped, you shouldn't have to manually correlate logs to find out why, and end up guessing instead of just doing a simple lookup.

Configuration that stays clear

Clear defaults and minimal directives, with predictable behavior even as your setup grows.

Popular web server (NGINX host configuration)

server {
    listen 80;
    listen 443 ssl http2;

    server_name example.com;
    server_tokens off;

    # Assuming you use Certbot for automatic certificate management
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    root /var/www/html;
    gzip on;

    location / {
        try_files $uri $uri/ =404;
    }
}

Ferron 3

# TLS certificate is obtained automatically by Ferron
example.com {
    root /var/www/html
}

Built for operators

Safe deployments and runtime control made simple for daily server management.

$ ferron doctor -c /etc/ferron/ferron.conf

[2026-07-11 20:26:18.807 WARN] Best practice violation (block 'http port 8443' in file '/etc/ferron/ferron.conf' at line 2, column 19): OTLP configured without an explicit `service_name`; data might be attributed incorrectly for multi-service environments

[2026-07-11 20:26:18.807 WARN] Best practice violation (block 'http port 8443' in file '/etc/ferron/ferron.conf' at line 19, column 5): `directory_listing` exposes generated indexes for directories without index files; enable it only for intentionally public file listings

"ferron doctor" showing configuration best-practice warnings.

Debug production without guessing

When things break, you see exactly what's happening: live runtime state, right out of the box.

A demonstration of debugging Ferron infrastructure via Grafana

See how Ferron helps you, while you debug your infrastructure.

Correlate logs and traces

When latency rises or backends fail, bridge your signals to trace requests end-to-end and see exactly what happened.

Spot problems before users report them

Watch latency, error rates, circuit breakers, and backend health in real time.

Halt configuration drift instantly

Monitor your running state; detect manual, out-of-band edits immediately so you never suffer from silent drift or a broken reload.

Keep using the tools you already know

Send logs, metrics, and traces to Grafana, Better Stack, OpenTelemetry collectors, and other observability systems.

Even grep can be enough

Access and application logs carry the same trace ID by default. When a request fails, grep that ID across both: see the full chain without a collector.

$ cat access.log error.log | grep 3d5b9bbc315384151b7b72d8270fddc5

>>> 3d5b9bbc315384151b7b72d8270fddc5 <<< ::1 - - [13/Jun/2026:05:22:52 +0200] "GET / HTTP/2.0" 502 - "-" "curl/8.20.0"

[2026-06-13 05:22:52.672 WARN] [trace=3d5b9bbc315384151b7b72d8270fddc5] Reverse proxy: TCP connect to localhost:3000 failed: Connection refused (os error 111)

[2026-06-13 05:22:52.672 WARN] [trace=3d5b9bbc315384151b7b72d8270fddc5] Upstream http://localhost:3000 circuit opened after 5 failures within 30s

[2026-06-13 05:22:52.672 WARN] [trace=3d5b9bbc315384151b7b72d8270fddc5] Reverse proxy: backend failed, retrying with another — upstream: http://localhost:3000: Connect failed: TCP connect failed: Connection refused (os error 111)

...

Real search across access and application logs.

Follow a request across your logs

One trace ID ties multiple logs. Grep it and the full sequence appears: what it returned, where it failed.

Works with whatever you're already doing

Plain text log files, compatible with logrotate, journald, and any log shipper you already have configured.

No complex setup needed

Log files are easy to set up. No collector, no dashboard, no additional process to keep running.

Performance without endless tuning

Predictable throughput under real-world workloads; no performance expertise required to keep it stable.

High concurrency

No dropped connections or silent backend failures under load. No artificial keep-alive limits, no pool starvation.

Modern protocols

Full HTTP/2 and HTTP/3 support, keeping connections fast and efficient under heavy traffic.

Efficient by design

Low memory usage and consistent behavior as traffic scales: no thread-per-connection overhead eating into your resources.

No tuning required

High performance out of the box. No tweaking worker counts, connection pools, or hidden limits.

Every question, answered without guessing

Real scenarios answered with real Ferron capabilities.

Why did this backend just get pulled out of rotation?

Circuit breaker transitions are emitted as named events and tracked as a live metric, not buried in a log line you'd only find if you knew to look.

Did my reload actually change anything?

Query the admin API's /config and /status endpoints and see the running configuration and its state directly: no restart, no diffing files by hand.

A request failed at 2:52am, where do I even start?

Grep the trace ID out of the access log and pull every related line from the application log in the same breath. No collector, no dashboard login, just the terminal you already have open.

Is this backend actually slow, or is my code slow?

Spans separate the reverse proxy hop from the origin response, so the flame graph tells you which side of the wire the time went, instead of you guessing from an aggregate number.

Install in minutes

Choose your platform and get Ferron running with a single command.

Using packages (recommended):

Using installer script:

sudo bash -c "$(curl -fsSL https://get.ferron.sh/v3)"

Join the Ferron community

Ferron is an open-source project built by developers like you. Whether you're a contributor or just using Ferron, you're welcome to join its community.

2K+

stars on GitHub

20+

contributors on GitHub

50K+

Docker Hub pulls

Contribute on GitHub

Improve Ferron by reporting issues, suggesting features, or submitting code.

Join Matrix community

Join our community on Matrix to chat with others who use Ferron.

What they say about Ferron

Don't take our word for it. Hear from people who have seen Ferron and are using it every day.

You may want to check out what Ferron is doing. I've been using it for a few months. Highly recommend. (...) Significantly easier to set up than nginx, and by far the most effortless auto TLS integration. (...) Highly recommend using the v2 docker images though. It now uses KDL for configuration, which is much cleaner than YAML. The syntax is versatile enough that you can create a custom DSL of sorts. Ferron uses it to replicate if statements, and uses them to filter access by IP or headers.

Source

Michael Murphy

Engineer at System76 and Pop!_OS maintainer

I just switched to @ferronweb on my pi to serve services at home. Imho ferron is just way easier to configure than anything else.

Source

Andreas Wachter

just tried it for serving a fastapi. It's fantastic. Instant TLS via Let's Encrypt. There may be other webservers that are equally easy, but this one is certainly easier than Apache or ngninx, which I used so far. Love it.

Source

Thomas Walther

Founded and sold an AI startup to Spotify

Ready for a simpler web server?

Deploy in minutes, configure with clarity, and run with confidence — from first setup to production.