Configuration: SCGI support
This page documents the scgi directive for configuring Ferron’s SCGI (Simple Common Gateway Interface) support. SCGI is a protocol for interfacing external application servers with web servers. It is similar to CGI but with binary framing for better performance.
scgi#
example.com {
scgi {
backend tcp://127.0.0.1:4000
environment "APP_ENV" "production"
}
}The scgi directive enables SCGI protocol support. When specified, Ferron forwards requests to the configured SCGI backend using the SCGI protocol instead of spawning local processes.
| Form | Description |
|---|---|
scgi { ... } | Enables SCGI and configures nested directives. |
scgi <url: string> { ... } | Enables SCGI and sets the backend URL directly. |
backend#
| Nested directive | Arguments | Description | Default |
|---|---|---|---|
backend | <url: string> | This directive specifies the SCGI backend server URL. Supports TCP URLs (tcp://host:port) and Unix socket URLs (unix:///path/to/socket). | none |
Configuration example:
example.com {
scgi {
backend tcp://127.0.0.1:4000
}
}Configuration example with Unix socket:
example.com {
scgi {
backend unix:///var/run/app.sock
}
}- TCP URLs must include both host and port (for example,
tcp://127.0.0.1:4000). - Unix socket paths must be absolute paths.
- When a connection failure occurs (connection refused, host unreachable, and so on), Ferron logs an error and returns a
503 Service Unavailableresponse.
environment#
| Nested directive | Arguments | Description | Default |
|---|---|---|---|
environment | <name: string> <value: string> | This directive sets an SCGI environment variable passed to the backend server. Values use the same interpolation syntax as other directives. You can specify this directive multiple times. | none |
Configuration example:
example.com {
scgi {
backend tcp://127.0.0.1:4000
environment "APP_ENV" "production"
environment "APP_SECRET" "{{env.APP_SECRET}}"
environment "RUBY_VERSION" "3.3"
}
}- Environment variables take precedence over any existing variables with the same name.
- The
Proxyheader is automatically removed from the request to prevent the httpoxy vulnerability. - Ferron always sets
SERVER_SOFTWARE,SERVER_NAME,SERVER_ADDR,SERVER_PORT,REQUEST_URI,QUERY_STRING,PATH_INFO,SCRIPT_NAME,AUTH_TYPE,REMOTE_USER, andSERVER_ADMINautomatically.
Environment variables#
Ferron automatically sets the following SCGI environment variables:
| Variable | Description |
|---|---|
SERVER_SOFTWARE | Always Ferron. |
SERVER_NAME | Server hostname. |
SERVER_ADDR | Local server address. |
SERVER_PORT | Server port. |
REQUEST_METHOD | HTTP method. |
REQUEST_URI | Original request URI. |
QUERY_STRING | Query string (empty string if none). |
PATH_INFO | Path info extracted from the request. |
SCRIPT_NAME | The script path relative to the document root. |
AUTH_TYPE | Authentication type from the Authorization header (for example, Basic, Bearer). |
REMOTE_USER | Authenticated username, if available. |
SERVER_ADMIN | Server administrator email (from admin_email configuration). |
HTTPS | Set to on when the connection uses encryption. |
Additional variables set by environment directives override any automatically set variables with the same name.
For authentication integration, SCGI scripts receive REMOTE_USER and AUTH_TYPE only when used alongside a module like http-basicauth that sets ctx.auth_user.
Authentication#
When used alongside an authentication module (for example, http-basicauth), Ferron automatically populates the AUTH_TYPE and REMOTE_USER environment variables in the SCGI request. Ferron extracts the authentication type from the Authorization header (for example, Basic or Bearer).
Trace context injection#
When a trace context exists for the request, Ferron automatically injects W3C Trace Context headers (traceparent, tracestate, and baggage) into the SCGI request. The server maps these headers to standard CGI environment variables:
| Header | SCGI environment variable |
|---|---|
traceparent | HTTP_TRACEPARENT |
tracestate | HTTP_TRACESTATE |
baggage | HTTP_BAGGAGE |
This enables end-to-end distributed tracing with SCGI backend applications.
No per-module configuration is necessary. The server controls trace context injection globally based on whether a trace context exists. See Tracing configuration for details on enabling trace generation and sampling.
Observability#
Logs#
ERROR: logged when a connection to the SCGI backend fails. The message includes the connection error details.
Structured logs#
| Description (summary) | Level | Attributes |
|---|---|---|
| SCGI service unavailable | ERROR | upstream.address (string): backend server URL |
Metrics#
| Metric | Type | Attributes | Description |
|---|---|---|---|
ferron.scgi.requests | Counter | None | Number of SCGI requests processed |
ferron.scgi.failures | Counter | error.type ("service_unavailable"), ferron.scgi.backend_url | Number of SCGI requests that failed before the backend returned a response |
ferron.scgi.upstream.duration | Histogram | ferron.scgi.backend_url | Duration of SCGI upstream request processing |
Access log fields#
The SCGI module contributes the following field to the HTTP access log line:
| Field | Type | Description |
|---|---|---|
ferron.scgi.backend_url | string | SCGI backend URL. |
Trace spans#
The SCGI stage sets the following attributes on its ferron.stage.scgi span:
| Attribute | Type | Description |
|---|---|---|
http.response.status_code | int | HTTP status code returned by the SCGI backend. |
ferron.scgi.backend_url | string | URL of the SCGI backend. |
error.type | string | Error type on failure, enabling trace UI highlighting. |
Examples#
Basic SCGI backend#
example.com {
scgi tcp://127.0.0.1:4000
}SCGI with Unix socket#
example.com {
scgi unix:///var/run/app.sock
}SCGI with environment variables#
example.com {
scgi {
backend "tcp://127.0.0.1:4000"
environment "APP_ENV" "production"
environment "APP_SECRET" "{{env.APP_SECRET}}"
environment "RUBY_VERSION" "3.3"
}
}SCGI with authentication#
example.com {
root /var/www/html
basic_auth {
users {
admin "$argon2id$v=19$m=19456,t=2,p=1$..."
}
}
scgi tcp://127.0.0.1:4000
}