π³ Production Grade, Rootless, Pre-configured, Extendable, and Multistage
PHP Docker Image for Cloud Native Deployments (and Kubernetes)
compatible with popular PHP Frameworks such as Laravel 5+ & Symfony 4+ and their variants.
Production Grade Docker Image for PHP 7+ Application running for Nginx + PHP FPM based on PHP & Nginx Official Images, compatible with popular PHP Frameworks such as Laravel 5+ & Symfony 4+ and their variants.
This is a pre-configured template image for your PHP Project, and you shall extend and edit it according to your app requirements.
The Image utilizes multistage builds to create multiple targets optimized for production and development.
β οΈ This image is for PHP applications that uses a single-entrypoint framework inpublic/index.php, such as Laravel, Symfony, and all their variants.
- Designed to run in orchestrated environments like Kubernetes.
- Multi-Container setup with
Nginx&PHP-FPMcommunicating via TCP. - Production Image that are immutable and fully contained with source code and dependencies inside.
- Runs as non-root in both application containers.
- Configured for graceful shutdowns/restarts, and correctly pass termination signal.
- Multi-stage builds for an optimized cache layers.
- Transparent configuration, all configuration determine app behavior are captured in VCS, such as PHP, FPM, and Nginx Config
- Production configuration with sane defaults tuned for performance.
- Easily extend the image with extra configuration, and scripts; such as post-build & pre-run scripts.
- Fast container start time done by only doing the necessary steps at application start and offload anything else to build.
- Override-able container CMD, used to run PHP Commands, to be used for cron-jobs/consumers.
- Image tries to fail at build time as much as possible by running all sort of checks.
- Default Healtchecks embedded for PHP FPM and Nginx
- Development Image supports mounting code and hot-reloading.
- Copy this repository
Dockerfile,dockerDirectory,Makefile, and.dockerignoreto your application root directory and configure it to your needs.
You'll need to iterate over your application's dependency system packages, and required PHP Extensions; and add them to their respective locations in the image.
- Add System Dependencies and PHP Extensions your application depends on to the Image.
- Port in any configuration changes you made for PHP.ini to the image, otherwise use the sane defaults.
make build && make upfor development setup,make deployto run the production variant.
These steps explained in details below.
Your application will be split into two components.
- The Webserver -> Server Static Content and proxy dynamic requests to PHP-FPM over TCP, webserver also applies rate limiting, security headers... and whatever it is configured for.
- The PHP Process -> PHP FPM process that will run you PHP Code.
Other type of deployments such as a cron-job, or a supervised consumer can be achieved by overriding the default image CMD.
- Docker 20.05 or higher
- Docker-Compose 3.7 or higher (optional)
- PHP >= 7 Application
- Download This Repository
- Copy
Dockerfile,dockerDirectory,Makefile, and.dockerignoreInto your Symfony Application Repository.
OR
- Modify
Dockerfileto your app needs, and add your app needed PHP Extensions and Required Packages. - Run
make upfor development ormake deployfor production. - Go to http://localhost
Makefile is just a wrapper over docker-compose commands.
-
The image comes with a handy Makefile to build the image using Docker-Compose files, it's handy when manually building the image for development or in a not-orchestrated docker host. However, in an environment where CI/CD pipelines will build the image, they will need to supply some build-time arguments for the image. (tho defaults exist.)
ARG Description Default PHP_VERSIONPHP Version used in the Image 7.4NGINX_VERSIONNginx Version 1.17.4COMPOSER_VERSIONComposer Version used in Image 2.0COMPOSER_AUTHA Json Object with Bitbucket or Github token to clone private Repos with composer.
Reference{}ENV Description Default APP_ENVApp Environment - prodfor Production image
-devfor Development imageAPP_DEBUGEnable Debug - 0for Production image
-1for Development imageTarget Env Desc Size Based On app Production The PHP Application with immutable code/dependencies. By default starts PHP-FPMprocess listening on9000. Command can be extended to run any PHP Consumer/Job, entrypoint will still start the pre-run setup and then run the supplied command.~450mb PHP Official Image (Debian) web Production The webserver, an Nginx container that is configured to server static content and forward dynamic requests to the PHP-FPM container running in the appimage variant~21mb Nginx Official Image (Alpine) app-dev Development Development PHP Application variant with dependencies inside. Image expects the code to be mounted on /var/www/appto support hot-reloading. You need to mount dummy/var/www/app/vendorvolume too to avoid code volume to overwrite dependencies already inside the image.~450mb PHP Official Image (Debian) web-dev Development Development Webserver with the exact configuration as the production configuration. Expects public directory to be mounted at /var/www/app/public~21mb Nginx Official Image (Alpine)
-
The image is to be used as a base for your PHP application image, you should modify its Dockerfile to your needs.
- Install System Packages in the following section in the Dockerfile.
# ------------------------------------- Install Packages Needed Inside Base Image -------------------------------------- RUN apt-get update && apt-get -y --no-install-recommends install \ # Needed for Image ... # Needed for Application Runtime ... < INSTALL YOU APPLICATION DEPENDENCY SYSTEM PACKAGES HERE> ...
- Install PHP Extensions In the following section in the Dockerfile.
# ---------------------------------------- Install / Enable PHP Extensions --------------------------------------------- RUN docker-php-ext-install \ opcache \ intl \ pdo_mysql \ # Pecl Extentions RUN pecl install apcu-5.1.20 && docker-php-ext-enable apcu # EX: RUN pecl install memcached && docker-php-ext-enable memcached
At build time, Image will run
composer check-platform-reqsto check that PHP and extensions versions match the platform requirements of the installed packages.
- PHP
baseConfiguration that are common in all environments indocker/php/base-php.iniπ - PHP
prodOnly Configurationdocker/conf/php/php-prod.iniπ - PHP
devOnly Configurationdocker/conf/php/php-dev.iniπ
- PHP FPM Configuration
docker/fpm/*.confπ
- Nginx Configuration
docker/nginx/*.conf && docker/nginx/conf.d/*π
In docker/ directory there is post-build and post-install scripts that are used to extend the image and add extra behavior.
-
post-buildcommand runs at the end of Image build.Run as the last step during the image build. Are Often framework specific commands that generate optimized builds.
-
pre-runcommand runs in runtime before running the container main commandRuns before the container's CMD, but after the composer's post-install and post-autload-dump. Used for commands that needs to run at runtime before the application is started. Often are scripts that depends on other services or runtime parameters.
- Your application should log app logs to stdout.. Read about 12factor/logs
- By default,
php-fpmaccess logs are disabled as they're mirrored onnginx, this is so thatphp-fpmimage will contain only application logs written by PHP. - In production, Image contains source-code, however, you must sync both
php-fpmandnginximages so that they contain the same code.
-
Why two containers instead of one ?
- In containerized environment, you need to only run one process inside the container. This allows us to better instrument our application for many reasons like separation of health status, metrics, logs, etc.
-
Why
debianbased image notalpine?- While a smaller image is very desired, and PHP image is infamous of being big. Alpine lacks a lot of packages (Available via
apk) that a typical PHP would need. Some packages are not even available for alpine as they link to glibc not musl. - The image is
alpinecompatible, even the entrypoint and helper scripts areshcompatible, modifying the image to usealpinevariant is possible with minimal changes to the image, you'll need to install the same package you're already using but foralpineand usingapk.
- While a smaller image is very desired, and PHP image is infamous of being big. Alpine lacks a lot of packages (Available via
-
Image Build Fails as it try to connect to DB.
- A typical application in most Frameworks comes with
DoctrineORM, Doctrine if not configured with a DB Version, will try to access the DB at php's script initialization (even at the post-install cmd's), and it will fail when it cannot connect to DB. Make sure you configure doctrine to avoid this extra DB Check connection.
- A typical application in most Frameworks comes with
MIT License Copyright (c) 2021 Sherif Abdel-Naby
PR(s) are Open and welcomed.

