๐ณ A preconfigured, extendable, multistage, PHP Symfony 4.3+ Docker Image for Production and Development
.
Docker Image for Symfony 4.3+ Application running Nginx + PHP FPM based on PHP & Nginx Alpine Official Images.
This is a pre-configured template image for your Symfony Project, and you shall extend and edit it according to your app requirements. The Image utilizes docker's multistage builds to create multiple targets optimized for production and development.
You should copy this repositoryDockerfile
, docker
Directory, Makefile
, and .dockerignore
to your Symfony application repository and configure it to your needs.
-
Multi-Container setup with
Nginx
&PHP-FPM
communicating via TCP. -
Production Images is immutable and fully contained Image with source code and dependencies inside, Development image is set up for mounting source code on runtime with hot-reload.
-
Image configuration is transparent, all configuration and default configurations that determine app behavior are present in the image directory.
-
Nginx is pre-configured with HTTP, HTTPS, and HTTP2. and uses a self-signed certificate generated at build-time. For production, you'll need to mount your own signed certificates to
/etc/nginx/ssl/server.(crt/key)
. -
The image has set up healthchecks for
Nginx
andPHP-FPM
, and you can add application logic healthcheck by adding it inhealthcheck.sh
๐. -
Image tries to fail at build time as much as possible by running all sort of Checks.
-
Dockerfile is arranged for optimizing prod builds so that changes won't invalidate cache as much as possible.
-
Available a
Supervisord
andCrond
image variant for your consumers and cron commands.
- Docker 17.05 or higher
- Docker-Compose 3.4 or higher (optional)
- Symfony 4+ Application
- PHP >= 7 Application
- Download This Repository
- Copy
Dockerfile
,docker
Directory,Makefile
, and.dockerignore
Into your Symfony Application Repository.
OR
![create repository from template](https://user-images.githubusercontent.com/16992394/65464461-20c95880-de5a-11e9-9bf0-fc79d125b99e.png)
- Modify
Dockerfile
to your app needs, and add your app needed PHP Extensions and Required Packages. - Go to
docker/.composer/.env
and modifySERVER_NAME
to your app's name. - Run
make up
for development ormake deploy
for production. - Go to https://localhost
Makefile is just a wrapper over docker-compose commands.
Production runs on port
80
and443
, Development runs on8080
and443
.
-
The image is to be used as a base for your Symfony application image, you should modify its Dockerfile to your needs.
-
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_VERSION |
PHP Version used in the Image | 7.3.9 |
ALPINE_VERSION |
Alpine Version | 3.10 |
NGINX_VERSION |
Nginx Version | 1.17.4 |
COMPOSER_VERSION |
Composer Version used in Image | 1.9.0 |
SERVER_NAME |
Server Name (In production, and using SSL, this must match certificate's common name) |
php-app |
COMPOSER_AUTH |
A Json Object with Bitbucket or Github token to clone private Repos with composer. Reference |
{} |
ENV | Description | Default |
---|---|---|
APP_ENV |
App Environment | - prod for Production image- dev for Development image |
APP_DEBUG |
Enable Debug | - 0 for Production image- 1 for Development image |
Target | Description | Size | Stdout | Targets |
---|---|---|---|---|
nginx |
The Webserver, serves static content and replay others requests php-fpm |
21 MB | Nginx Access and Error logs. | nginx-prod , nginx-dev |
fpm |
PHP_FPM, which will actually run the PHP Scripts for web requests. | 78 MB | PHP Application logs only. | fpm-prod , fpm-dev |
supervisor |
Contains supervisor and source-code, for your consumers. (config at docker/conf/supervisor/ ) |
120 MB | Stdout of all Commands. | supervisor-prod |
cron |
Loads crontab and your app source-code, for your cron commands. (config at docker/conf/crontab ) |
78 MB | Stdout of all Crons. | cron-prod |
All Images are Alpine based. Official PHP-Alpine-CLI image size is 79.4MB.
Size stated above are calculated excluding source code and vendor directory.
- For SSL: Mount your signed certificates as secrets to
/etc/nginx/ssl/server.key
&/etc/nginx/ssl/server.crt
- Make sure build argument
SERVER_NAME
matches certificate's common name. - Expose container port
80
and443
.
By default, Image has a generated self-signed certificate for SSL connections added at build time.
- Mount source code root to
/var/www/app
- Expose container port
8080
and443
. (or whatever you need actually)
- PHP
prod
Configurationdocker/conf/php/php-prod.ini
๐ - PHP
dev
Configurationdocker/conf/php/php-dev.ini
๐ - PHP additional Symfony recommended configuration at
docker/conf/php/symfony.ini
๐
Add Packages needed for PHP runtime in this section of the Dockerfile
.
...
# ------------------------------------- Install Packages Needed Inside Base Image --------------------------------------
RUN apk add --no-cache \
# # - Please define package version too ---
# # ----- Needed for Image----------------
fcgi tini \
# # ----- Needed for PHP -----------------
<HERE>
...
Add PHP Extensions using docker-php-ext-install <extensions...>
or pecl install <extensions...>
and Enable them by docker-php-ext-enable <extensions...>
in this section of the Dockerfile
.
...
# --------------------- Install / Enable PHP Extensions ------------------------
RUN docker-php-ext-install opcache && pecl install memcached && docker-php-ext-enable memcached
...
At build time, Image will run
composer check-platform-reqs
to check that PHP and extensions versions match the platform requirements of the installed packages.
Nginx defaults are all defined in docker/conf/nginx/
๐
Nginx is pre-configured with:
- HTTP, HTTPS, and HTTP2.
- Rate limit (
rate=5r/s
) - Access & Error logs to
stdout/err
- Recommended Security Headers
- Serving Static content with default cache
7d
- Metrics endpoint at
:8080/stub_status
from localhost only.
At build time, Image will run
nginx -t
to check config file syntax is OK.
Post Installation scripts should be configured in composer.json
in the post-install-cmd
part.
However, Sometimes, some packages have commands that need to be run on startup, that are not compatible with composer, provided in the image a shell script post-deployment.sh
๐ that will be executed after deployment.
Special about this file that it comes loaded with all OS Environment variables as well as defaults from .env
and .env.${APP_ENV}
files. so it won't need a special treatment handling parameters.
It is still discouraged to be used if it's possible to run these commands using composer scripts.
If you have consumers (e.g rabbitMq or Kafka consumers) that need to be run under supervisor, you can define these at docker/conf/supervisor/*
, which will run by the supervisor
image target.
If you have cron jobs, you can define them in docker/conf/crontab
, which will run by the cron
image target.
- Your application should log app logs to stdout.. Read about 12factor/logs
- By default,
php-fpm
access & error logs are disabled as they're mirrored onnginx
, this is so thatphp-fpm
image will contain only application logs written by PHP. - During Build, Image will run
composer dump-autoload
andcomposer dump-env
to optimize for performance. - In production, Image contains source-code, however, you must sync both
php-fpm
andnginx
images so that they contain the same code.
MIT License Copyright (c) 2019 Sherif Abdel-Naby
PR(s) are Open and welcomed.
This image has so little to do with Symfony itself and more with Setting up a PHP Website with Nginx and FPM, hence it can be extended for other PHP Frameworks (e.g Laravel, etc). maybe if you're interested to build a similar image for another framework we can collaborate.
- Add a slim image with supervisor for running consumers.
- Add a slim image with cron tab for cron job instances.
- Add node build stage that compiles javascript.
- Recreate the image for Symfony 3^
- Recreate the image for Laravel