DEV Community

Habib Akande
Habib Akande

Posted on

Fixing Laravel Logs Not Showing in Docker (PHP-FPM + Nginx + Supervisor)

If you’re running Laravel inside Docker with PHP-FPM, Nginx, and Supervisor, you might run into a confusing issue:

  • docker logs <container> shows nothing
  • storage/logs/laravel.log is empty
  • Logging looks configured correctly

After some digging, the fix turned out to be a combination of small but critical settings across Supervisor, PHP, and Laravel.

This post documents the working setup.

The setup

  • Laravel
  • PHP-FPM
  • Nginx
  • Supervisor
  • Docker

Laravel is configured to log to stdout/stderr instead of files.

Supervisor must forward logs to stdout/stderr

This is the most important part.

Supervisor does not forward process output to Docker by default.

If this is missing, logs are silently swallowed.

Make sure each program includes:

stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

Enter fullscreen mode Exit fullscreen mode

Without this, docker logs will always be empty, even if Laravel is logging correctly.

Nginx configuration (optional)

Nothing is strictly required here for Laravel logs.

If you do want Nginx logs to appear in Docker:

access_log /dev/stdout;
error_log  /dev/stderr warn;
Enter fullscreen mode Exit fullscreen mode

Otherwise, Nginx can be ignored for this issue.

PHP must log errors to stderr

PHP-FPM needs to write errors to Docker’s stderr.

In php.ini (or a Docker override):

log_errors=On
error_log=/proc/self/fd/2
Enter fullscreen mode Exit fullscreen mode

This ensures PHP errors show up in docker logs.

The real culprit: Laravel logging.php

The main issue is in Laravel’s Monolog configuration.

This looks correct at first glance, but the stream configuration matters a lot.

Working configuration:

'stderr' => [
    'driver' => 'monolog',
    'level' => env('LOG_LEVEL', 'debug'),
    'handler' => StreamHandler::class,
    'formatter' => env('LOG_STDERR_FORMATTER'),
    'with' => [
        'stream' => 'php://stdout',
        'level' => env('LOG_LEVEL', 'debug'),
    ],
],
Enter fullscreen mode Exit fullscreen mode

Key takeaways:

  • The stream must explicitly point to php://stdout (or stderr)

  • Using with incorrectly can silently break logging

  • Laravel does not warn you when Monolog is misconfigured

This is the main reason logs were not appearing.

Environment configuration

Final .env setup:

LOG_CHANNEL=stack
LOG_STACK=stderr
LOG_LEVEL=debug
LOG_DEPRECATIONS_CHANNEL=null
Enter fullscreen mode Exit fullscreen mode

Don’t forget to clear cached config:

php artisan config:clear
Enter fullscreen mode Exit fullscreen mode

Final result

With:

  • Supervisor forwarding stdout/stderr

  • PHP writing errors to stderr

  • Laravel correctly streaming logs

  • Docker collecting logs

Top comments (0)