====== Utilisation de Docker====== ====0. Remarques==== ===Résumé=== En plus de la machine virtuelle nous allons utiliser docker pour séparer les différentes applications. Le but de ce TP est d'installer 5 conteneurs : - un docker ''mysql'' qui servira de base de donnée; - un docker ''phpmyadmin'' pour piloter cette base; - un docker ''nginx'' qui sera le serveur web de base et servira aussi en tant que proxy inverse en assurant la répartition des requêtes dans les différents conteneurs; - un docker ''owncloud'' qui servira de serveur de partage de fichiers - et éventuellement un docker ''onlyoffice'' qui permettra l'édition en ligne des fichiers. ===Objectifs=== * Apprendre à manipuler les dockers. * Savoir configurer les dockers via les options de lancement. * Savoir configurer les dockers en partageant certains fichiers de configurations avec la machine hôte. * Savoir configurer les dockers en modifiant l'image par un //Dockerfile//. * Gérer les réseaux interne des dockers. ===Notation=== Nous allons noter ces TPs en fonction du travail accompli. Pour cela, il faut impérativement noter votre binôme et l'adresse IP de votre VM dans les cases prévues de tomuss : ''BinomeTpDocker'' et ''IPTpDocker''. ==Première séance== Nous vous proposons un fichier de test qui sera utilisé pour vérifier votre avancement. Ce fichier est {{ :cloud:2018:test.zip |ici}}. C'est un script python. La version actuelle a été testée et fonctionne sur l'image des VMs utilisées, le fichier à exécuter s'appelle ''verif.py''. Il vérifie pour le moment les dockers jusqu'à la fin de la partie IV (sans la partie cachée). ==Seconde séance== Le TP sera noté de la même manière. Vous devez aller le plus loin possible, le script sera passé pour la plupart d'entre vous le samedi 17/11 vers 14h. Pour les étudiants en 1/3 temps, ce script sera réutilisé samedi soir (après 22h). Comme pour la première séance, il sera possible d'améliorer le travail si vous terminez le TP avant le prochain TP de l'UE (7/12). La note obtenue alors sera inférieure à 11/20. Les notes sont en ligne sur [[https://tomuss.univ-lyon1.fr|tomuss]]. Le script utilisé est {{ :cloud:2018:test2.zip |ici}}. Comme il faut étreindre les dockers entre la première partie et le compose, il est déconseillé de tout tester en une seule fois. ## pour tester la fin de la première partie $./verif owncloud ## pour tester la partie compose $./verif compose Attention, la case ''ResultTP2-Owncloud'' contient la valeur obtenue par le script moins 9 (les 9 premiers points qui étaient déjà vérifié dans le premier TP). Le système de test du login a un bug. Il arrive assez souvent que le login est rejeté car //owncloud// considère que la série des action a faire pour se connecter n'a pas été respectée. Si votre le test donne : OK un serveur web semble répondre à l'adresse http://192.168.77.18/ OK http://192.168.77.18/ semble un site owncloud Not OK Le login ne semble pas possible ici http://192.168.77.18//login la réponse est --2018-11-21 14:19:44-- http://192.168.77.18/login Connecting to 192.168.77.18:80... connected. HTTP request sent, awaiting response... HTTP/1.1 412 Precondition failed Server: nginx/1.15.6 Date: Wed, 21 Nov 2018 14:19:44 GMT Content-Type: application/json; charset=utf-8 Content-Length: 31 Connection: keep-alive Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-cache, must-revalidate Pragma: no-cache Content-Security-Policy: default-src 'none';manifest-src 'self';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self';connect-src 'self';media-src 'self' X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block X-Robots-Tag: none X-Frame-Options: SAMEORIGIN X-Download-Options: noopen X-Permitted-Cross-Domain-Policies: none 2018-11-21 14:19:44 ERROR 412: Precondition failed. OK On semble pouvoir se connecter en tant qu'admin Not OK Je ne trouve pas l'utilisateur admin Not OK On ne trouve pas le module calendar Not OK On ne peut pas se déconnecter l'url est http://192.168.77.18/ Not OK Onlyoffice ne semble pas fonctionner (et on compte 3 fois) Not OK Onlyoffice ne semble pas fonctionner (et on compte 3 fois) Not OK Onlyoffice ne semble pas fonctionner (et on compte 3 fois) Il faut patienter et recommencer plus tard. De même, //owncloud// se mettant en place lentement, il est conseillé de ne pas lancer le script peut de temps après le démarrage des dockers. ===Avant de commencer=== Vous devez détruire vos VMs créées la dernière fois (sauf cas particuliers). À partir de maintenant, merci de ne pas faire de //snapshot// de vos machines, normalement, vous conservez dans vos rapports les commandes nécessaires au bon fonctionnement du TP. * **Créez une VM** par groupe : - basée sur le snapshot ''snap-docker-ready'' - avec le flavor ''m1-small'' - avec une clef ssh **dont vous déposez la clef secrète dans la case ''clefTpDocker'' de [[http://tomuss.univ-lyon1.fr/|tomuss]]** ====I. Installation d'un premier docker : mysql==== Comme pour beaucoup de serveurs connus, il existe plusieurs images qui permettent l'installation de //mysql// très simplement. * Recherchez la liste des dockers fournissant ''mysql'', (commande ''docker search'') vous verrez qu'ils sont classés par défaut grâce à un système de recommandation via des étoiles. Quels sont les 3 mieux notés ? * Recherchez de la même manière sur le site [[https://store.docker.com/|docker store]]. Ce site donne plus de détails notamment les différentes versions pour une image, les ''Dockerfile''... Il faut savoir reconnaître rapidement la qualité d'une image, dans l'exemple de //mysql// vous avez 2 possibilités (nous excluons mariadb)((//mariadb// est un fork de //mysql// qui est apparu après le rachat de l'entreprise par la firme oracle, il est très proche de //mysql// et nous ne l'utiliserons pas ici)). : - [[https://store.docker.com/images/mysql-enterprise-server|l'image officielle de mysql par l'entreprise oracle]]; - [[https://store.docker.com/images/mysql|l'image de mysql par l'entreprise docker]]. La documentation de la seconde est beaucoup plus fournie et elle semble proposer un grand nombre d'options de configuration, c'est cette dernière que vous allez choisir. * Quelles sont les versions proposées et comment reconnait-on la dernière ?\\ * Sur quelle distribution est basée la version ''5'' de mysql ? Regardez les Dockerfiles * Téléchargez l'image de la version 5.7.23 (''docker pull ...'') * Vérifiez que l'image est bien téléchargée, son nom et son tag. * Lancez un premier docker basé sur cette image dont : - le nom est ''docktest''; - le //hostname// est ''test''; - avec un mot de passe //root// aléatoire. Notez le mot de passe de l'administrateur. Lors du lancement un grand nombre d'informations sont affichées. En fait, par défaut le lancement bloque le terminal et affiche tous les résultats de la commande. Parmi ces derniers vous pouvez noter la ligne ''GENERATED ROOT PASSWORD: ...'' qui contient le mot de passe administrateur de la base. Dans la suite, vous utilisez sans doute l'option ''-d'' pour lancer le docker de manière détachée, les informations ne seront plus affichées, mais conservées et disponible via la commande ''docker log ...''. * Grâce à la commande ''docker inspect ...'' trouvez l'adresse attribuée au docker * Pouvez-vous vous connecter sur le serveur mysql avec la commande ''telnet'' (le port par défaut est 3306). Il est toujours possible d'installer le client //mysql// sur votre VM, mais ici, on va utiliser celui qui se trouve dans le docker. En effet, on peut toujours ajouter un processus au conteneur via la commande ''docker exec ...'' * En utilisant la commande docker exec -it NOMDUDOCKER mysql -u root -pMOTDEPASSE connectez-vous au serveur //mysql//. * Exécutez un shell bash dans le docker (commande ''docker exec -it ...'') et créer un fichier à la racine ''/toto'' à la racine du docker contenant ''coucou''. * Sortez du docker et essayez de retrouver le fichier sur la VM. Pour cela, vous pouvez utiliser ''docker inspect ...'' notamment la partie ''Data''. Que représentent les répertoires ''MergedDir'' et ''UpperDir'' et ''LowerDir'' ?((il vaut mieux être root pour cette question : ''sudo su'')) ===Partage de volumes=== //mysql// est une base de données qui stocke ces données dans le répertoire ''/var/lib/mysql''. Dans la configuration actuelle, ce répertoire est interne au docker et difficile d'accès. Cela peut poser des problèmes si vous souhaitez changer le docker sans perdre les données stockées. Pour éviter cela, vous allez donc recréer le docker en partageant le répertoire de stockage avec la machine hôte. Pour cela il faut utiliser l'option ''-v'' du ''docker run''. * Détruisez le docker ''docktest''. * Recréez un docker basé sur mysql 5.7.23 dont : - le nom est ''docktest''; - le //hostname// est ''test''; - **le mot de passe //root// est ''passbdd''**; - **qui partage le répertoire ''/var/lib/mysql'' du docker avec le répertoire ''/home/ubuntu/docker/datatest/'' de la VM**. * Après la fin du démarrage du docker (qui prend un peu de temps) listez le contenu du fichier ''/home/ubuntu/docker/datatest/'' * Créez une base de données en exécutant la commande mysql -u root -ppassbdd -e 'CREATE DATABASE MABASE;' dans le docker * Relistez le même répertoire, quelle est la différence ? ====II. Gestion des adresses et installation d'une interface à mysql : phpMyAdmin==== //mysql// n'est qu'un serveur de base de donnée, on ne peut l'utiliser que via des commandes SQL. Pour simplifier son utilisation, on ajoute en général une interface comme le logiciel //phpMyAdmin//. C'est une interface web permettant simplement de faire la plupart des opérations sur le serveur. Il est basé sur un code en //php// et donc un serveur capable de l'interpréter. * Peut-on ajouter //phpMyAdmin// au docker mysql pour former un docker avec le serveur et l'interface. Si oui pourquoi ne le fait-on pas ? Vous allez utiliser le [[https://hub.docker.com/r/phpmyadmin/phpmyadmin/|docker phpMyAdmin]] pour mettre en place l'interface. Dans la documentation ne suivez pas la méthode **Usage with linked server** qui est dépréciée. Utilisez la méthode avec un serveur externe. * Créer un docker basé sur la dernière version de phpMyAdmin : - dont le nom est ''dockpma''; - qui partage le port 8080 de votree VM avec le port 80 du docker; - qui utilise l'adresse du docker ''docktest'' comme base de données. * Connectez-vous sur l'interface web entrez le login mot de passe de l'administrateur mysql et créer une nouvelle base de données : ''MABASE2''. Constatez les modifications du répertoire partagé. ===Gestion du réseau et liaison entre les dockers=== Ce système de configuration n'est pas utilisable, car il demande d'entrer dans le docker ou ses fichiers de configuration une adresse qui est gérée par docker. Cela signifie par exemple que si vous programmez un service web pour utiliser la base de donnée, ce dernier devra être modifié si par hasard le docker est recrée avec une autre adresse. Pour remédier à cela vous allez utiliser la possibilité de créer des réseaux et de choisir les adresses des dockers. En effet, il est possible de choisir les adresses IPs des dockers, de choisir la valeur de leurs variables d'environnement ou de paramétrer leur fichier ''/etc/hosts''. * Vous devez tout d'abord créer un réseau utilisateur via la commande ''docker network create ...''. Attention, il faut utiliser l'option ''subnet'' pour définir le réseau. Créer un réseau de nom ''interne'' et utilisant la plage d'adresses ''172.18.100.0/24''. * Arrétez le docker ''docktest'' **Attention ne le supprimez pas** * puis recréez un nouveau docker mysql utilisant le réseau ''interne'' (option ''%%--net%%'') et en attribuant une adresse (option ''%%--ip%%'') : - **le nom est ''dockbdd''**; - **le //hostname// est ''bdd''**; - le mot de passe //root// est ''passbdd''; - qui partage le répertoire ''/var/lib/mysql'' du docker avec le répertoire ''/home/ubuntu/docker/datatest/'' de la VM. - **utilisant l'adresse 172.18.100.10.** * Supprimez le docker ''dockpma'' puis recréez-le en ajoutant à son fichier //hosts// le docker ''dockbdd'' sous le nom ''bdd'' avec leurs adresses (option ''%%--add-host%%''). Créez un docker basé sur ''phpmyadmin/phpmyadmin'' : - dont le nom est ''dockpma''; - qui partage le port 8080 de votre VM avec le port 80 du docker; - qui utilise ''bdd'' comme base de données; - dont le nom ''bdd'' correspond à l'adresse ''172.18.100.10''. * Ajoutez ''dockpma'' au réseau interne (commande ''docker network connect ...'') en lui attribuant l'adresse : ''172.18.100.11''. * Verifiez que ''dockmpa'' est bien dans le même réseau que le docker ''dockbdd'' (avec un ''docker inspect ..''). * La VM peut-elle contacter ces dockers ? Une autre VM le peut-elle ? * Reconnectez-vous sur l'interface web, tout devrait fonctionner et les bases créées précédemment devraient être encore fonctionnelles. Cela signifie donc que le docker //mysql// est capable de conserver les données déjà existantes. * Créez une autre base de données ''MABASE3'' et vérifiez son apparition dans le partage de données. La solution présentée ici n'est pas totalement idéale, car il faut refaire le docker ''dockpma'' si l'adresse du docker ''dockbdd'' est modifiée. Il existe des solutions plus souples présentées plus loin. ==== III. Configuration des dockers ==== En général pour configurer un service, il est nécessaire de modifier des fichiers. Mais ces fichiers sont internes au docker donc difficiles d'accès. De plus, les outils d'édition les plus courants (nano, vim, emacs ...) ne font pas parti d'un conteneur classique ce qui complique encore cette modification. Pour résoudre le problème, on peut : - Pré-configurer le docker via le //Dockerfile// ou les outils de création (voir plus tard); - Copier des fichiers entre la VM et le docker; - Utiliser le partage des répertoires entre la VM et le docker. Nous allons utiliser la dernière méthode pour configurer un proxy inverse //nginx//. Le fichier de configuration principale de //nginx// est ''/etc/nginx/nginx.conf''. Nous allons partir d'un fichier copié depuis un docker //nginx// fonctionnel . * créez un docker basé sur la dernière image //nginx// tel que : - son nom soit ''docknginx''; - il soit dans le réseau ''interne'' avec l'adresse ''172.18.100.5''; - le port 80 de l'hôte soit envoyé sur le port 80 du docker; - le nom ''dockpma'' soit relié à l'adresse 172.18.100.11; - le fichier {{ :cloud:2018:nginx.conf }} soit lié au fichier ''/etc/nginx/nginx.conf'' du docker, le container ne doit pas pouvoir écrire dans le fichier; - le répertoire ''/home/ubuntu/docker/nginx/'' soit lié au répertoire ''/www/'' du docker. * vérifiez le bon fonctionnement du serveur //nginx// en allant à l'adresse [[http://IPDEVOTREVM/]] * Modifiez la configuration du serveur pour que la racine du site web soit le répertoire partagé ''/www/'' * Modifiez la configuration du serveur pour que l'url [[http://IPDEVOTREVM/phpMyAdmin/]] soit renvoyée vers le docker //dockpma//. Pour cela il faut - utiliser la configuration de //nginx// comme [[https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/|reverse proxy]] - reconstruire le docker ''dockpma'' avec l'adresse ''172.18.100.11''; - reconstruire le docker ''dockpma'' en lui donnant l'url par laquelle il sera contacté via la variable ''PMA_ABSOLUTE_URI''; - reconstruire le docker ''dockpma'' en supprimant le transfert de port (8080 vers 80) car il est inutile (et gênant pour la suite). ====III-bis. Problèmes à l'installation de logiciel sur la machine virtuelle ==== L'image utilisée pour les TP semble avoir eu un petit souci. En effet, il semble que des processus de mise a jour apt sont en train de tourner et bloquent toute commande d'installation. Si pour une installation vous avez ce problème : ubuntu@prepa-tp-dockercompose:~$ sudo apt install unzip E: Could not get lock /var/lib/dpkg/lock - open (11: Resource temporarily unavailable) E: Unable to lock the administration directory (/var/lib/dpkg/), is another process using it? Cela signifie qu'il y a sans doute un processus ''apt'' en train de tourner. Il faut le stopper afin de poursuivre votre installation. **Attention à ne pas supprimer un processus de votre binôme** qui peut être justement en train de travailler sur la machine. Si vous êtes sûr de ce que vous faites : - retrouver le numéro du processus fautif : ubuntu@prepa-tp-dockercompose:~$ ps auxf USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 2 0.0 0.0 0 0 ? S Oct23 0:00 [kthreadd] root 4 0.0 0.0 0 0 ? I< Oct23 0:00 \_ [kworker/0:0H] root 6 0.0 0.0 0 0 ? I< Oct23 0:00 \_ [mm_percpu_wq] root 7 0.0 0.0 0 0 ? S Oct23 0:06 \_ [ksoftirqd/0] ... root 7096 0.0 0.0 4628 920 ? Ss 06:38 0:00 /bin/sh /usr/lib/apt/apt.systemd.daily install root 7109 0.0 0.0 4628 1764 ? S 06:38 0:00 \_ /bin/sh /usr/lib/apt/apt.systemd.daily lock_is_held install root 7138 0.1 3.8 148192 78700 ? S 06:38 0:16 \_ /usr/bin/python3 /usr/bin/unattended-upgrade _apt 7150 0.0 0.4 80116 8580 ? S 06:38 0:00 \_ /usr/lib/apt/methods/http - Détruisez le dernier fils des processus (ici ''/usr/lib/apt/methods/http'') ubuntu@prepa-tp-dockercompose:~$ sudo kill -15 7150 ubuntu@prepa-tp-dockercompose:~$ - Vérifiez qu'il n'y a plus de processus apt en cours ubuntu@prepa-tp-dockercompose:~$ ps aux | grep apt ubuntu 10485 0.0 0.0 14856 1060 pts/0 S+ 10:23 0:00 grep --color=auto apt - Relancez votre installation ubuntu@prepa-tp-dockercompose:~$ sudo apt install unzip Reading package lists... Done Building dependency tree ... ====IV. Création d'image : installation du docker owncloud==== Vous allez maintenant ajouter un élément au site : //owncloud//. C'est un logiciel de partage de fichier. Il fonctionne un peu comme //dropbox// ou le //drive// de google. //owncloud// est un service web écrit en php. Il est disponible [[https://owncloud.org/|ici]] ou dans une [[https://github.com/owncloud-docker/server|version dockerisée]]. La documentation propose d'utiliser en plus de ce docker un docker mysql et un docker //redis//. Nous n'utiliserons que mysql. * Adaptez le docker //dockbdd// pour qu'il crée un utilisateur et une base de données : - le nom est ''dockbdd''; - le //hostname// est ''bdd''; - le mot de passe //root// est ''passbdd''; - **qui partage le répertoire ''/var/lib/mysql'' du docker avec le répertoire ''/home/ubuntu/docker/data/'' de la VM**((ici il faut bien penser à changer le répertoire de données. En effet, la création de table et d'utilisateur n'est fait que si la base de données est nouvelle donc sans rien dans son répertoire de stockage)). - utilisant l'adresse ''172.18.100.10''; - **avec un utilisateur ''owncloud'' dont le mot de passe est ''passowc'';** - **avec une base de données ''owncloud''**. * Créer un docker ''dockowncloud'' - basé sur l'image ''owncloud/server''; - qui utilise cette basse de données (voir les variables ''OWNCLOUD_DB_TYPE'', ''OWNCLOUD_DB_HOST'', ''OWNCLOUD_DB_NAME'', ''OWNCLOUD_DB_USERNAME'' et ''OWNCLOUD_DB_PASSWORD''; - dont l'administrateur est ''admin'' de mot de passe est ''passadmin''; - dont l'adresse est ''172.18.100.15''; - qui écoute sur le port 8080 de la machine hôte. * Testez-le, à l'adresse ''http://IPDEVOTREVM:8080/'' attention, il est long à démarrer car le premier démarrage met en place le partage de fichier. * Testez-le, à l'adresse ''http://IPDEVOTREVM:8080/'' attention, il est long à démarrer, car le premier démarrage met en place le partage de fichier. === Création d'une première image === Certaines configurations ne sont pas proposées par le docker //owncloud//. Par exemple, celui-ci ne dispose pas de la commande ''sudo'', or cette commande est utile pour la suite du TP((En effet, nous souhaitons utiliser l'utilitaire en ligne de commande ''occ'' qui permet de piloter le logiciel //owncloud// via des scripts. Or il est important que les commandes ''occ'' soient exécutées par l'utilisateur ''www-data'' qui est aussi celui utilisé par le serveur web. L'utilisateur par défaut du docker est ''root'', ''sudo'' nous permettra de changer cela.)). Vous allez donc dans un premier temps modifier l'image ''owncloud/server'' La modification d'une image se fait grâce à des fichiers de description //Dockerfile//. En fait, chaque création d'image correspond à un répertoire qui contient les données nécessaires à la modification ainsi que le fichier de description ''Dockerfile''. Vous pouvez noter que la plupart des documentations de dockers sont en fait constituées par un dépôt git correspondant à ce répertoire. Comme vous pouvez le voir [[https://github.com/owncloud-docker/server|ici]]. Nous vous proposons de commencer par {{ :cloud:2018:owncloud.zip |ce répertoire de travail}}. * Construisez une nouvelle image nommée ''owncloud-perso:0.1'' basée sur ce //Dockerfile//. * Testez la nouvelle image et vérifiez que tout fonctionne. * Modifiez le //Dockerfile// pour installer ''sudo'' dans l'image. * Modifiez le //Dockerfile// pour installer le module //calendar// dans le logiciel owncloud. Ici, il est nécessaire de le faire sous la forme d'un script de post-installation. Ce script est déjà préparé, c'est le fichier ''pinst.sh'' du répertoire. Il faut simplement lui demander d'exécuter la commande ''%%sudo -u www-data php occ market:install calendar%%'' automatiquement à la première installation du docker). * Reconstruisez l'image avec le tag ''owncloud-perso:0.2''. * Ajouter à cette image le tag ''owncloud-perso:latest''. * reconstruisez le docker ''dockowncloud'' en précisant l'image ''owncloud-perso'' **sans mentionner de version**. Vérifiez que vous obtenez bien l'image ''0.2''. ==== V. Retour sur la gestion des réseaux ==== Il faut maintenant faire le lien entre le docker ''docknginx'' et le docker ''dockowncloud''. La méthode vue précédemment utilisait l'affectation de l'adresse IP pour faire ce lien. Cela suppose de détruire puis refaire le docker ''docknginx''. Pour éviter cela, nous allons utiliser le fait que les réseaux définis par les utilisateurs permettent de créer des associations entre le nom et l'adresse des dockers((Vous avez deviné, nous ne savions pas ça la semaine dernière.)). * Détruisez le docker owncloud et reconstruisez-le en ajoutant un alias via l'option ''%%--network-alias%%'' - il doit être basé sur l'image ''owncloud-perso'' sans mention de la version; - il doit être nomé dockowncloud; - il doit connaitre la base de donnée par le nom ''bdd''; - il doit utiliser la base de donnée, l'utilisateur ''owncloud'', son mot de passe; - l'administrateur doit être ''admin'' de mot de passe ''passadmin''; - le répertoire ''/home/ubuntu/docker/files/'' doit être partagé sur ''/mnt/data/''; - le docker doit avoir l'adresse 172.18.100.15 dans le réseau interne; - il doit écouter sur le port ''8080'' de la machine virtuelle; - **il doit être connu avec l'alias ''owncloud'' dans le réseau.** * Vérifier que cela a fonctionné, une résolution de nom dans le réseau ''interne'' doit fonctionner. Par exemple les commandes suivantes doivent permettre au docker ''dockpma'' de contacter le docker ''dockowncloud''. - ''%%docker exec -it dockpma ping dockowncloud%%'' - ''%%docker exec -it dockpma ping owncloud%%'' * Modifiez le fichier de configuration du docker ''docknginx'' pour que la racine du site [[http://IP_DE_VOTRE_VM/]] soit transmise au docker owncloud. * Testez le fonctionnement. * Vous pouvez aussi ajouter un alias à des dockers existant lors de la connexion au réseau. S'ils sont déjà dans les réseaux, il faut au préalable les retirer du réseau. ubuntu@prepa:~/docker$ docker network disconnect interne dockpma ubuntu@prepa:~/docker$ docker network connect --alias pma --ip 172.18.100.11 interne dockpma ==== VI. Gestion de plusieurs dockers avec compose ==== Vous devez être capable de lancer un petit ensemble de services via des dockers. Mais cela n'est pas suffisant. En effet, avec la méthode actuelle, pour que le site fonctionne, il faut être capable de lancer les dockers avec les bonnes options, dans un ordre précis, avec des fichiers de configuration qui dépendent de ces options ... Tout cela est difficile à distribuer. Il est donc nécessaire de faire la même chose mais de manière automatique. En effet, pour automatiser les opérations sur les conteneurs, il est possible d'écrire une description des commandes utilisées dans un fichier, c'est le rôle de ''docker-compose''. Docker compose est capable de faire à votre place toutes les commandes docker nécessaire à partir de ce que vous avez décrit dans un fichier ''docker-compose.yml''. Vous pouvez avoir une description de ces fichiers à [[https://docs.docker.com/compose/compose-file/compose-file-v2/|cette adresse]]. Attention, l'api docker évolue rapidement, il est important de se limiter à une version pour travailler. De plus, //il ne faut pas confondre la version de l'exécutable ''docker-compose'', celle du logiciel ''docker'' et celle du fichier de description ''docker-compose.yml''//. La version la plus importante est celle du fichier de description, elle est écrite au début du fichier : version: '2.4' services: foo: image: busybox Nous vous conseillons d'utiliser pour ce TP la version de l'exemple : ''2.4''. C'est //la dernière de la version 2//. En effet la version 3 est la version qui introduit l'utilisation de cluster ce qui sera vu plus tard. La documentation conseillée est donc celle de la version 2 et **il est important de vérifier que la documentation que vous consultez est bien basée sur cette version pour expliquer les problèmes**. ===Organisation du fichier compose=== Dans la version 2, le fichier est composé de 3 sections correspondant aux sous-commandes docker utilisées : - ''services'' est la section qui donne la liste des dockers et de leurs options, cela correspond aux commandes ''docker run ...'' ou ''docker create ...'' - ''networks'' est la section qui décrit les réseaux à utiliser. Cela correspond à la commande ''docker network ...'' - ''volumes'' est la section qui décrit les volumes à utiliser. Cela correspond à la commande ''docker volume ...'' === Section volumes === Pour résumer, cette section correspond à la création de volumes en dehors des dockers. Jusqu'à présent, vous n'avez jamais utilisé la commande ''docker volumes ...'' ce qui signifie que vous n'aurez pas à utiliser la section pour ce TP. Tous vos volumes seront des volumes de type //bind//, c'est à dire créés lors du ''docker run'' (section service) et partagée avec la machine hôte. Les volumes sont des espaces de stockage persistants utilisés par les dockers. Vous pouvez les créer soit en les utilisant dans un docker soit en les créant à part via la commande ''docker volume...''. La description de la section ''volumes'' d'un docker-compose est [[https://docs.docker.com/compose/compose-file/compose-file-v2/#volume-configuration-reference|ici]]. Il faut aussi consulter la description de l'utilisation des volumes par les dockers grâce à la //sous-section// ''volumes'' d'un service. La documentation est [[https://docs.docker.com/compose/compose-file/compose-file-v2/#volumes|là]]. Dans un fichier //docker-compose.yml// * La section ''volumes'' globale vous permettra de créer un volume ou de déclarer un volume qui a été créé en dehors du docker compose. Elle permet aussi d'utiliser des drivers spéciaux. * La sous-section ''volumes'' de la description d'un service est celle qui attachera effectivement le volume au docker créé, cela correspondra à l'option ''%%-v%%'' de la commande ''docker-run''. C'est à cet endroit que vous pouvez associer un répertoire du docker avec un répertoire de la machine. === Section networks === C'est la section qui vous permettra de créer et configurer le réseau. Correspondant à ce que vous avez fait via la commande ''docker network ...''. Vous êtes invité à consulter [[https://docs.docker.com/compose/compose-file/compose-file-v2/#network-configuration-reference|cette documentation]], notamment la partie //ipam// qui permet de gérer l'intervalle d'adresse utilisé. === Section services === Cette section décrit les dockers qui devront être créés. Pour cette version, chaque service correspond à un docker et une commande ''docker-run ...''. [[https://docs.docker.com/compose/compose-file/compose-file-v2/#service-configuration-reference|La documentation]] est très fournie, vous aurez notamment besoin : - De pouvoir choisir l'image à partir de laquelle le docker est créé, cela peut être * une image utilisable via le mot clef [[https://docs.docker.com/compose/compose-file/compose-file-v2/#image|image]]; * une image construite via le mot clef [[https://docs.docker.com/compose/compose-file/compose-file-v2/#build|build]]. - D'imposer le réseau utilisé via le mot clef [[https://docs.docker.com/compose/compose-file/compose-file-v2/#networks|networks]]. Regardez notamment comment choisir l'adresse ip et donner un //alias// à ce docker. - D'ajouter au docker des partages de répertoires de type bind [[https://docs.docker.com/compose/compose-file/compose-file-v2/#volumes|volumes]]. - De déclarer des variables d’environnement dans le docker [[https://docs.docker.com/compose/compose-file/compose-file-v2/#environment|environment]]. - De mettre en place des transferts de ports réseaux entre la VM et le docker [[https://docs.docker.com/compose/compose-file/compose-file-v2/#ports|ports]]. - De spécifier des dépendances entre les dockers [[https://docs.docker.com/compose/compose-file/compose-file-v2/#depends_on|depends_on]]. === Travail à faire === Vous devez installer //docker-compose//. N'utilisez pas ''apt-get install docker-compose'' car cela installerait une ancienne version de docker sur votre VM. Vous devez créer un ensemble de fichiers et un ''docker-compose.yml'' qui recrée l'architecture vue au début du TP. Le répertoire doit être ''/home/ubuntu/compose/'' et contenir tous les fichiers et partage nécessaires à cette architecture. ./compose/ |_ docker-compose.yml |_ data/ | |_ mysql/ | |_ owncloud/ | |_ onlyoffice/ |_ logs/ | |_ onlyoffice/ |_ nginx/ | |_ nginx.conf |_ owncloud/ |_ Dockerfile |_ pinst.sh Vous devez faire un fichier compose qui crée des dockers équivalents aux 4 dockers et au réseau créé auparavant. Ces dockers utiliseront les mêmes ports que les précédant. Vous devez donc les éteindre (''docker stop dockbdd docknginx dockpma dockowncloud''). //Attention à ne pas les supprimer cela poserait des problèmes pour le script de notation//. Pour résumer il faut : * un réseau ''rescompose'' - utilisant les adresses ''172.18.200.0/24''; - s'il attribue automatiquement une adresse, elle devra être dans la plage 172.18.200.128 à 172.18.200.160 * un service //nginx// qui servira de front web - basé sur la dernière version de l'image //nginx//; - qui a une adresse fixe dans le réseau ''rescompose'' : ''172.18.200.5''; - lancé après les services phpmyadmin et owncloud; - qui partage le port 80 de la machine avec le port 80 du docker; - qui est configuré via le partage du fichier ''./compose/nginx/nginx.conf''; - qui renvoie les requêtes [[http://IP_DE_VOTRE_VM/]] sur //owncloud// et [[http://IP_DE_VOTRE_VM/phpMyAdmin/]] sur //phpmyadmin//. * Un service //mysql// - basé su l'image ''mysql'' dans la version 5.7.23 ; - dont le répertoire de données est associé à ''./compose/data/mysql/''; - qui a une adresse automatique dans le réseau ''rescompose''; - qui est connu des autres dockers sous plusieurs noms : ''mysql'', ''bdd'' ou ''bd''; - dont le mot de passe root est ''passbdd''; - qui contient un utilisateur ''owncloud'' de mot de passe ''passowc'' et une base ''owncloud''. * Un service //phpmyadmin// - basé sur l'image ''phpmyadmin/phpmyadmin''; - qui démarre après //mysql//; - qui a une adresse dynamique dans le réseau ''rescompose''; - qui est connu des autres dockers sous plusieurs noms : ''phpmyadmin'' ou ''pma''; - qui interroge le serveur //mysql//; * Un service //owncloud// - basé sur une image construite d'après le contenu du répertoire ''./compose/owncloud/''; - qui démarre après le docker mysql; - dont le volume de données est associé au répertoire ''./compose/data/owncloud/''; - qui a une adresse dynamique dans le réseau ''rescompose''; - qui est connu des autres dockers sous plusieurs noms : ''owncloud'' ou ''owc''; - qui utilise la base de donnée et l'utilisateur mysql ''owncloud''; - dont l'administrateur ''admin'' a pour mot de passe ''passadmin''; - qui utilise le //plugins// ''calendar''. Vous constaterez que les dockers créés par //compose// n'ont pas le nom des services. En effet, s'il n'est pas précisé par le champ [[https://docs.docker.com/compose/compose-file/compose-file-v2/#container_name|container_name]], compose ajoute le nom du répertoire et un numéro unique. C'est utile pour que les noms de ces dockers soient différents de ceux que vous aviez crée auparavant. Gardez les noms par défauts. === Un peu plus difficile === Il est possible de donner à //owncloud// la possibilité d'éditer les documents en ligne. Pour cela, il faut utiliser un autre service : //onlyoffice// et ajouter le //plugins// onlyoffice à owncloud pour lui permettre de contacter ce dernier. Pour faire fonctionner ce service de manière automatique, il faut savoir les choses suivantes : * Le service //onlyoffice// a besoin d'une configuration particulière derrière un proxy inversé, [[https://helpcenter.onlyoffice.com/fr/server/document/document-server-proxy.aspx|voir ici]] * Le service //onlyoffice// doit pouvoir être accédé par le navigateur, on le teste en allant sur la page du service qui doit renvoyer vers la page //welcome// comme ici [[http://192.168.77.14/onlyoffice/]] * Le plugin //onlyoffice// de //owncloud// demande en plus de son installation la configuration de variable. L'interface permet de le faire dans la partie ''settings->additionnal''. * En ligne de commande on peut lister les variables de configuration avec la commande ''sudo -u www-data php occ config:list'' * En ligne de commande on peut lister les variables de configuration de module avec la commande ''sudo -u www-data php occ config:app:set''