Fix the PHP Error Handling with Docker, PHP-FPM and Nginx

I’ve been struggling to understand PHP’s error handling system, especially in the context of using Docker with the php:7.4-fpm image. I’ve managed to configure PHP-FPM, even though many of the options are still unclear to me. Here’s my current setup and the challenges I’m facing. If anyone can help clarify or guide me in the right direction, I’d greatly appreciate it!

My PHP-FPM Configuration

I’m using the php:7.4-fpm Docker image, and here’s my PHP-FPM configuration:

[global]
error_log = /var/log/php-fpm.log
daemonize = no
log_level = notice
log_limit = 8192

[www]
listen = 9000
clear_env = no
catch_workers_output = yes
decorate_workers_output = no

Key Points:

  1. Error Logging:
    • I’ve set error_log to /var/log/php-fpm.log to redirect PHP-FPM errors to a file instead of stderr and stdout.
    • This seems to work fine for PHP-FPM-related errors.
  2. Worker Output:
    • catch_workers_output = yes ensures that output from PHP workers is captured.
    • decorate_workers_output = no disables additional decoration in the logs.

My PHP Configuration (php.ini)

Here’s my PHP configuration:

error_reporting = E_ALL
display_errors = On
log_errors = On
; error_log = /var/log/php-errors.log

Key Points:

  1. Error Reporting:
    • error_reporting = E_ALL ensures all errors are reported.
    • display_errors = On displays errors on the screen (useful for debugging).
    • log_errors = On enables logging of errors.
  2. Error Log:
    • I’ve commented out the error_log directive to observe the default behavior.
    • According to the PHP documentation, if error_log is not set, errors are sent to the SAPI error logger.

What is the SAPI Error Logger?

The SAPI (Server API) error logger is the logging mechanism provided by the server interface PHP is using. In my case, since I’m using PHP-FPM with Nginx, the SAPI is PHP-FPM.

From what I’ve gathered (thanks to this StackOverflow answer), when error_log is not set:

  • Errors are sent to the parent system’s logger (e.g., Apache, Nginx, or PHP-FPM).
  • In my setup, this means errors should be handled by PHP-FPM or Nginx.

My Nginx Configuration

Here’s my Nginx configuration:

server {
error_log /var/log/nginx/web_error.log;
access_log /var/log/nginx/web_access.log;
}

The Problem:

  • PHP errors are not appearing in /var/log/nginx/web_error.log or /var/log/nginx/web_access.log.
  • I’m not sure if Nginx is capturing PHP errors or if they’re being handled by PHP-FPM.

What I Want to Achieve

  1. Capture PHP Errors:
    • I want to log PHP errors (e.g., syntax errors, runtime errors) in a file or send them to a logging system like Monolog.
    • Currently, errors are only displayed on the screen (due to display_errors = On), but I need them logged for debugging and monitoring.
  2. Understand the Flow:
    • How do PHP errors propagate through PHP-FPM to Nginx?
    • Where should I configure logging to ensure errors are captured?

Possible Solutions

Set error_log in php.ini

  • Uncomment the error_log directive and specify a file:
error_log = /var/log/php-errors.log
  • This will send all PHP errors to the specified file.

Use Monolog for Advanced Logging

  • Install Monolog via Composer:
composer require monolog/monolog
  • Configure Monolog in your PHP application:
use Monolog\Logger;
use Monolog\Handler\StreamHandler;

$log = new Logger('name');
$log->pushHandler(new StreamHandler('/var/log/php-app.log', Logger::WARNING));

// Example usage
$log->error('This is an error message');
  • This allows you to log errors to a file or even external services (e.g., Elasticsearch, Slack).

Check PHP-FPM Logs

  • Since catch_workers_output = yes is set, PHP errors might be captured in the PHP-FPM log (/var/log/php-fpm.log).
  • Verify if PHP errors are being logged there.

Nginx and PHP-FPM Communication

  • Ensure Nginx is correctly passing requests to PHP-FPM.
  • Check the Nginx error log (/var/log/nginx/web_error.log) for any issues with the FastCGI connection.

Final Thoughts

PHP error handling in a Dockerized environment with PHP-FPM and Nginx requires careful configuration to ensure errors are logged and visible. By setting error_log in php.ini, you can direct PHP errors to a specific file, while tools like Monolog offer advanced logging capabilities. Ensure PHP-FPM and Nginx are correctly configured to capture and propagate errors. Understanding the flow of errors through these layers is key to effective debugging and monitoring. With the right setup, you can achieve robust error handling for your PHP applications.

Related blog posts