October 11, 2017 0 comments

Gist - A ready to go Dockerfile with PHP 7 for your Symfony project

Making websites with Symfony requires a lot of dependencies that can be painful and time-consuming to install on your computer. That's why Docker was invented. With it, you can setup a working development environnement pretty quickly since you have pratically nothing to do.

This Gist provides you a Dockerfile with all the required tools you need (PHP 7ApacheComposer...). 

We saw in a previous tutorial how to install Docker and docker-compose on your computer. Both are required for use this gist so check it out if you have not already done.




So here is a list of the dependencies that will be available with this Dockerfile and docker-compose :


  • PHP 7
  • Apache 2
  • Composer
  • Memcached
  • APCu
  • MySQL
  • PhpMyAdmin
  • Mailcatcher


APCu, MySQL and PhpMyAdmin will be downloaded from existing images available on DockerHub.




Why should I use PHP 7 instead of PHP 5.6 ?


Two reasons to this.


Firstly, since the version 2.7 of Symfony, PHP 7 is 100% supported. It was in 2015 and since then a lot of the most common bundles we can found on Symfony (FOSUserBundle, JMSSerializerBundle, ...) are working with PHP 7 too. It's therefore highly recommended to use PHP 7 too.


The second reason to use PHP 7 instead of PHP 5.6 is the huge performance gap between these two versions.


According to CloudWays, a Symfony 3 project will be much faster with PHP 7 as shown by these graphs :


PHP 5.6 graph


As you can see, with PHP 5.6, as long as we are under 50 users the servers responds fast enough, but as the number of users increased, the response time also increased. In this example 5490 ms for 246 users.


PHP 7 graph


On the other hand, with PHP 7 we almost gain 2 seconds of response time. 3093 ms for 200 users


If you want more proofs, check the complete article.




 So, where is my Dockerfile ?!


Here it is :

FROM php:7.0-apache

RUN apt-get update && apt-get install -y \
    npm \
    git \
    nodejs \
    g++ \
    pkg-config \
    build-essential \
    libmemcached-dev \
    libmemcached-tools \
    libicu-dev \
    libmcrypt-dev \
    libfreetype6-dev \
    libjpeg62-turbo-dev \
    libpng12-dev \
    libfreetype6 \
    libfontconfig \
    libxml2-dev \
    default-jre \
    vim \
    nano \
    mysql-client \
    libldap2-dev \

RUN apt-get clean

# Extension PHP
RUN docker-php-ext-install pdo pdo_mysql
RUN docker-php-ext-install intl
RUN docker-php-ext-install mbstring
RUN docker-php-ext-install bcmath
RUN docker-php-ext-install mcrypt
RUN docker-php-ext-install zip
RUN docker-php-ext-install exif
RUN docker-php-ext-install soap
RUN docker-php-ext-install opcache
RUN docker-php-ext-install iconv
RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/
RUN docker-php-ext-install gd

# APCu
RUN pecl channel-update pecl.php.net
RUN pecl install apcu
RUN echo "extension=apcu.so" > /usr/local/etc/php/conf.d/apcu.ini

# Enable PHP 7
RUN a2enmod rewrite
RUN a2enmod php7
RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf

COPY ./default-vhost.conf /etc/apache2/sites-available/
COPY ./my-vhost.conf /etc/apache2/sites-available/

RUN a2dissite 000-default.conf
RUN a2ensite default-vhost.conf
RUN a2ensite my-vhost.conf

# Composer
RUN curl -sS https://getcomposer.org/installer | php
RUN mv composer.phar /usr/local/bin/composer

# Memcached
RUN apt-get update
RUN apt-get install -y pkg-config build-essential libmemcached-dev
RUN git clone https://github.com/php-memcached-dev/php-memcached.git
RUN cd php-memcached && git checkout php7 && phpize && ./configure --disable-memcached-sasl && make && make install
RUN echo 'extension = memcached.so' > /usr/local/etc/php/conf.d/memcached.ini

RUN echo "alias ll='ls -l'" >> /root/.bashrc
RUN echo "alias la='ls -l'" >> /root/.bashrc

ENV TERM linux
WORKDIR /var/www/my-site

COPY ./docker-entrypoint.sh /
CMD /docker-entrypoint.sh


Now the virtual hosts files :


# default-vhost.conf
<VirtualHost *:80>

  Serveralias localhost
  DocumentRoot /var/www/html

  <Directory "/var/www/html">
    Allow from all
    Options +FollowSymLinks

  CustomLog /var/log/apache2/default-access.log combined
  ErrorLog /var/log/apache2/default-error.log

# my-vhost.conf
<VirtualHost *:80>

    DocumentRoot /var/www/my-site/web

    <Directory "/var/www/my-site/web">
        Allow from all
        Options +FollowSymLinks

        RewriteEngine On

        RewriteCond %{REQUEST_FILENAME} -f
        RewriteRule .? - [L]
        RewriteRule .? app.php [L]



The docker-entrypoint.sh file :



echo "Set symfony dirs permissions"
setfacl -R -m u:www-data:rwX -m u:`whoami`:rwX var/cache var/logs var/spool 
setfacl -dR -m u:www-data:rwX -m u:`whoami`:rwX var/cache var/logs var/spool

echo "Composer install"
composer install --prefer-dist

echo "Npm install"
npm install



And finally the docker-compose.yml file :


version: '2'

        context: .
        dockerfile: Dockerfile
      container_name: my-site
        VIRTUAL_HOST: my-site.local
        TZ: Europe/Paris
        - "80:80"
        - ./../my-site:/var/www/my-site
        - memcached:memcached
        - mysql:mysql
        - phpmyadmin:phpmyadmin
        - mailcatcher:mailcatcher

      image: memcached
        - "11211:11211"

      container_name: mysql
      image: mysql:5.6
         - "3306:3306"
         - MYSQL_ROOT_PASSWORD=password
        - ./config/mysql.cnf:/etc/mysql/conf.d/mysql.cnf

       image: phpmyadmin/phpmyadmin
       container_name: phpmyadmin
       hostname: phpmyadmin.local
       ports :
          - "8080:80"
          - PMA_HOST=mysql
          - PMA_USER=root
          - PMA_PASSWORD=password
          - mysql:mysql

       image : schickling/mailcatcher
       container_name: mailcatcher
          - "1080:1080"




Here are the values you have to set in your parameters.yml file.


# app/config/parameters.yml
    database_driver: pdo_mysql
    database_host: mysql # <- your mysql container name
    database_port: null
    database_user: root
    database_password: password
    database_name: my-site
    mailer_transport: smtp
    mailer_host: mailcatcher # <- your mailcatcher container name
    mailer_port: 1025
    mailer_user: null
    mailer_password: null



Now you have all the prerequisites, you just have to build your container then launch it.


$ cd /path/to/my-site
$ docker-compose build
$ docker-compose up


Your working environement is now fully functionnal. You can access your project at http://my-site.local/app_dev.php, your PhpMyAdmin at http://phpmyadmin.local:8080 and your Mailcatcher at http://localhost:1080.


I hope this gist makes your daily work more enjoyable ! laughing


Hugo Soltys

Who is talking to you ?

My name is Hugo, I'm 29 and I'm a Symfony developer since 2013. I love to create websites by myself to learn new technologies or increase my skills. I also like to share my knowledge so I created this blog. I hope you enjoy it :)