PHP hosting

Ferron can run PHP applications through CGI or FastCGI. FastCGI is the recommended approach for most deployments. PHP worker processes stay alive between requests. This reduces process startup overhead and improves throughput.

To run PHP with FastCGI (commonly PHP-FPM), use fcgi_php:

# Example configuration with PHP through FastCGI. Replace "example.com" with your domain name.
example.com {
    root /var/www/html # Replace "/var/www/html" with your PHP app directory
    fcgi_php "unix:///run/php/php8.4-fpm.sock" # Replace with your PHP FastCGI socket or TCP URL

    # If using PHP-FPM over a Unix socket, ensure the socket is accessible by Ferron.
    # For example, in your PHP-FPM pool configuration:
    #   listen.owner = ferron
    #   listen.group = ferron
}

You can also point fcgi_php to TCP listeners (for example tcp://127.0.0.1:9000/). Use this when your PHP FastCGI server does not use a Unix socket.

Disabling PHP in specific locations⁠#

You can disable PHP FastCGI for specific locations within a domain that has fcgi_php enabled globally. Use fcgi_php false in a location block. This stops the PHP backend from processing .php files in that scope:

example.com {
    root /var/www/html
    fcgi_php "unix:///run/php/php8.4-fpm.sock"

    # Disable PHP execution for static file paths
    location /static {
        fcgi_php false
        root /var/www/static
    }

    # Disable PHP for API/proxy endpoints
    location /api {
        fcgi_php false
        proxy http://localhost:3000
    }
}

This is useful when you have a mixed deployment. For example, a PHP application that serves static files or proxies to another backend for certain paths. Without fcgi_php false, Ferron attempts to process .php files in those locations through the PHP backend. This could cause unexpected behavior.

PHP through CGI⁠#

If you specifically want classic CGI execution, enable cgi and map the .php extension:

# Example configuration with PHP through CGI. Replace "example.com" with your domain name.
example.com {
    root /var/www/html # Replace "/var/www/html" with your PHP app directory
    cgi {
        extension ".php"
    }
}

CGI is functional but usually slower than FastCGI for production workloads. Ferron starts a PHP process per request. For more control, see Configuration: FastCGI support.

Tip
  • If you use PHP-CGI with the CGI module, you may need cgi.force_redirect = 0 in your CGI php.ini. Without this setting, requests can fail with a force-cgi-redirect warning.
  • If PHP files download instead of executing, verify you enabled either fcgi_php or cgi + extension ".php" in the correct domain/location block.

Distributed tracing with PHP⁠#

PHP applications that use CGI or FastCGI automatically receive W3C Trace Context headers (traceparent, tracestate, and baggage) when tracing is enabled in Ferron. These headers appear as CGI environment variables (HTTP_TRACEPARENT, HTTP_TRACESTATE, HTTP_BAGGAGE).

With the official OpenTelemetry SDK for PHP, these headers enable distributed tracing out of the box. The SDK reads the incoming traceparent header and creates child spans. This connects your PHP backend traces to the rest of your infrastructure.

Info

You need only install and configure the OpenTelemetry SDK. No other PHP-side configuration is required. See Tracing configuration for details on enabling trace generation and sampling in Ferron.

Important

Keep upload/download directories outside of cgi-bin when using CGI to avoid accidental CGI execution of uploaded files.

See also⁠#

  • PHP edge caching (LSCache): Use Ferron as an edge caching proxy in front of Apache. This setup supports the LSCache plugin for PHP hosting.