Post on 21-Apr-2017
Dockerizing Symfony Apps
Dennis Benkert@denderello
Set out to make service orchestration simple for developers.
Based in Cologne, Germany.Ten terrific folks, and hiring!
http://giantswarm.io/
It’s that new kid everybody talks about
So, Docker ...
Ever heard about it?
IT’S FUN!
It will help you to ...
● run your environment everywhere● try out infrastructure changes easier● deploy new releases faster● run PHP without installing it locally!
How is that possible?
Docker Containers!
Watch out. Linux Kernel ahead!
Docker’sBuilding Blocks
What are Docker Containers?
Linux Containers+
Union Filesystems
Linux Containers?
RememberVirtual Machines?
They use Hypervisors
Hypervisors virtualize
a whole system
Virtual Machines
Machine
Kernel
Init
Hypervisor
VM
Kernel
InitProcess
VM
Kernel
Init
VM
Kernel
Init
Process
Process
Process
Process
Process
Try to start 100 of them on your
laptop … ;-)
Linux Containers are lightweight virtualization
Linux Containers ...
● run in their own Kernel namespace● are standalone processes● only see processes inside them● cannot see outside processes● share the kernel instance● can have their own filesystem● can be isolated using CGroups
Linux Containers
Machine
Kernel
Init
Container
Process
Container
Process
Container
Process
Union Filesystem?
Think of stacked layers
Everywrite operation
opens a new layer
Union filesystem
Basic Ubuntu RootFS
Install PHP-FPM
Change /etc/php5/fpm/php.ini
You will see a combined view of
all layers
Imagine your webserver is a
layer
And every project release becomes a
layer on top
Run this filesystem as a single process
You haveDocker
Containers!
Docker Containers is chroot on steroids.”— Jérôme Petazzoni (Docker)
“
Sounds hard to achieve?
Docker makes this super easy!
Four steps needed
1. Create a PHP file
<?php
echo "Hello from PHP";
2. Create a Dockerfile
FROM php
ADD index.php /var/www
EXPOSE 8080
WORKDIR /var/www
ENTRYPOINT ["php", "-S", "0.0.0.0:8080"]
Every line
becomes a layer
3. Build your Container
$ docker build -t denderello/phptest .
4. Run your Container
$ docker run -d -p 8080:8080 denderello/phptest
$ curl 127.0.0.1:8080
Hello from PHP
Binds local port to exposed port
You can run this Container
everywhere!
The Dockerhub saves your Containers
D
Dev Prod
Docker daemon Docker daemon
Docker client Docker client
push run
Symfony, get ready to become dockerized!
Let’s get started
Imagine a simple Symfony app
Redisnginx / fpm
Symfony
A classic setup
Let’s break this up into processes
Redis nginx
Seperate the processes
fpm
Every process becomes a container
Wait
nginx and fpm need to share the
source files
nginx
Incorporation of nginx and PHP-FPM
fpm
Symfony
Let’s add avolume container
Volume containers share folders with other containers
Redis nginx
Define the containers
fpm
Symfony
Redis
Redis Container
$ docker run -d -p 6379:6379 \
--name redis redis:2.8.13
Redis
Define the containers
Symfony
FROM ubuntu:14.04
RUN apt-get update && apt-get install -y \
git curl php5-cli php5-json php5-intl
RUN curl -sS https://getcomposer.org/installer | php
RUN mv composer.phar /usr/local/bin/composer
ADD entrypoint.sh /entrypoint.sh
ADD ./code /var/www
VOLUME /var/www
WORKDIR /var/www
ENTRYPOINT ["/entrypoint.sh"]
CMD ["echo", "hello"]
Symfony Container
Entrypoint Bash Script
#!/bin/bash
rm -rf /var/www/app/cache/*
/bin/bash -l -c "$*"
Run the Symfony Container
$ docker run denderello/symfony composer install
$ docker run denderello/symfony \
app/console cache:clear
No PHP on the local machine
anymore
Redis
Define the containers
Symfony
PHP-FPM
php-fpm Container
FROM ubuntu:14.04
RUN apt-get update && apt-get install -y \
php5-fpm php5-json php5-intl
ADD entrypoint.sh /entrypoint.sh
EXPOSE 9000
WORKDIR /var/www
ENTRYPOINT ["/entrypoint.sh"]
Configure your app with
environment variables
Entrypoint Bash Script
#!/bin/bash
echo "env[SYMFONY__REDIS_PORT] = ${REDIS_PORT_6379_TCP_PORT}" \
>> /etc/php5/fpm/pool.d/www.conf
echo "env[SYMFONY__REDIS_ADDRESS] = ${REDIS_PORT_6379_TCP_ADDR}" \
>> /etc/php5/fpm/pool.d/www.conf
exec /usr/sbin/php5-fpm --nodaemonize
Docker will set these for links
Docker links?
Containers have no open ports by
default
Exposed ones can be opened to the
host
Links open exposed ports between two containers
They will not be open to the host
Run the fpm Container
$ docker run -d denderello/fpm \
--link redis:redis \
--volumes-from symfony \
--name fpm
Redis
Define the containers
fpm
Symfony
nginx
nginx Container
FROM ubuntu:14.04
RUN apt-get update && apt-get install -y \
nginx
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf
ADD vhost.conf /etc/nginx/sites-enabled/default
ADD entrypoint.sh /entrypoint.sh
EXPOSE 80
ENTRYPOINT ["/entrypoint.sh"]
Run the nginx Container
$ docker run -d denderello/nginx \
--link fpm:fpm \
--volumes-from symfony \
--name nginx
Redis nginx
The final containers
fpm
Symfony
Running this setup requires 4 cli commands
This can be done easier
Fig
Fast, isolated development environments using Docker”— The Fig Website
“
Define your environment using
YAML
fig.yml (excerpt)
…nginx:
build: nginx/
ports:
- 8080:80
links:
- fpm
volumes_from:
- symfony
…
fig.yml (excerpt)
…symfony:
build: symfony/
links:
- redis
volumes:
- ./symfony/code:/var/www
…
Overrides the the folder when running the container
Starting all containers is just a command away
Using fig
$ fig up
Running Symfony commands is
easier
Using fig
$ fig run symfony composer install
$ fig run symfony app/console cache:clear
Hosting this is still a challenge
But there is company setting
out to change this
Sign up for our private Beta
Request Invite
http://giantswarm.io/
Thanks for listening!Reach out:Dennis Benkert@denderello@giantswarm