Using a Docker/Podman reverse proxy setup for PHP FastCGI is anot as straightforward as you may expect! (Caddy and PHP-FPM containers).
It seem's like the php error logs are not logged to the stdout aka the terminal logs when running docker-compose. Not ideal for containerised development or deployment.
Note: I use Docker here but this all works for the arguably better (more linuxy) Podman too.
The docs around the internet on this subject are almost all outdated, and so there's not super clear the solution.
There's three parts to get it working; the config files which are mounted in via docker compose, the PHP ini config and then the fpm www config.
Project File Structure:
./proj/compose.yml./proj/conf/Caddyfile./proj/php-dev.ini./proj/fpm-www.conf
Docker Compose:
name: php-dev-server
services:
caddy:
container_name: caddy
image: docker.io/caddy:latest
volumes:
- ../:/srv
- ./conf:/etc/caddy
ports:
- 8080:8080
php:
container_name: php
image: php:8.5-fpm
volumes:
- ../:/srv
- ./php-dev.ini:/usr/local/etc/php/conf.d/php-custom.ini
- ./fpm-www.conf:/usr/local/etc/php-fpm.d/zz-php-error-fix.conf
#ports:
# - 9000:9000
- Note that we specify the full URL for caddy to ensure podman compatibility.
- Docker doesn't mount files well when compared to directories. Something to do with change detection. We need to avoid that with Caddy but it doesn't seem to be an issue on the PHP side mounts.
- Notice that the php-fpm (FastCGI) ports are not exposed/forwarded directly. This is not needed since caddy talks to php-fpm internally within this compose files network. Exposing the ports would tell Docker (but not Podman) to also expose though the servers firewall.
- The "zz" is to ensure our small config is appended last.
Caddy config Caddyfile:
http://*:8080 {
root * /srv
# we specify http only above so if you want internal https, edit that too.
tls internal
# Enable the static file server.
file_server
# Or serve a PHP site through php-fpm:
php_fastcgi php:9000
}
- This will run a local PHP server on http://localhost:8080/.
- Notice that the php_fastcgi URL is the internal url within the docker compose network and it's internal port.
PHP-FPM config php-dev.ini:
short_open_tag = On
display_errors = On
html_errors = Off
- Short open tags is optional here, it was just needed for my project.
PHP-FPM config fpm-www.conf:
[www]
php_admin_flag[log_errors] = on
- This is the magic sauce that seems to be missing from the standard container configuration in 2025.

Comments & Questions
Reply by email to send in your thoughts.
Comments may be featured here unless you say otherwise. You can encrypt emails with PGP too, learn more about my email replies here.
PGP: 9ba2c5570aec2933970053e7967775cb1020ef23