A new Docker Compose guide promises a simple PHP 8.4 development environment. It delivers: PHP-FPM, Nginx, MariaDB, and Composer in one command. The tutorial is clean and practical.
What it skips: the permission nightmare that hits developers within hours.
The Setup Works
The stack is standard: php:8.4-fpm with PDO extensions, Nginx proxying to FastCGI, MariaDB 11 with named volumes. The Dockerfile uses multi-stage patterns from official Docker docs, copying Composer from the official image. This mirrors what 70% of enterprises already use for containerized development (Stack Overflow 2025).
PHP 8.4, released November 2024, adds JIT improvements and property hooks. PHP holds 77.6% of server-side market share (W3Techs, January 2026), though only 45% run PHP 8.x. Docker adoption makes sense: it bypasses local extension hell.
The Permission Reality
The guide mounts ./src:/var/www/html without addressing file ownership. PHP-FPM runs as www-data (UID 33). Your host user is probably UID 1000. MariaDB writes to volumes as mysql (UID 999).
This causes:
composer installpermission denied errors on Windows- MariaDB volume mount failures on Ubuntu
- Nginx 403 errors when PHP-FPM can't read files
- Database writes failing with "permission denied"
The fix requires custom user mapping in Dockerfiles or runtime UID synchronization. Production setups use USER directives and build-time args. The tutorial doesn't mention this.
Alternative Views
Skeptics argue Docker adds overhead for solo PHP projects. Native tools like Homebrew or XAMPP work fine without container complexity. Laravel Sail or VS Code Devcontainers provide pre-configured environments with permission handling baked in.
Apache-based alternatives are simpler than Nginx/PHP-FPM separation but less performant under load. Some teams prefer php:8.4-apache for development, switching to FPM for production.
What This Means in Practice
The tutorial works for read-only apps or teams willing to debug permissions. For enterprise use, add:
- User mapping:
ARG UID=1000in Dockerfile - Volume ownership fixes in entrypoint scripts
- Production-hardening: read-only volumes, non-root users
Docker simplifies PHP environments. The permission layer still needs work. History suggests tutorials that skip this create more support tickets than they save.