GitHub - sherifabdlnaby/symdocker: 🐳 An extendable multistage PHP Symfony 4.3+ D...
source link: https://github.com/sherifabdlnaby/symdocker
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
A preconfigured, extendable, multistage, PHP Symfony 4.3+ Docker Image for Production and Development
Introduction
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.
Main Points
-
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.
Requirements
- Docker 17.05 or higher
- Docker-Compose 3.4 or higher (optional)
- Symfony 4+ Application
- PHP >= 7 Application
Setup
1. Add Template to your repo.
- Download This Repository
- Copy
Dockerfile
,docker
Directory,Makefile
, and.dockerignore
Into your Symfony Application Repository.
2. Start
- 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
.
Building and Extending Image
-
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.)
Build Time Arguments
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 |
{} |
Runtime Environment Variables
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 |
Image Targets
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.
Tips for building Image in different environments
Production
- 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.
Development
- Mount source code root to
/var/www/app
- Expose container port
8080
and443
. (or whatever you need actually)
Configuration
1. PHP Extensions, Dependencies, and Configuration
Modify PHP Configuration
- 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
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 & Enable PHP Extensions
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.
2. Nginx Configuration
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.
3. Post Deployment Custom Scripts
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.
3. Supervisor Consumers
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.
4. Cron Commands
If you have cron jobs, you can define them in docker/conf/crontab
, which will run by the cron
image target.
Misc Notes
- 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.
License
MIT License Copyright (c) 2019 Sherif Abdel-Naby
Contribution
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.
Possible Ideas
- 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
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK