Docker Symfony (PHP7-FPM OPcache - NGINX - MySQL - ELK - REDIS - VARNISH)
Docker-symfony gives you everything you need for developing Symfony application. This complete stack run with docker and docker-compose (1.7 or higher).
Installation
-
In the docker-compose file, indicate where's your Symfony project
services: php: volumes: - path/to/your/symfony-project:/var/www/symfony
-
Build/run containers with (with and without detached mode)
docker-compose build docker-compose up docker-compose up -d
-
Update your system host file (add symfony.sf)
# get containers IP address and update host (replace IP according to your configuration) docker inspect --format '{{ .NetworkSettings.IPAddress }}' $(docker ps -f name=nginx -q) # or, if empty : docker inspect $(docker ps -f name=nginx -q) | grep IPAddress # unix only (on Windows, edit C:\Windows\System32\drivers\etc\hosts) sudo echo "171.17.0.1 symfony.sf" >> /etc/hosts # on MAC with Docker for Mac, 127.0.0.1 can be used sudo echo "127.0.0.1 symfony.sf" >> /etc/hosts
-
Prepare Symfony app
-
Retrieve mysql & redis IP
docker inspect --format '{{ .NetworkSettings.Networks.dockersymfony_default.IPAddress }}' $(docker ps -f name=db -q) docker inspect --format '{{ .NetworkSettings.Networks.dockersymfony_default.IPAddress }}' $(docker ps -f name=redis -q) # or, if empty : docker inspect $(docker ps -f name=db -q) | grep IPAddress
-
Update app/config/parameters.yml
# path/to/your/symfony-project/app/config/parameters.yml parameters: database_host: mysqldb database_password: root #... redis_host: redis
-
Composer install & create database
docker-compose exec php bash composer install # Symfony2 sf2 doctrine:database:create sf2 doctrine:schema:update --force sf2 doctrine:fixtures:load --no-interaction # Symfony3 sf doctrine:database:create sf doctrine:schema:update --force sf doctrine:fixtures:load --no-interaction
-
Usage
Just run docker-compose -d
, then:
- Symfony app: visit symfony.sf
- Symfony app through Varnish: visit symfony.sf:81
- Symfony dev mode: visit symfony.sf/app_dev.php
- Logs (Kibana): symfony.sf:8081
- Logs (files location): logs/nginx and logs/symfony
- PHPMyAdmin : symfony.sf:8080
Application cache
You should disable the Symfony cache for development and debugging purposes by removing the loadClassCache method to AppKernel into the app_dev.php file :
/**
* @var Composer\Autoload\ClassLoader $loader
*/
$loader = require __DIR__.'/../app/autoload.php';
Debug::enable();
$kernel = new AppKernel('dev', true);
//$kernel->loadClassCache(); // remove class cache
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);
And remove twig cache into config_dev.yml :
twig:
cache: false
Service Oriented Architecture (SOA) application
Multiple applications running on this stack for aIf you want to use this docker configuration to run multiple Symfony applications - ex : project{1,2,3} - follow those steps :
- add the needed hosts to your local /etc/hosts
127.0.0.1 localhost symfony.sf project1.sf project2.sf project3.sf
- or, better setup a wildcard DNS domain (Mac OS X) with Dnsmasq :
brew install dnsmasq
# This forces the .sf domain to respond with 127.0.0.1
echo "address=/.sf/127.0.0.1" > /usr/local/etc/dnsmasq.conf
# Install the daemon startup file
sudo cp -fv /usr/local/opt/dnsmasq/*.plist \
/Library/LaunchDaemons
# Start the daemon
sudo launchctl load \
/Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
# man 5 resolver
sudo mkdir -p /etc/resolver
sudo sh -c 'echo "nameserver 127.0.0.1" > /etc/resolver/sf'
now ping yourdomain.sf :
ping yourdomain.sf
PING yourdomain.sf (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.022 ms
- mount the volumes into docker-compose.yml
php:
build: php7-fpm
ports:
- 9000:9000
links:
- db:mysqldb
- redis
volumes:
- ../project1:/var/www/symfony_project1
- ../project2:/var/www/symfony_project2
- ../project3:/var/www/symfony_project3
- ./logs/symfony:/var/www/symfony/app/logs
nginx:
(...)
No need to modify nginx/symfony.conf as a wildcard is set to map automaticaly a subdomain with this pattern, example : project1.sf or project3.sf.
run docker-compose -d
(alias dkup)
For OPcache & PHP FPM you can read the Symfony documentation for NGINX, more details here : OPcache Symfony symlinks issue for a Capifony deployment.
Then you can configure the VCL to fetch the right backend for each project eg. project2.sf:81 or project3.sf:81.
Add Couchdb :
To add CouchDB to this stack, add to docker-compose.yml :
couchdb:
image: couchdb
ports:
- 8082:5984
To verify the exposed port :
docker inspect dockersymfony_couchdb_1
result :
"PortBindings": {
"5984/tcp": [
{
"HostIp": "",
"HostPort": "8082"
}
]
},
Urls for CouchDB : localhost:8082, localhost:8082/_utils/, localhost:8082/_utils/fauxton/
You can use Kinematic UI for Docker.
Docker aliases
Into ~/.bash_profile :
# dki e2dac6620ad3
function dke {
docker exec -it $1 bash
}
# dke e2dac6620ad3
function dki {
docker inspect $1
}
alias dk='docker-compose build && docker-compose up -d'
alias dkup='docker-compose up -d'
alias dkbuild='docker-compose build'
alias dks='docker ps'
alias dkrm='docker stop $(docker ps -a -q) && docker rm $(docker ps -a -q)'
alias dkd='docker-compose down'
alias dkp='lsof -i -n -P | grep com.doc'
alias dkin='docker-compose exec php bash'
How it works?
Have a look at the docker-compose.yml
file, here are the docker-compose
built images:
db
: This is the MySQL database container,php
: This is the PHP-FPM container in which the application volume is mounted (OPcache & optimized for Docker usage),nginx
: This is the Nginx webserver container in which application volume is mounted too,elk
: This is a ELK stack container which uses Logstash to collect logs, send them into Elasticsearch and visualize them with Kibana,redis
: This is a redis database container.varnish
: This is a varnish container (from the New York Times Newsroom Developers).
This results in the following running containers:
$ docker-compose ps
Name Command State Ports
--------------------------------------------------------------------------------------------------
dockersymfony_couchdb_1 tini -- /docker-entrypoint ... Up 0.0.0.0:8082->5984/tcp
dockersymfony_db_1 docker-entrypoint.sh mysqld Up 0.0.0.0:3306->3306/tcp
dockersymfony_elk_1 /usr/bin/supervisord -n -c ... Up 0.0.0.0:8081->80/tcp
dockersymfony_nginx_1 nginx Up 443/tcp, 0.0.0.0:80->80/tcp
dockersymfony_php_1 php-fpm Up 0.0.0.0:9000->9000/tcp
dockersymfony_phpmyadmin_1 /run.sh phpmyadmin Up 0.0.0.0:8080->80/tcp
dockersymfony_redis_1 docker-entrypoint.sh redis ... Up 0.0.0.0:6379->6379/tcp
dockersymfony_varnish_1 start-varnishd Up 80/tcp, 0.0.0.0:81->8081/tcp
Useful commands
# bash commands
docker-compose exec php bash
# Composer (e.g. composer update)
docker-compose exec php composer update
# SF commands (Tips: there is an alias inside php container)
docker-compose exec php php /var/www/symfony/app/console cache:clear # Symfony2
docker-compose exec php php /var/www/symfony/bin/console cache:clear # Symfony3
# Same command by using alias
docker-compose exec php bash
sf cache:clear
# MySQL commands
docker-compose exec db mysql -uroot -p"root"
# Redis commands
docker-compose exec redis redis-cli
# Cache/logs folder
sudo chmod -R 777 app/cache app/logs # Symfony2
sudo chmod -R 777 var/cache var/logs # Symfony3
# Check CPU consumption
docker stats $(docker inspect -f "{{ .Name }}" $(docker ps -q))
# Delete all containers
docker rm $(docker ps -aq)
# Delete all images
docker rmi $(docker images -q)
Concise commandline monitoring for containers
Container monitoring with ctop (OS X : brew install ctop).
Commits
If you need to display the latest Git commits into the Symfony debug bar and link them to your code repository you can use this bundle.
FAQ
-
Docker for Mac issue : port is already allocated (without even running containers) : docker-compose down & restart docker and eventually check ports : lsof -i tcp:PORTNUMBER or lsof -i -n -P | grep com.doc docker/for-mac#205
-
Got this error:
ERROR: Couldn't connect to Docker daemon at http+docker://localunixsocket - is it running? If it's at a non-standard location, specify the URL with the DOCKER_HOST environment variable.
?
Rundocker-compose up -d
instead. -
Permission problem? See this doc (Setting up Permission)
-
PHP7-FPM Docker image MEDIA.figaro Docker Hub
-
If port 80 is already in use, especially on a MAC, you should stop apache :
sudo apachectl stop