Cet article explique comment mettre en place une application Symfony avec Docker. L'application qui va nous servir de test possède comme couche technique : PHP 5.6, Apache 2, Symfony 3, MySQL 5.7 et phpMyAdmin. Toutes les procédures d'installations décrites dans l'article se font sur Ubuntu 15.10.
Note de l'auteur
Le code contenu dans cet article peut être trouvé sur github.
D'un point de vue technique si vous le pouvez, je vous recommande plutôt de suivre mon article plus récent car la couche technique utilisée est plus performante (PHP-FPM avec le module Apache mod_proxy_fcgi à la place de PHP avec le module Apache mod_php). Si vous ne connaissez pas PHP-FPM, vous utilisez probablement PHP avec le module Apache mod_php (méthode qui est utilisée dans cet article ici). Avant de poursuivre votre lecture, je vous invite à aller lire mon article sur comment mettre en place un environnement Apache / PHP-FPM. Vous trouverez les différents avantages et inconvénients de chaque méthode.
Installation de Docker
Prérequis
Docker a besoin au minimum du kernel Linux 3.10. Pour vérifier le numéro de version de votre kernel, tapez la commande :
uname -r
Une fois la vérification faite, on commence par mettre à jour la liste des dépôts :
sudo apt-get update
Il faut s'assurer que APT fonctionne avec HTTPS et que les certificats CA sont bien installés :
sudo apt-get install apt-transport-https ca-certificates
On peut ensuite rajouter une clé GPG :
sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
Ouvrez le fichier /etc/apt/sources.list.d/docker.list. Il faut supprimer tout le contenu de ce fichier. S'il n'existe pas, il faut le créer. Ensuite, il faut y ajouter une ligne en fonction de la version de votre Ubuntu (voir le site officiel). Par exemple pour la version 15.10 :
deb https://apt.dockerproject.org/repo ubuntu-wily main
Puis sauvegardez le fichier. Vous pouvez maintenant relancer une mise à jour des dépôts :
sudo apt-get update
Purgez les anciens dépôts s'ils existent :
sudo apt-get purge lxc-docker
Vérifiez que APT utilise les bons dépôts :
sudo apt-cache policy docker-engine
Pour cette version d'Ubuntu, il est recommandé d'installer le packet linux-image-extra :
sudo apt-get install linux-image-extra-$(uname -r)
Installation de Docker Engine
Pour installer Docker, tapez la commande :
sudo apt-get install docker-engine
Démarrez le service Docker :
sudo service docker start
Pour tester si l'installation s'est effectuée correctement, vous pouvez lancer le programme de test hello-world :
sudo docker run hello-world
Pour éviter de devoir taper à chaque fois sudo devant les commandes docker, il faut faire quelques actions supplémentaires. Créez un groupe d'utilisateur docker et ajoutez-y votre login :
sudo usermod -aG docker votre_login
Ensuite déconnectez-vous de votre session puis reconnectez-vous. Lors de son démarrage, le service docker va donner les accès de lecture et d'écriture au groupe docker (dont vous faites parti). Maintenant si vous tapez une commande docker sans le sudo, la commande peut s'exécuter correctement. Par exemple :
docker run hello-world
Installation de Docker Compose
Docker Compose est un outil qui permet de configurer ses conteneurs via un fichier yml. On évite ainsi de taper X commandes docker.
Allez sur la page github de Docker compose, et suivez les instructions pour installer la bonne version. Pour la version 1.6.2 :
curl -L https://github.com/docker/compose/releases/download/1.6.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
Puis testez l'installation :
docker-compose --version
«Dockerisation » de l'application Symfony
Objectif
Attention, ici je ne vais pas expliquer comment fonctionne Docker. Si vous débutez, je vous invite à aller lire la documentation bien fournie sur le site officiel.
On va découper l'application en 5 conteneurs :
1) Un conteneur web : PHP + Apache.
2) Un conteneur base de données : MySQL.
3) Un conteneur phpMyAdmin.
4) Un conteneur donnée qui va stocker le projet Symfony.
5) Un conteneur donnée qui va stocker les données de la base de données.
Pour cela, on va commencer par créer les images qui vont être utilisées pour initialiser ces conteneurs.
Création des images
On crée un répertoire Docker dans lequel on crée un répertoire par image. Chaque répertoire va contenir le Dockerfile de l'image. C'est visible ici sur github.
Image n°1
FROM ubuntu:15.10
MAINTAINER Christophe Meneses
RUN echo "deb http://ppa.launchpad.net/ondrej/php5-5.6/ubuntu wily main" | tee -a /etc/apt/sources.list \
&& apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 4F4EA0AAE5267A6C \
&& apt-get update
RUN apt-get install -y apache2
RUN apt-get install -y php5-common php5-cli libapache2-mod-php5
RUN apt-get install -y php5-mcrypt php5-mysql php5-apcu php5-curl php5-intl php5-xdebug
ADD php-custom.ini /etc/php5/apache2/conf.d
ADD 20-xdebug.ini /etc/php5/apache2/conf.d
ADD php-custom.ini /etc/php5/cli/conf.d
ADD 20-xdebug.ini /etc/php5/cli/conf.d
RUN php -r "readfile('https://getcomposer.org/installer');" | php -- --install-dir=/usr/local/bin --filename=composer \
&& chmod +x /usr/local/bin/composer
RUN apt-get install -y git
EXPOSE 80
WORKDIR /etc/php5
CMD /usr/sbin/apache2ctl -D FOREGROUND
Image n°2
FROM mysql:5.7
MAINTAINER Christophe Meneses
Image n°3
FROM phpmyadmin/phpmyadmin:4.6.0-1
MAINTAINER Christophe Meneses
Image n°4
FROM ubuntu:15.10
MAINTAINER Christophe Meneses
VOLUME /var/www/html
Image n°5
FROM ubuntu:15.10
MAINTAINER Christophe Meneses
VOLUME /var/lib/mysql
Une fois les fichiers Dockerfile prêts, il faut demander à Docker de créer les images. Pour cela, mettez-vous dans le répertoire Docker et lancez à la suite les commandes ci-dessous :
docker build -t cmeneses/apache_php:2-5.6 ./apache2_php5.6/
docker build -t cmeneses/data_application ./data_application/
docker build -t cmeneses/data_mysql ./data_mysql/
docker build -t cmeneses/mysql:5.7 ./mysql5.7/
docker build -t cmeneses/phpmyadmin:4.6 ./phpmyadmin4.6/
Pour lister les images disponibles sur votre machine, tapez la commande :
docker images
Les images crées précédemment doivent apparaitre :
REPOSITORY TAG IMAGE ID CREATED SIZE
cmeneses/data_application latest ab7eb6a8ba30 6 days ago 135.9 MB
cmeneses/phpmyadmin 4.6 5c0b3987b89c 6 days ago 57.57 MB
cmeneses/mysql 5.7 2cf6f84ca859 6 days ago 361.2 MB
cmeneses/data_mysql latest 356bb880ef1e 6 days ago 135.9 MB
cmeneses/apache_php 2-5.6 4435d4b78463 6 days ago 298 MB
Création du fichier docker-compose.yml
Le fichier docker-compose.yml est à créer à la racine du projet Symfony. Il va contenir toute la configuration des conteneurs du projet et leurs relations. Ainsi, on pourra lancer la construction de l'ensemble des conteneurs avec une seule commande.
version: '2'
services:
test_application:
image: cmeneses/data_application
volumes:
- /xxx/Test-Docker-Sf/Symfony:/var/www/html
test_data:
image: cmeneses/data_mysql
volumes:
- /xxx/Test-Docker-Sf/Data:/var/lib/mysql
test_database:
image: cmeneses/mysql:5.7
ports:
- 60001:3306
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: test
MYSQL_USER: test
MYSQL_PASSWORD: test
volumes_from:
- test_data
test_phpmyadmin:
image: cmeneses/phpmyadmin:4.6
ports:
- 60002:80
links:
- test_database:db
environment:
- PMA_USER=root
- PMA_PASSWORD=root
test_web:
image: cmeneses/apache_php:2-5.6
ports:
- 60000:80
environment:
XDEBUG_CONFIG: remote_host=172.22.0.1
volumes_from:
- test_application
links:
- test_database
working_dir: /var/www/html
Les adresses des volumes sur la machine hôte doivent être modifiées (c'est en fonction de votre installation). Le reste est à personnaliser en fonction de vos besoins.
Lancement de l'application
Placez-vous dans le dossier du projet Symfony, et lancez la commande :
docker-compose build
Cette commande va construire l'ensemble du projet en lisant le fichier docker-compose.yml. Comme on a déjà construit nous-même les images à l'étape précédente, la commande va nous dire qu'il n'y a plus rien à faire.
Il ne reste plus qu'à démarrer l'ensemble des containers :
docker-compose up
Voilà le projet est lancé ! Cependant avant de pouvoir accéder à l'application Symfony, il peut être nécessaire de lancer un composer install pour télécharger tous les vendors. Pour cela, on doit d'abord récupérer l'identifiant de notre conteneur test_web. Tapez la commande :
docker ps
Dans les lignes affichées, repérez le container test_web et récupérez son identifiant :
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
22e642982db4 cmeneses/apache_php:2-5.6 "/bin/sh -c '/usr/sbi" 6 days ago Exited (137) 6 days ago symfony_test_web_1
Vous pouvez ainsi lancer une commande à l'intérieur de celui-ci. Si vous regardez bien le fichier docker-compose.yml, on a indiqué un répertoire de travail (working_dir). Cela veut dire que toute les commandes seront lancées directement dans /var/www/html, c'est à dire à la racine du projet Symfony. On peut donc aisément utiliser composer (ou quelle que soit la commande Symfony) :
docker exec 22e642982db4 composer install
docker exec 22e642982db4 php bin/console cache:clear
L'application Symfony est accessible à l'adresse http://localhost:60000/web/app_dev.php, phpMyAdmin est accessible à l'adresse http://localhost:60002, MySQL est accessible à l'adresse http://localhost:60001.
Vous pouvez également lancer le projet en tâche de fond. Il faut rajouter l'option -d :
docker-compose up -d
Pour arrêter l'ensemble des conteneurs du projet, il faut taper la commande :
docker-compose stop
Modifications au niveau de Symfony
Il reste quelques actions à faire pour que l'application fonctionne correctement.
Pour que Symfony est accès à la base de données, il faut indiquer le nom du conteneur de la base de données dans le fichier parameters.yml. Par exemple ici, on doit indiquer test_database :
database_host: test_database
Si vous essayer d'accéder à app_dev.php, vous aurez l'erreur suivante : You are not allowed to access this file. Check app_dev.php for more information.. La solution est de commenter les lignes ci-dessous dans app_dev.php :
if (isset($_SERVER['HTTP_CLIENT_IP'])
|| isset($_SERVER['HTTP_X_FORWARDED_FOR'])
|| !in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1', 'fe80::1', '::1'))
) {
header('HTTP/1.0 403 Forbidden');
exit('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.');
}
C'est terminé ! Normalement tout est OK maintenant pour commencer les développements.
Autres commandes utiles
Vous pouvez supprimer tous les conteneurs d'un coup :
docker rm $(docker ps -a -q)
Vous pouvez supprimer toutes les images d'un coup :
docker rmi $(docker images -q)
Version
Cet article a été testé avec :
Ubuntu : 15.10
Docker Engine : 1.11
Docker Compose : 1.6
Symfony : 3.0
PHP : 5.6
MySQL : 5.7
phpMyAdmin : 4.6