Reverse proxying
Configuring Ferron as a reverse proxy is straightforward — you just need to specify the backend server URL using the proxy directive. To configure Ferron as a reverse proxy, you can use the configuration below:
example.com {
proxy http://localhost:3000
}The WebSocket protocol is supported out of the box in this configuration — no additional configuration is required.
Reverse proxy with static file serving support
Ferron supports serving static files and reverse proxying at once. You can use separate location blocks for this:
example.com {
# The "/api" location is used for reverse proxying
# For example, "/api/login" is proxied to "http://localhost:3000/api/login"
location /api {
proxy http://localhost:3000/api
}
# The "/" location is used for serving static files
location / {
root /var/www/html
}
}Reverse proxy with a single-page application
Ferron supports serving a single-page application and reverse proxying at once. You can use this configuration:
example.com {
# The "/api" location is used for reverse proxying
location /api {
proxy http://localhost:3000/api
}
# The "/" location is used for serving static files with SPA fallback
location / {
root /var/www/html
rewrite "^/.*" "/" {
last true
directory false
file false
}
}
}Load balancing
Ferron supports load balancing by specifying multiple upstream backends inside a proxy block. To configure Ferron as a load balancer, you can use the configuration below:
example.com {
proxy {
upstream http://localhost:3000
upstream http://localhost:3001
lb_algorithm two_random
}
}Load balancing algorithms
| Algorithm | Description |
|---|---|
random | Selects a backend randomly for each request. |
round_robin | Cycles through backends in order. |
least_conn | Selects the backend with the fewest active tracked connections. |
two_random | Picks two random backends and selects the less loaded one. |
Health checks
Ferron supports passive health checks. To enable passive health checking:
example.com {
proxy {
upstream http://localhost:3000
upstream http://localhost:3001
lb_health_check
lb_health_check_max_fails 3
lb_health_check_window 5s
}
}Reverse proxy to backends listening on Unix sockets
Ferron supports reverse proxying to backends listening on Unix sockets:
example.com {
proxy http://backend {
upstream http://backend {
unix /run/backend/web.sock
}
}
}Reverse proxy to gRPC backends
Ferron supports reverse proxying to gRPC backends that accept HTTP/2 requests:
grpc.example.com {
proxy http://localhost:3000 {
http2_only true
}
}Reverse proxy to dynamic backends (via SRV records)
Ferron supports reverse proxying to dynamic backends via DNS SRV records (requires srv-lookup feature):
example.com {
proxy {
srv _backend._tcp.example.com
}
}Example: Ferron multiplexing to several backend servers
In this example, the example.com and bar.example.com domains point to a server running Ferron.
Below are assumptions made for this example:
https://example.comis “main site”, whilehttps://example.com/agendais hosting a calendar service.https://foo.example.comis passed tohttps://saas.foo.nethttps://bar.example.comis the front for an internal backend.
You can configure Ferron like this:
* {
tls {
provider "manual"
cert "/path/to/certificate.crt"
key "/path/to/private.key"
}
}
example.com {
location /agenda {
# It proxies /agenda/example to http://calender.example.net:5000/agenda/example
proxy http://calender.example.net:5000
}
location / {
# Catch-all path
proxy http://localhost:3000
}
}
foo.example.com {
location / {
proxy https://saas.foo.net
}
}
bar.example.com {
location / {
proxy http://backend.example.net:4000
}
}For http://calender.example.net:5000/agenda/example, you will probably have to either configure the calendar service to strip agenda/ or configure URL rewriting in Ferron.
Notes and troubleshooting
- If you get
502 Bad Gatewayor504 Gateway Timeout, verify theupstreamURL is reachable and checklb_health_check_max_failssettings. - If only some paths fail, review
locationmatching order — more specific locations win over less specific ones. - For mixed static + API setups, keep API routes in a dedicated prefix like
/apiand use a catch-all/location for static files or SPA fallback. - For gRPC upstreams, enable
http2_only; without HTTP/2-only proxying, many gRPC backends will fail. - If Ferron is behind an HTTPS-terminating proxy and you also use automatic TLS, use HTTP-01 challenge instead of TLS-ALPN-01. See Automatic TLS.
- For upstream header forwarding details, see Reverse proxying configuration reference.