- What is a Container and why Docker Makes that a Difficult Question to Answer
- Running Go Programs in Docker Scratch Containers
- Five Reasons Your PHP Application is Hard to Containerize for Production
- Accessing Docker Desktop’s Virtual Machine
First — the container/docker/K8s approach presumes that your application can easily run as a stand-alone Linux process and PHP applications aren’t stand-alone processes. PHP itself doesn’t handle incoming HTTP requests (hello Swoole/async users I see you but you’re still a small niche in the PHP world, this isn’t for you). There’s almost always a web server like apache, nginx, or LiteSpeed sitting in front of PHP handling incoming requests.
Right out of the gate you need to decide
- Apache and mod_php?
- Litespeed and the LiteSpeed SAPI?
- Apache and PHP-FPM?
- Nginx and PHP-FPM?
- Other combinations less known to me, etc.?
Additionally — if you chose an approach like FastCGI you’ll need to decide whether your web server and FastCGI/PHP-FPM server are in the same process-space/container or if they’re in separate process-spaces/containers.
Second — there’s the PHP command line. Since PHP applications aren’t persistent in memory like a Node.js or Java application it’s very common for there to be a cron process running that handles things like log rotation, index rebuilding, etc. The PHP command line that runs the cron is a separate concern and in a containerized approach almost becomes a second application you need to deploy and maintain.
Third — PHP’s extension architecture. There’s no universal PHP binary that runs programs. PHP’s core runtime architecture is extension based. There are 72 extensions that some folks will consider part of core PHP, and other folks will consider optional. There’s also the wide world of pecl extensions — many of which folks consider hard requirements. These extensions can be compiled into the binary or enabled via shared
.so files and
php.ini configuration. What extensions will be there by default? How will users add new extensions to the system? If users need to compile their own extensions, what build tools and Linux distributions will your containers be based on?
Fourth — and more cultural than a strict technical requirement — most PHP applications have assumptions about access to a shared file system baked in. PHP’s built-in sessions work via the file system by default. Many complex MVC systems feature various levels of caching that default to the file system — often with options to skip the file system as a storage engine and use something like your database or Redis instead. So that’s needing to have your volumes story right straight out of the gate and possibly more containerized DB or cache processes to manage (or, more likely, a cloud DB/cache solution as container scaling and DB scaling are different worlds).
Finally — while all this is possible to do it puts the container orchestrator in a bit of a bind. Should she make these decisions for her users? Or should she build a container solution that handles every combination for her users? Or should she build a generic set of containers that allow her users to make these decisions for themselves? In an ideal world, it’s all of them — but time is the ultimate trade-off. Particularly with open-source work.
The end result? Drupal provides a dizzying array of tags with different Linux distributions and PHP versions. Laravel provides a new noun. The core PHP project side steps the issue and lets “the Docker community” build their images. Etc. So far containerization remains uneven and inconsistent across the PHP world and will likely stay that way.