Server Setup

NGINX: easily debug PHP applications

by , , revisited on


It is essential to run PHP applications with production settings. But if there’s an issue that cannot be reproduced in a staging environment, you will want a quick way to enable debug settings at live.

NGINX is very flexible in a way that it allows to make your PHP configuration “dynamic”. Let’s configure PHP debug settings in presence of a secret debughoiFTWg3wg4WFNy cookie.

http {

    map $http_cookie $debug {
        default        0;
        "~*debughoiFTWg3wg4WFNy" 1;
    }

    map $debug $php_log_suffix {
        "0" "";
        "1" ".debug";
    }

    map $debug $php_error_reporting {
        "0" "E_ALL & ~E_DEPRECATED & ~E_STRICT & ~E_NOTICE";
        "1" "E_ALL";
    }

    ...

server {
    ...
    location ~ \.php$ {
        fastcgi_param PHP_ADMIN_VALUE "error_log=/var/log/nginx/php$php_log_suffix.log \n display_errors=$debug \n error_reporting=$php_error_reporting";
    }
}

Now you can create a page with secret URL which sets our secret debug cookie, e.g. debughoiFTWg3wg4WFNy.php:

<?php
setcookie('debughoiFTWg3wg4WFNy', 1);
echo 'Cookie is sent';

Once you visit the the secret debughoiFTWg3wg4WFNy.php page, the debug cookie is obtained by your browser. Your browser will then send it in subsequent requests. This initiates our “debug session”.

The PHP log entries will be set to use .debug suffix: /var/log/nginx/php.debug.log.
The level of PHP error logging will be set to E_ALL and the error will be displayed in browsers.

In absence of the cookie, things will work as usual. The log entries will be written to “/var/log/nginx/php.log` and the logging level will be appropriate to production environment.

Deal with caches

You have to make sure that your debug session will not prime caches on the way of “debug response” to your browser.

Thus you’d need to ensure the caches are bypassed in presence of the debug cookie.

FastCGI cache

location ~ \.php$ {

    #don't takes this FROM cache
    fastcgi_cache_bypass ... $debug;

    #don't put this TO cache
    fastcgi_no_cache ... $debug;

Varnish cache

sub vcl_recv {
    if (req.http.Cookie ~ "debughoiFTWg3wg4WFNy") {
        return (pass);
    }
}

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.