{{tag>Trusty Xenial serveur tutoriel}} ---- {{ :docker_container_engine_logo.png?200|}} ====== Monter un serveur LAMP grâce à Docker ====== [[:Docker]] permet d'installer les logiciels de son choix, dans les versions de son choix quelle que soit notre version de Linux. Pour cela il isole les logiciels qu'on souhaite utiliser les uns des autres avec chacun leurs dépendances dans des "containers". Mais il permet aussi d'éviter les inconvénients de la [[:virtualisation]] (fichiers lourds, ressources machines divisées, lenteurs, etc.).\\ C'est donc une solution extrêmement pertinente lorsqu'il s'agit de déployer une plateforme de développement (afin de reproduire n'importe quel environnement de production), ou d'une manière générale de déployer des applications ou des versions de logiciels non supportées par le système courant. De plus cela confère une portabilité très aisée et une grande souplesse à sa configuration. Nous traiterons ici de la mise en place d'un serveur [[:LAMP]] (Linux [[:Apache]] [[:MySQL]] [[:PHP]]) au moyen de Docker.\\ Pour cet exemple nous allons installer PHP 5.6 qui n'est pas disponible sur [[:Xenial]]. Nous allons considérer 2 méthodes : une simple, l'autre plus avancée.\\ La [[#méthode simple]] consiste à installer un seul container avec tout le stack [[:LAMP]].\\ Avec la [[#méthode avancée]] on installera le serveur web ([[:Apache]] et [[:PHP]]) séparément du serveur de base de données, dans 2 containers différents. C'est la méthode conseillée par [[:Docker]], qui recommande de séparer chaque processus / service dans un container différent. Cela rend effectivement notre environnement de travail extrêmement modulaire et permet par ex. de switcher de PHP 5.6 à PHP 7 ou de [[:MySQL]] à [[:MariaDB]] en un claquement de doigt ! De nombreuses images crées par la communauté sont disponibles sur le [[https://hub.docker.com/|Docker Hub]] et d'autres plus officielles sur le [[https://store.docker.com/|Docker Store]]. ===== Installation de Docker ===== Pour installer [[:Docker]] sous Ubuntu, cliquez sur **[[apt>docker.io]]** ou en ligne de commande : sudo apt install docker.io Ajoutez votre utilisateur au groupe **docker** afin de pouvoir manipuler les containers : Cette méthode pose un problème de sécurité. Il devient en effet possible d'élever les privilèges de l'utilisateur sans entrer à nouveau de mot de passe. Si vous êtes sur un serveur en production n'entrez pas cette commande et utilisez la commande **sudo docker** au lieu de **docker** pour la suite des opérations. sudo usermod -aG docker $USER Finalement **redémarrez votre ordinateur**. ===== Mise en place des répertoires de travail ===== Par défaut les modifications apportées aux fichiers d'un container ne sont pas persistantes (tout est réinitialisé à chaque lancement du container). L'intérêt de l'option **-v** (volume) de Docker est de créer une sorte de lien symbolique entre le container et le système hôte, ainsi les fichiers modifiés par le container seront persistés sur le système. Commençons donc par créer des répertoires pour le contenu que l'on souhaite modifier et conserver, en l'occurrence les fichiers du site et les bases de donnés : mkdir ~/www ~/mysql Rendons les lisibles et modifiables par Docker : chmod 777 ~/www ~/mysql Pour la suite, à vous de choisir entre les deux méthodes en fonction de vos besoins. ===== Méthode simple ===== Pour cette méthode, choisissons une image contenant le stack LAMP complet.\\ Celle-ci est basée sur [[:debian_ubuntu_comparaison|Debian Jessie]], [[:php|PHP 5]], [[:apache|Apache 2]], et [[:MySQL]] : [[https://hub.docker.com/r/lioshi/lamp/]] Lançons donc un container avec cette image : docker run -v ~/www:/var/www/html -v ~/mysql:/var/lib/mysql -p 80:80 -p 3306:3306 --restart=always lioshi/lamp L'option **-v** (volume) relie les répertoires locaux **~/www** et **~/mysql** aux répertoires **/var/www/html** et **/var/lib/mysql** de l'image Debian dans le container.\\ L'option **-p** (port) relie les ports qui nous intéressent du container aux ports de notre machine locale. Ici le port 80 (HTTP) et le port 3306 (MySQL).\\ L'option **--restart=always** permet de relancer le container à chaque démarrage de Docker (donc au démarrage de l'ordinateur). La première fois qu'on lance le container, Docker télécharge toutes les librairies nécessaires, ce qui prend un peu de temps. Et c'est tout ! À partir de là notre serveur tourne. Les bases de données seront sauvegardées dans notre répertoire **~/mysql**.\\ [[:PhpMyAdmin]] est accessible sur [[http://localhost/phpmyadmin]]\\ Avec cette image Docker l'utilisateur par défaut pour les bases de données devrait être **admin** avec le mot de passe **admin** (hôte **localhost**). On peut mettre les fichiers de son site dans notre répertoire **~/www**. On pourra ensuite y accéder sur [[http://localhost]] ===== Méthode avancée ===== Pour cette méthode nous avons besoin d'une image pour [[Apache]] avec [[:PHP]], une image pour [[:MySQL]] et une image pour [[:phpMyAdmin]]. * Pour **Apache/PHP** nous allons choisir [[https://hub.docker.com/r/lavoweb/php-5.6/|celle-ci]], basée sur l'[[https://hub.docker.com/r/library/php/|image fournie officiellement par PHP]], mais à laquelle on a ajouté quelques librairies bien utiles (**gd**, **zip**, **mcrypt**...). * Pour **MySQL**, nous pouvons prendre l'[[https://hub.docker.com/_/mysql/|image fournie officiellement par MySQL]], en version 5.5 (une version un peu ancienne). * Pour **phpMyAdmin**, nous pouvons aussi choisir l'[[https://hub.docker.com/r/phpmyadmin/phpmyadmin/|image officielle]]. Pour la suite nous allons nous servir d'un outil bien pratique pour lancer plusieurs containers en évitant les lignes de commandes à rallonge : **docker-compose**.\\ Il faut tout d'abord l'installer : sudo apt install docker-compose Nous allons ensuite créer un fichier **docker-compose.yml** dans lequel nous allons définir notre environnement : version: '2' services: web: image: lavoweb/php-5.6 ports: - "80:80" volumes: - ~/www:/var/www/html links: - db:db db: image: mysql:5.5 volumes: - ~/mysql:/var/lib/mysql ports: - "3306:3306" environment: - MYSQL_ROOT_PASSWORD=root myadmin: image: phpmyadmin/phpmyadmin ports: - "8080:80" links: - db:db Les **services** sont des containers.\\ **web**, **db** et **myadmin** sont les noms qu'on décide de leur donner. Ces noms sont utilisés pour créer des liens - **links** - entre les différents containers. Par ex. **db:db** signifie que notre container **db** (du nom de notre container MySQL) correspondra à l'hôte **db** dans notre container **web**. Pour se connecter au serveur [[:MySQL]] il faudra donc entrer **db** comme nom d'hôte.\\ On peut également passer des variables d'environnements à nos containers. Ici nous définissons le mot de passe de l'utilisateur [[:MySQL]] **root** comme étant **root**.\\ De la même manière que l'options **-v** de la ligne de commande, le paramètre **volumes** relie les répertoires locaux **~/www** et **~/mysql** aux répertoires **/var/www/html** de l'image Apache/PHP et **/var/lib/mysql** de l'image MySQL dans nos containers.\\ Et le paramètre **ports** de la même manière que l'options **-p**, relie les ports qui nous intéressent de nos containers aux ports de notre machine locale. Ici le port 80 (HTTP) et le port 3306 (MySQL). Une fois ce fichier mis en place on peut lancer tous nos containers avec un simple docker-compose up Il faut attendre une peu que les images soient téléchargées, et c'est tout ! Notre serveur est en route. De la même manière qu'avec la [[#méthode simple]] les bases de données seront sauvegardées dans notre répertoire **~/mysql**.\\ [[:PhpMyAdmin]] est cette fois accessible sur le port 8080 : [[http://localhost:8080]]\\ Et cette fois l'utilisateur par défaut pour les bases de données sera **root** avec le mot de passe **root** (hôte **db**). On peut mettre les fichiers de notre site dans notre répertoire **~/www**. On pourra ensuite y accéder sur [[http://localhost]]. Pour passer de MySQL 5.5 à MySQL 5.7 par ex. il suffit de remplacer **image: mysql:5.5** par **image: mysql:5.7** et de relancer **docker-compose up**. ===== Aller plus loin ===== ==== Configuration de PHP, d'Apache et de MySQL ==== Pour ajuster les configurations des différents services, le mieux est aussi d'utiliser la fonctionnalité **volume** (qu'on peut utiliser comme des liens symboliques entre les containers et l'exterieur, aussi bien pour des répertoires que pour des fichiers).\\ Ainsi on peut facilement éditer ou modifier les fichiers de config sur notre système. C'est très facile, à condition de savoir où doivent se trouver ces fichiers de config sur nos images.\\ Pour stocker nos configs personnalisées on peut créer un répertoire : mkdir ~/config Puis on créé notre fichier **~/config/php.ini** qui contient seulement les paramètres que l'on souhaite modifier, par ex. : short_open_tag = On error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT display_errors = On max_execution_time = 600 memory_limit = 1024M post_max_size = 1024M upload_max_filesize = 5G max_file_uploads = 200 allow_url_fopen = On date.timezone = "Europe/Paris" Finalement on relie ce fichier avec le paramètre **volume**, par ex. pour l'image de notre [[#méthode simple]] : -v ~/config/php.ini:/etc/php5/apache2/conf.d/90-custom.ini Ainsi on garde la configuration par défaut de l'image mais on ajoute notre config customisée en dernier, afin d'écraser les valeurs prédéfinies (**conf.d/90-custom.ini**, ces fichiers sont chargés par ordre alphabétique).\\ Si on préfère on peut aussi écraser complètement le fichier **/etc/php5/apache2/php.ini**. Pour Apache on peut si on le souhaite définir une liste de VirtualHosts (chacun dans un fichier **.conf** dans le répertoire **~/config/virtualhosts**) : -v ~/config/virtualhosts:/etc/apache2/sites-enabled ==== Création de Dockerfiles personnalisés ==== Le [[https://hub.docker.com/|Docker Hub]] et le [[https://store.docker.com/|Docker Store]] fournissent une quantité impressionnante d'images toutes faites. Mais parfois il est nécessaire de modifier ces images, par ex. pour installer une extension exotique à PHP. La plupart des images disponibles sur ces hubs fournissent un fichier [[docker#automatisation_avec_un_dockerfile|Dockerfile]]. [[https://hub.docker.com/r/lioshi/lamp/~/dockerfile/|exemple]].\\ Ce fichier est une liste d'instructions qui permettent de construire une image. Il définit une image de base (par ex. Debian:telle_version) et contient ensuite une série de commandes telles que **apt install ...**.\\ On peut également créer ce fichier sur notre machine pour créer une image Docker qui corresponde exactement à nos besoin (pour plus de facilité on peut évidemment partir d'un Dockerfile existant). Voici un site qui explique plus en détail comment s'y prendre : [[http://putaindecode.io/fr/articles/docker/dockerfile/]]. Une fois notre [[docker#automatisation_avec_un_dockerfile|Dockerfile]] créé, par ex. à l'emplacement **~/webserver/Dockerfile**, on peut construire notre image avec la commande : docker build -t apache-php5.6 ~/webserver/ après quoi on peut lancer notre image nommée **apache-php5.6** dans un container : docker run -v ~/www:/var/www/html -p 80:80 apache-php5.6 ==== Commandes utiles ==== Certaines commandes sont très utiles pour manipuler nos images et nos containers : \\ \\ docker ps -a Lister les containers. Pour chaque container on récupère ainsi un id comme **fc2ff39a9270** \\ \\ docker rm fc2 Supprimer un container. les 3 premiers caractères de l'id suffisent à l'identifier. \\ \\ docker images Lister les images installées. On récupère aussi leurs ids. \\ \\ docker rmi e15 Supprimer une image dont l'id commence par **e15**. \\ \\ docker exec -ti fc2 bash Se connecter au terminal d'un container dont l'id commence par fc2 pour en explorer les entrailles. Souvenez-vous que les modifications disparaîtront au prochain démarrage du container. ===== Voir aussi ===== Pour des éventuelles questions, suggestions, retour, n'hésitez pas à participer à [[https://forum.ubuntu-fr.org/viewtopic.php?pid=21727074|ce sujet]] sur le forum. ---- //Contributeur principal : [[:utilisateur:krodelabestiole|krodelabestiole]]//