Afin de préparer la migration technique d’un site web, j’ai eu besoin de reconstruire un environnement à l’identique de la production.
Hébergé sur un serveur Linux, ce site est propulsé par Apache 2.2, PHP 5.6 et MySQL 5.5.
C’était l’occasion parfaite pour découvrir Docker. Une première étape consiste à décomposer cette plateforme LAMP en conteneurs Docker ayant chacun leur responsabilité. Voici les 3 conteneurs identifiés :
- site : conteneur Apache et PHP sur lequel les pages PHP du site sont déployées
- database : conteneur MySQL hébergeant la base de données utilisée par les pages PHP
- phpmyadmin : conteneur dédié à l’outil d’administration de base de données phpMyAdmin
Pour orchestrer le démarrage des conteneurs, gérer leur configuration et définir leurs interactions, l’utilisation de l’outil Docker Compose paraissait évidente.
Dans ce billet, vous trouverez le fichier docker-compose correspondant, un Dockerfile personnalisant l’image officielle php:5.6-apache, les lignes de commandes démarrant les conteneurs sous MacOSX et alimentant la base à partir d’un script SQL.
Configuration Docker Compose
Le fichier docker-compose.yml décrit en YAML les 3 conteneurs présentés en introduction :
site: build: site ports : - "80:80" volumes: - /Users/arey/dev/mysite/www:/var/www/html/ links: - database phpmyadmin: image: corbinu/docker-phpmyadmin ports : - "8080:80" environment: - MYSQL_USERNAME=root - MYSQL_PASSWORD=password links: - database:mysql database: image: mysql:5.5 ports: - "3306:3306" environment: - MYSQL_ROOT_PASSWORD=password - MYSQL_DATABASE=mysite - MYSQL_USER=mysite - MYSQL_PASSWORD=password
Voici quelques explications :
- Le conteneur site est créé à partir d’un Dockerfile que nous étudierons par la suite. Le port 80 d’Apache est exposé à l’hôte sur le port 80. Le répertoire /Users/arey/dev/mysite/www contenant les pages PHP est monté dans le répertoire /var/www/html/ correspondant au répertoire home d’Apache. Enfin, ce conteneur dépend du conteneur database.
- Le conteneur database utilise l’image officielle mysql:5.5. Le port par défaut 3306 de MySQL est exposé aux autres conteneurs et à l’hôte. La base de données mysite est crée au démarrage du conteneur. Les credentials de l’administrateur et d’un utilisateur sont paramétrés.
- Le conteneur phpmyadmin utilise l’image corbinu/docker-phpmyadmin. Il se connecte au conteneur database en utilisant les credential définis dans le conteneur database. L’IHM de phpMyAdmin est accessible depuis un navigateur sur le port 8080.
Dockerfile
Créé dans le sous-répertoire site, le Dockerfile suivant permet de construire une image personnalisée Docker à partir de l’image officielle php:5.6-apache :
FROM php:5.6-apache # Install PDO MySQL driver # See https://github.com/docker-library/php/issues/62 RUN docker-php-ext-install pdo mysql RUN docker-php-ext-install pdo mysqli # Workaround for write permission on write to MacOS X volumes # See https://github.com/boot2docker/boot2docker/pull/534 RUN usermod -u 1000 www-data # Enable Apache mod_rewrite RUN a2enmod rewrite
Les commentaires sont suffisamment explicites.
Si besoin, la commande RUN a2emod permet d’activer d’autres modules Apache.
Démarrer les conteneurs
Sur MacOSX, l’utilisation de Docker passe par la VM Boot2Docker. L’installation de VirtualBox est un pré-requis à l’utilisation de boot2docker.
Le gestionnaire de package Homebrew permet d’installer Docker et boot2docker en quelques lignes :
brew install boot2docker brew install docker
La commande boot2docker init permet de télécharger et d’installer la VM boot2docker-vm.
Et les commandes ci-dessous permettent de démarrer la VM et d’obtenir son adresse IP.
boot2docker start $(boot2docker shellinit 2> /dev/null) boot2docker ip
Le téléchargement des images, la construction de l’image site et le démarrage des 3 conteneurs ne demandent que 2 lignes de commande :
docker-compose build docker-compose up
Une fois démarrés, phpMyAdmin est accessible depuis votre hôte sur l’adresse http://192.168.59.104:8080/index.php (renseigner l’adresse IP obtenue précédemment)
Chargement de la base de données
Le site web ne peut pas fonctionner avec une base vide. La dernière étape consiste donc à charger la base MySQL à partir d’un export de la base de données de production.
Une première solution est d’utiliser phpMyAdmin.
Une seconde solution consiste à installer un client MySQL.
Une 3ième est d’utiliser un conteneur docker doté d’un client MySQL :
docker run -v /Users/arey/dev/mysite/sql:/sql --link mysite_database_1:mysql -it arey/mysql-client -h mysql -ppassword -D mysite -e "source /sql/export.sql"
Voici quelques explications :
- Le répertoire /Users/arey/dev/mysite/sql contient le script sql
- mysite_database_1 correspond au nom de l’image docker attribué par docker-compose
- L’image arey/mysql-client est publiée sur Docker Hub. Je l’ai créé spécifiquement pour ce type de besoin. Son code source est sur GitHub.
Conclusion
En 2 fichiers textes et une dizaine de lignes de commandes, vous disposerez d’une plateforme LAMP opérationnelle. Cela s’avère très pratique pour tester des montées de version de base de données, de CMS ou bien encore de PHP. Elle peut également être utilisée lors de la phase de développement.
Une fois mon projet de migration terminé, j’ai archivé ces 2 fichiers dans un repo git privé sur BitBucket puis j’ai supprimé les images téléchargées, libérant ainsi autant d’espace sur mon SSD.
Références :
Très bon article. Merci beaucoup !
Bonjour,
j’ai mis au point mes containers mais est il possible d’avoir le meme docker-compose dans plusieurs dossier (projets) ?
pour le moment j’ai souvent une erreur de conflit (un container ayant dejà le meme nom)
Il y a t’il une solution?
merci
Sébastien, d’après la doc https://docs.docker.com/compose/compose-file/, tu peux nommer ton image à l’aide du paramètre image.
Sympa, ça m’a bien aidé.
Par contre j’ai pas mal galéré sur le pdo_mysql. En effet
ne marche pas, ou plus.
Et à en croire https://github.com/docker-library/php/tree/master/5.6
C’est plutôt ça qu’il faut mettre :
Qui a fonctionné.
Cordialement.
Merci Etienne pour ce retour. Saurais-tu me dire si c’est le passage à MySQL 5.6 qui a entrainé le problème que tu évoques et quels étaient les symptômes ?
Le symptôme était l’absence de pdo_mysql dans phpinfo(). Quant à la cause, je n’en sais rien.
Bonjour,
J’ai le même soucis que Étienne, mais je n’arrive pas à le résoudre.
Mon connecteur pdo_mysql n’est toujours pas présent malgré mes tentatives acharnées… Et j’ai bien suivi ce tutoriel ^^
Quelqu’un dispose d’une solution ?
Bonjour Aleo,
Je n’ai pas eu le temps de tester la solution proposée par Etienne. A ce que je comprends de ton commentaire, elle ne fonctionne pas dans ton cas. Peux-tu me le confirmer ?
Merci
Antoine
Bonjour Antoine,
J’ai bel et bien testé la version proposé par Etienne, et le problème persiste.
Bonjour à tous,
Lorsque je fais un insert avec PDO, j’ai deux ligne en BDD ?!
Quand je passe par le phpmyadmin, je n’ai pas le soucis…
Une idée ?