keyboard

Hugo Soltys

Symfony developer

Since 2013

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

Posted on by Hugo - 795 views - 0 comment


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 7, Apache, Composer...). 


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.

 

SUMMARY

 

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.

 

SOME FACTS 

 

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.

 

THE FILES

 

 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 \
    wget

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

# ALIASES
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
  </Directory>

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

</VirtualHost>
# 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]
    </Directory>

</VirtualHost>

 

The docker-entrypoint.sh file :

#!/bin/bash

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

apache2-foreground

 

And finally the docker-compose.yml file :

version: '2'

services:
    my-site:
      build:
        context: .
        dockerfile: Dockerfile
      container_name: my-site
      environment:
        VIRTUAL_HOST: my-site.local
        TZ: Europe/Paris
      ports:
        - "80:80"
      volumes:
        - ./../my-site:/var/www/my-site
      links:
        - memcached:memcached
        - mysql:mysql
        - phpmyadmin:phpmyadmin
        - mailcatcher:mailcatcher

    memcached:
      image: memcached
      ports:
        - "11211:11211"

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

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

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

 

CONFIGURE SYMFONY

 

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

# app/config/parameters.yml
parameters:
    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

 

LAUNCH MY CONTAINER

 

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.


Hugo Soltys

My name is Hugo, I'm 25 and I'm a Symfony developer since 2013. I love to create websites by myself to learn new technologies or increase my skills.
I love movies, books, music and video games. I also like to drink a few beers with my friends. I'm from Lille (France) and I currently work as Symfony developer at Decathlon since 2016. Before that, I worked as Symfony developer for the IT Room company, in Roubaix, France.