GETTING INSTANTLY UP AND RUNNING

WITH DOCKER AND SYMFONY
GETTING STARTED AND BEYOND WITH DOCKER AND SYMFONY
André Rømcke - VP Engineering @ezsystems
Symfony Live London, 16th of September 2016
www.ez.no
Warning
๏Won’t cover performance issues on Win/Mac in dev mode due to very slow FS
๏Pragmatic “fix” is to use Linux, or VM with files shared to host over nfs
๏Besides that there are third party solutions with own pitfalls, eg docker-sync
๏This is the first time I do this talk, so hold on tight
๏Including demo effect ;)
www.ez.no
Who?
๏André Rømcke | @andrerom
๏Norwegian, like being social, mountains, skiing, biking, running, technology
๏PHP for 11 years. From 96: Html, CSS, JS, VB, C#, PHP, Bash, Groovy, (Hack)
๏Contributed to Symfony, FOS, Composer, FIG, Docker, and attempting for PHP
๏VP Engineering at eZ Systems
๏eZ Systems AS | ez.no
๏Global, 70 people across 7 countries, partners & community in many many more
๏Maker of eZ Publish since 2001, 6th+ gen called eZ Studio (commercial) & eZ Platform
๏eZ Platform | ezplatform.com
๏Open source Content Management System, a super flexible Full and Headless CMS
๏Developed since 2011, on Symfony Full Stack since 2012 (v2.0)
www.ez.no
Getting started
basic example
The instant part, what we’ll cover:
1.Clone Symfony standard
2.Add Dockerfile for building our application container
3.Add docker-compose.yml to define our software services
4.[Optional] Add .dockerignore file to hint which files should be ignored
5.[Optional] Add .env variable for default variables
www.ez.nowww.ez.no
Getting started: #1 Clone Symfony standard
$ git clone https://github.com/symfony/symfony-standard.git
$ cd symfony-standard
# Or using composer	create-project, or using Symfony installer, ..
www.ez.nowww.ez.no
Getting started: #2 Add basic Dockerfile
$ vim Dockerfile
FROM php:7.0-apache

MAINTAINER André Rømcke "ar@ez.no"

ENV COMPOSER_HOME=/root/.composer SYMFONY_ENV=prod



COPY . /var/www/html



# … (install Composer, or skip the composer instal step below)



RUN composer install -o -n --no-progress --prefer-dist 

&& echo "Clear cache and logs so container starts clean" 

&& rm -Rf var/logs/* var/cache/*/* 

&& echo "Set perm for www-data, add data folder if you have" 

&& chown -R www-data:www-data var/cache var/logs var/sessions





EXPOSE 80

CMD ["apache2-foreground"]
www.ez.nowww.ez.no
Getting started: #3 Add basic docker-compose.yml
$ vim docker-compose.yml
version: '2'



services:

web:

build: .

image: my_web

ports: [ "8088:80" ]

environment:

- SYMFONY_ENV

- SYMFONY_DEBUG
www.ez.nowww.ez.no
Getting started: #4 Add basic .dockerignore
$ vim .dockerignore
# GIT files

.git/
# Cache, session files and logs (Symfony3)

var/cache/*

var/logs/*

var/sessions/*

!var/cache/.gitkeep

!var/logs/.gitkeep

!var/sessions/.gitkeep
www.ez.nowww.ez.no
Getting started: #5 Add default .env variables
Or having to hard code and duplicate defaults in your docker-compose.yml:
environment:

- SYMFONY_ENV=prod

- SYMFONY_DEBUG=0
Instead of having to always specify ENV variables on command line:
export SYMFONY_ENV=prod SYMFONY_DEBUG=0



docker-compose up -d
www.ez.nowww.ez.no
Getting started: #5 Add default .env variables
Instead we can set all default in one file:

$ vim .env
# Default env variables, see: https://docs.docker.com/compose/env-file/

#COMPOSE_FILE=docker-compose.yml



SYMFONY_ENV=prod

SYMFONY_DEBUG=0
Demo time
Up and running
git clone https://github.com/andrerom/symfony-live-london-2016-docker-demo.git sf_demo
cd sf_demo
git show

docker up -d
Conventions in official docker images
order in docker, in official images, and in php image
As the getting started example is way to simple, lets go over some things to know before we
make a more advance example.
We’ll cover:
1.Entrypoints
2.Data dirs
3.EVN variables & Symfony
4.Image Layers (and how it affects image size)
www.ez.nowww.ez.no
Convention: Entrypoint
Found in for instance official mysql/mariadb, postgres, solr images:
# https://github.com/docker-library/mariadb/blob/master/10.1/docker-entrypoint.sh
for f in /docker-entrypoint-initdb.d/*; do
case "$f" in
*.sh) echo "$0: running $f"; . "$f" ;;
*.sql) echo "$0: running $f"; "${mysql[@]}" < "$f"; echo ;;
*.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${mysql[@]}"; echo ;;
*) echo "$0: ignoring $f" ;;
esac
echo
done
This lets you to pass in sql and/or shell scripts to enhance a
official image without having to extend it with own docker image:
db:

image: ${MYSQL_IMAGE}

volumes_from:

- db_vol:ro
www.ez.nowww.ez.no
Convention: Data dir
Found in for instance mysql/mariadb, postgres, elastic:
Same benefit as entrypoint usage with sql files, but more specifically
for mounting backup data for start up when starting a new environment.
VOLUME /var/lib/mysql
VOLUME /usr/share/elasticsearch/data
VOLUME /var/lib/postgresql/data
www.ez.nowww.ez.no
Convention: ENV variables with Symfony
As “SYMFONY__” ENV variables are broken, common solution is:
env/docker.php
imports:

- { resource: default_parameters.yml }

- { resource: parameters.yml }

- { resource: security.yml }

- { resource: env/docker.php}
<?php

// Executed on symfony container compilation





if ($value = getenv('SYMFONY_SECRET')) {

$container->setParameter('secret', $value);

}
www.ez.nowww.ez.no
Convention: ENV variables with Symfony
But this is hopefully not needed anymore, as of 3.2 we will have this:
www.ez.nowww.ez.no
Convention: Image Layers & image size
• Each instruction in Dockerfile will by default create a new layer
• Which means files added in one layer continues taking space in final image
• Which means you will have to do things like:
# Install and configure php plugins

RUN set -xe 

&& buildDeps=" 

$PHP_EXTRA_BUILD_DEPS 

libfreetype6-dev 

libjpeg62-turbo-dev libxpm-dev libpng12-dev libicu-dev libxslt1-dev 

&& apt-get update && apt-get install -y --force-yes $buildDeps --no-install-
recommends && rm -rf /var/lib/apt/lists/* 

# Extract php source and install missing extensions

&& docker-php-source extract 

&& (…)

# Delete source & builds deps so it does not hang around in layers taking up space

&& docker-php-source delete 

&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false
$buildDeps
Advance use
extending, composing and using
Lets have a look at some actual code.
Sources:
- https://github.com/ezsystems/docker-php/blob/master/php/Dockerfile-7.0#L33
- https://github.com/ezsystems/ezplatform/tree/master/doc/docker-compose
Fin
the end, but hopefully just the beginning
For more on eZ Platform see ezplatform.com

Getting instantly up and running with Docker and Symfony

  • 1.
    GETTING INSTANTLY UPAND RUNNING
 WITH DOCKER AND SYMFONY GETTING STARTED AND BEYOND WITH DOCKER AND SYMFONY André Rømcke - VP Engineering @ezsystems Symfony Live London, 16th of September 2016
  • 2.
    www.ez.no Warning ๏Won’t cover performanceissues on Win/Mac in dev mode due to very slow FS ๏Pragmatic “fix” is to use Linux, or VM with files shared to host over nfs ๏Besides that there are third party solutions with own pitfalls, eg docker-sync ๏This is the first time I do this talk, so hold on tight ๏Including demo effect ;)
  • 3.
    www.ez.no Who? ๏André Rømcke |@andrerom ๏Norwegian, like being social, mountains, skiing, biking, running, technology ๏PHP for 11 years. From 96: Html, CSS, JS, VB, C#, PHP, Bash, Groovy, (Hack) ๏Contributed to Symfony, FOS, Composer, FIG, Docker, and attempting for PHP ๏VP Engineering at eZ Systems ๏eZ Systems AS | ez.no ๏Global, 70 people across 7 countries, partners & community in many many more ๏Maker of eZ Publish since 2001, 6th+ gen called eZ Studio (commercial) & eZ Platform ๏eZ Platform | ezplatform.com ๏Open source Content Management System, a super flexible Full and Headless CMS ๏Developed since 2011, on Symfony Full Stack since 2012 (v2.0)
  • 4.
    www.ez.no Getting started basic example Theinstant part, what we’ll cover: 1.Clone Symfony standard 2.Add Dockerfile for building our application container 3.Add docker-compose.yml to define our software services 4.[Optional] Add .dockerignore file to hint which files should be ignored 5.[Optional] Add .env variable for default variables
  • 5.
    www.ez.nowww.ez.no Getting started: #1Clone Symfony standard $ git clone https://github.com/symfony/symfony-standard.git $ cd symfony-standard # Or using composer create-project, or using Symfony installer, ..
  • 6.
    www.ez.nowww.ez.no Getting started: #2Add basic Dockerfile $ vim Dockerfile FROM php:7.0-apache
 MAINTAINER André Rømcke "ar@ez.no"
 ENV COMPOSER_HOME=/root/.composer SYMFONY_ENV=prod
 
 COPY . /var/www/html
 
 # … (install Composer, or skip the composer instal step below)
 
 RUN composer install -o -n --no-progress --prefer-dist 
 && echo "Clear cache and logs so container starts clean" 
 && rm -Rf var/logs/* var/cache/*/* 
 && echo "Set perm for www-data, add data folder if you have" 
 && chown -R www-data:www-data var/cache var/logs var/sessions
 
 
 EXPOSE 80
 CMD ["apache2-foreground"]
  • 7.
    www.ez.nowww.ez.no Getting started: #3Add basic docker-compose.yml $ vim docker-compose.yml version: '2'
 
 services:
 web:
 build: .
 image: my_web
 ports: [ "8088:80" ]
 environment:
 - SYMFONY_ENV
 - SYMFONY_DEBUG
  • 8.
    www.ez.nowww.ez.no Getting started: #4Add basic .dockerignore $ vim .dockerignore # GIT files
 .git/ # Cache, session files and logs (Symfony3)
 var/cache/*
 var/logs/*
 var/sessions/*
 !var/cache/.gitkeep
 !var/logs/.gitkeep
 !var/sessions/.gitkeep
  • 9.
    www.ez.nowww.ez.no Getting started: #5Add default .env variables Or having to hard code and duplicate defaults in your docker-compose.yml: environment:
 - SYMFONY_ENV=prod
 - SYMFONY_DEBUG=0 Instead of having to always specify ENV variables on command line: export SYMFONY_ENV=prod SYMFONY_DEBUG=0
 
 docker-compose up -d
  • 10.
    www.ez.nowww.ez.no Getting started: #5Add default .env variables Instead we can set all default in one file:
 $ vim .env # Default env variables, see: https://docs.docker.com/compose/env-file/
 #COMPOSE_FILE=docker-compose.yml
 
 SYMFONY_ENV=prod
 SYMFONY_DEBUG=0
  • 11.
    Demo time Up andrunning git clone https://github.com/andrerom/symfony-live-london-2016-docker-demo.git sf_demo cd sf_demo git show
 docker up -d
  • 12.
    Conventions in officialdocker images order in docker, in official images, and in php image As the getting started example is way to simple, lets go over some things to know before we make a more advance example. We’ll cover: 1.Entrypoints 2.Data dirs 3.EVN variables & Symfony 4.Image Layers (and how it affects image size)
  • 13.
    www.ez.nowww.ez.no Convention: Entrypoint Found infor instance official mysql/mariadb, postgres, solr images: # https://github.com/docker-library/mariadb/blob/master/10.1/docker-entrypoint.sh for f in /docker-entrypoint-initdb.d/*; do case "$f" in *.sh) echo "$0: running $f"; . "$f" ;; *.sql) echo "$0: running $f"; "${mysql[@]}" < "$f"; echo ;; *.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${mysql[@]}"; echo ;; *) echo "$0: ignoring $f" ;; esac echo done This lets you to pass in sql and/or shell scripts to enhance a official image without having to extend it with own docker image: db:
 image: ${MYSQL_IMAGE}
 volumes_from:
 - db_vol:ro
  • 14.
    www.ez.nowww.ez.no Convention: Data dir Foundin for instance mysql/mariadb, postgres, elastic: Same benefit as entrypoint usage with sql files, but more specifically for mounting backup data for start up when starting a new environment. VOLUME /var/lib/mysql VOLUME /usr/share/elasticsearch/data VOLUME /var/lib/postgresql/data
  • 15.
    www.ez.nowww.ez.no Convention: ENV variableswith Symfony As “SYMFONY__” ENV variables are broken, common solution is: env/docker.php imports:
 - { resource: default_parameters.yml }
 - { resource: parameters.yml }
 - { resource: security.yml }
 - { resource: env/docker.php} <?php
 // Executed on symfony container compilation
 
 
 if ($value = getenv('SYMFONY_SECRET')) {
 $container->setParameter('secret', $value);
 }
  • 16.
    www.ez.nowww.ez.no Convention: ENV variableswith Symfony But this is hopefully not needed anymore, as of 3.2 we will have this:
  • 17.
    www.ez.nowww.ez.no Convention: Image Layers& image size • Each instruction in Dockerfile will by default create a new layer • Which means files added in one layer continues taking space in final image • Which means you will have to do things like: # Install and configure php plugins
 RUN set -xe 
 && buildDeps=" 
 $PHP_EXTRA_BUILD_DEPS 
 libfreetype6-dev 
 libjpeg62-turbo-dev libxpm-dev libpng12-dev libicu-dev libxslt1-dev 
 && apt-get update && apt-get install -y --force-yes $buildDeps --no-install- recommends && rm -rf /var/lib/apt/lists/* 
 # Extract php source and install missing extensions
 && docker-php-source extract 
 && (…)
 # Delete source & builds deps so it does not hang around in layers taking up space
 && docker-php-source delete 
 && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false $buildDeps
  • 18.
    Advance use extending, composingand using Lets have a look at some actual code. Sources: - https://github.com/ezsystems/docker-php/blob/master/php/Dockerfile-7.0#L33 - https://github.com/ezsystems/ezplatform/tree/master/doc/docker-compose
  • 19.
    Fin the end, buthopefully just the beginning For more on eZ Platform see ezplatform.com