Passage de mes sites sous Docker : retour d’expérience

Ça fait un bail que je voulais écrire cet article, et comme d’hab ça a traîné…D’un sens c’est pas plus mal car ça me permet d’avoir un retour d’expérience plus long et donc peut-être plus juste aussi.

Mon pote Patrice, évangile selon St Docker, à force de prêcher pour sa paroisse que représentait la firme à la baleine bleue a fini par me convaincre de passer mes sites sous Docker.

Pourtant, je dois reconnaître que je n’ai plus trop le temps de m’en occuper, que ce soit pour la gestion des contenus pour la partie sys-admin. Mais comme j’étais curieux de voir les prouesses que tout le monde vends à Docker, je me suis laissé tenter!

Un beau matin de septembre 2015, je lui demande au café comment ça se passerait pour moi de faire tourner mes sites dans des conteneurs Docker. Je vous passe l’explication de 2h (et encore je suis gentil ^^) qu’il m’a faite, mais qu’il a heureusement résumée dans un article ici: Docker Apache Mysql PHP.

Une dernière chose avant de rentrer dans le vif du sujet: je n’avais avant de découvrir Docker qu’une très faible expérience du monde de la virtualisation (au sens large). Docker est donc le premier outil que j’utilise et donc certaines de mes réactions enthousiastes sont uniquement dues aux joies de la découverte de la virtualisation, j’aurais donc eu des réactions similaires en jouant avec ces autres solutions.

Docker docker docker docker

Il y a des effets de modes dans le monde du numérique, Docker est passé par là lui aussi! Beaucoup n’ont que ce mot à la bouche, et il n’y avait pendant un temps pas une conférence sans qu’un des speakers en parle.

Pour faire simple, docker, ça reprends le vieux concept de la virtualisation sans toutefois embarquer son propre OS puisque les conteneurs dockers’appuient sur le propre OS de la machine hôte.

Si vous voulez plus d’infos, je m’étalerai pas ici, car d’autres l’ont déjà fait ailleurs, ce que je voulais partager avec vous aujourd’hui, c’est mon retour d’expérience face à cet changement de mon infra et les quelques difficultés que j’ai pu essuyer.

La machine

J’ai profité de ce passage sous docker pour changer de serveur et de distribution. Je suis passé de ma vieille Ubuntu à un centOS (pur choix perso, influuencé par des trolleurs/détracteurs d’Ubuntu dans mon entourage!), et j’ai changé de machine OVH car mon je payais trop cher mon kimsufi vieillissant (kimsufisait plus donc…).

Voilà, donc me voilà sur ma nouvelle machine, je fais des mises à jour de rigueur, installe quelques outils de sécurité et file installer docker et docker-compose que je vais chercher directement sur le site officiel de docker (ceux présents dans les repo n’étaient pas les derniers produits par docker).

L’environnement

Pour vous faire une présentation de mon parc de sites webs et autres apps hébergées, c’est environ 8 sites webs tournant sur Apache (il y a du wordpress, du symfony, du laravel, du angular, bref un peu de tout), quelques applications (serveur git, usine logicielle, petit client p2p….).

Serveur web

Cela faisait aussi pas mal de temps que je voulais m’amuser avec Nginx, mais pareil pas le temps de le mettre en place sur mon serveur, j’en ai donc profité pour commencer à passer d’Apache à Nginx. Pas de réelle justification technique de ce coté si ce n’est celle de prendre un peu plus Nginx en main!

Pour pas me donner trop de travail, les vieux sites restent sous Apache et les nouveaux filent sur Nginx. J’ai donc installé le Nginx en frontal qui écoute sur les ports 80 et 443 et qui forwarde les requêtes en fonction du domaine appelé: soit vers le Apache/PHP5, soit vers le Nginx/PHP7.

PHP

Coté sites, certains étaient prêts à passer à PHP7, d’autres, un peu plus vieux ne l’étaient pas, j’ai donc deux conteneurs qui tournent pour servir mes sites en PHP, l’un qui fournit du PHP5 et l’autre du PHP7.

Base de données

Coté bdd, très simple, historiquement mes sites tournent avec MySQL et une interface phpMyAdmin, ici, j’ai rien voulu révolutionner, tout devait continuer de marcher ainsi!

(s)FTP

J’avais avant un serveur FTP qui me permettait de bidouiller des choses (oui je sais c’est le mal FTP), j’en ai profité pour remettre un serveur, cette fois-ci en sFTP, un chouya plus secure.

/etc(etera)

Voilà, c’est à peu près tout pour la stack opérationnelle de mes sites. A cela s’ajoutent quelques applications et autre outils tels qu’un serveur mail (très fonctionnel et stable, actuellement en expérimentation sur mon serveur), un outil de déploiement continu (jenkins), un serveur git avec une interface sympa (gogs), un webmail (rainloop) et un client p2p (transmission).

Mon retour d’expérience

Avant d’aller plus loin, j’ai souhaité partager tout de suite avec vous mon retour d’expérience, si vous voulez savoir un peu plus comment fonctionne mon architecture actuelle, je vous invite à aller plus loin pour lire la partie “Description et mise en place des conteneurs“.

Bien que Docker ne recommande toujours de faire tourner des sites en production avec docker, à mon échelle, il fait preuve d’une très haute stabilité. Les seuls plantages serveurs que j’ai eus venaient d’une mauvaise configuration du serveur Apache et aussi d’un disque dur étant plein à craquer faisant de fait planter les conteneurs, donc je ne peux pas le blâmer pour ça.

Pour la facilité de mise en place des conteneurs, en quelques minutes on arrive à des choses concluantes: jamais je n’aurai pris le temps de mettre en place une plateforme d’intégration continue ou un serveur git avec interface graphique. C’est maintenant chose faite!

De surcroît, j’ai pu mettre en place une solution de backup plus simple, car sur la machine hôte, les données de mes conteneurs sont bien rangés dans des dossiers et au même endroit. Pas besoin d’aller piocher dans /etc,/usr/lib,/var/lib et plein d’autres dossiers qu’il faut penser à backuper: ici tout est géré au même endroit (la conf et data).

De la même façon, le changement de serveur n’est plus douloureux comme il pouvait l’être avant, plus besoin de se retaper des installation de tout (et des petits hacks qu’on doit parfois faire pour faire fonctionner une install), ici on se contente de déposer nos fichiers sur le nouveau serveur et de  lancer une commande pour reconstruire les conteneurs et hop le tour est joué.

Bref à mon niveau, c’est que du bonheur. Je reste attentif aux évolutions de cet outil qui n’en est encore qu’à ses débuts mais qui ne fait malgré tout pas l’unanimité chez tout le monde.

Description et mise en place des conteneurs

Je ne vais pas vous faire un tuto de comment j’ai mis en place tout cela, vous pouvez aller jeter un oeil sur l’article de Patrice qui parle de mise en place d’un DAMP (Docker Apache MySQL PHP). Quand vous aurez compris comment mettre en place un conteneur, ce sera la même chose pour n’importe quoi d’autre: que vous souhaitiez installer un Tomcat, un IIS ou juste un conteneur pour faire du Go ou du Python!

Juste je vais vous donner sans trop détailler quelques morceaux de mes fichiers de configuration docker (situés dans un ou plusieurs “docker-compose.yml”) pour que vous puissiez comprendre la logique et l’adapter à votre cas. Certaines parties ont été modifiées donc n’essayez pas de copier-coller bêtement: ça ne fonctionnera pas forcément!

Frontal

Le frontal tourne donc sur un custom nginx, ça ne fait rien d’autre que récupérer l’image officielle d’Nginx et installer vim et deux trois autres softs dont j’ai besoin).

Il écoute sur les ports 80 et 443 de mon serveur. J’ai divers “volumes” pour garder hors de mon conteneur les configurations de mon serveur et également un volume qui contient les sites (www). Pour rappel, les volumes, c’est des espaces partagés entre la machine hôte et le conteneur. Ainsi lorsqu’on supprime le conteneur, ces données sont toujours en local, ce qui fait que lorsqu’on remonte un conteneur, ces données sont restaurées et donc le conteneur est “restauré”. On a d’un coté de l’instruction le path de la machine local qu’on mappe avec le path du conteneur. Ex: sur la machine hôte, le dossier “/nginx/www” contiendra le contenu du dossier “/usr/share/nginx/html” situé dans le conteneur.

Et pour finir, je “link” ce conteneur avec d’autres qu’on verra plus bas: “sites” qui est mon conteneur principal pour faire tourner mes sites (Apache/PHP5), “rainloop” qui est mon webmail, “database” ma bdd, et “php5fpm” qui est mon conteneur qui permet de faire tourner PHP5 en mode proxy.

“Linker”, ça consiste grossièrement à permettre à deux conteneurs de se voir et de communiquer ensemble sur le réseau local.

frontal:
     build: ./nginx/
     ports:
     - "80:80"
     - "443:443"
     volumes:
     - "./nginx/www:/usr/share/nginx/html"
     - "./nginx/etc:/etc/nginx"
     links:
     - sites
     - rainloop
     - database
     - php5fpm

Database

Ici, on récupère la dernière version d’image MySQL, on dit au conteneur de redemarrer seul comme un grand quand il se casse la gueule et on sauvegarde en local la data et la conf avec des volumes. Tout con.

database:
    image: mysql:latest
    restart: always
    volumes:
    - "./database/data:/var/lib/mysql"
    - "./database/mysql:/etc/mysql"

Sites

Ici on build une image custom de PHP5.6 avec le serveur Apache en y ajoutant les extensions dont on a besoin (traitement d’image, json, gzip et compagnie).

Ensuite dans les volumes, on persiste les data, la conf et les logs.

On link avec le conteneur “database” car nos sites ont besoin de parler avec elle, puis aussi avec “mail” qui est mon conteneur de serveur mail en test.

sites:
    build: ./sites/
    volumes:
    - "./sites/www/:/var/www/html"
    - "./sites/virtualhosts/:/etc/apache2/sites-enabled"
    - "./sites/logs/:/var/log/apache2/"
    links:
    - database
    - mail

PHP5-fpm

Ici on a un conteneur juste pour gérer PHP5 en mode fpm, on a aussi une image custom pour ajouter quelques extensions à PHP.

On persiste les data, et on link la bdd.

php5fpm:
     build: ./php5fpm/
     volumes:
     - "./nginx/www:/usr/share/nginx/html"
     links:
     - database

PhpMyAdmin

Je récupère l’image phpMyAdmin, je lui dit d’écouter sur le port 8001 (donc je pourrais accèder à phpMyAdmin depuis n’importe où via ce port).

Je link bien évidemment avec la base de données, et je lui file quelques variables d’environnement pour qu’il puisse fonctionner (comme le mot de passe que je n’ai pas mis ici)

pma:
    image: corbinu/docker-phpmyadmin
    ports:
    - "8001:80"
    links:
    - database

Mail

Ce conteneur est en phase d’expérimentation donc je vais vite passer dessus. En gros je lui confie la gestion des ports 25,143,587 et 993 (pop, stmp).

Je sauvegarde les données des mails en local.

mail:
  image: tvial/docker-mailserver
  hostname: mail
  domainname: mondomaine.com
  # your FQDN will be 'mail.domain.com'
  ports:
  - "25:25"
  - "143:143"
  - "587:587"
  - "993:993"
  volumes:
  - ./mailserver/maildata:/var/mail/
  - ./mailserver/config:/tmp/docker-mailserver/

Rainloop

Ici c’est la partie webmail, qui va communiquer avec le conteneur “mail”. Il est accessible sur le net via un reverse proxy mis en place dans mon conteneur “frontal” Nginx (d’où le link qu’on voyait un peu plus haut)

rainloop:
  image: ahmet2mir/rainloop
  volumes:
  - ./rainloop:/webapps/rainloop/data
  links:
  - mail

Gogs

Gogs, c’est un github like, un poil plus léger et moins fourni, mais libre, gratuit et self-hosted. Pour mes besoins basiques de gérer mon code source ça me va très bien. Je peux pusher, faire des pull-request dans le cas où je travaille à plusieurs et je peux utiliser des hooks pour communiquer avec des outils comme jenkins.

Je récupère ici l’image officielle de gogs, et je publie l’appli sur le port 7777 de mon serveur et je mappe le port 7778 pour les connexions en ssh. Et c’est tout!

gogs:
     image: gogs/gogs
     ports:
     - "7777:3000"
     - "7778:22"
     volumes:
     - ./var/gogs:/data

 

Jenkins

Jenkins, je le présente plus: il  s’agit là d’un des plus gros bouffeur de ram (après Google Chrome sur nos chers ordinateurs), il permet de faire de l’intégration continue. Le rôle que je lui ai défini est de tester le code que je push sur mes repo, de me faire un rapport et de déployer ça quelque part si les tests passent. C’est bourrin, mais ça me convient, bien sûr, je ferais jamais ce genre de choses chez un client :p

Ici j’écoute les ports 4444 et 4445 que je mappe sur les ports standard d’écoute de jenkins. Je backup les data et je link avec gog.

jenkins:
     #image: jenkinsci/jenkins
     build: ./jenkins/
     ports:
     - "4444:8080"
     - "4445:50000"
     volumes:
     - ./jenkins/jenkins-data:/var/jenkins_home
     links:
     - gogs

Voilà en gros tout ce que j’utilise sur mon serveur web, et tout ça sans avoir pourri mon serveur comme j’aurai pu le faire avant, car oui le grand avantage de docker c’est que je dispose d’une infinité de sandbox pour tester de nouvelles choses sans avoir a pourrir mon serveur en installant des trucs que je saurais jamais désinstaller ni en prenant le risque de faire planter mes sites web!

Du coup pour aller plus loin dans la veille, c’est un véritable bijou car ça me permet de tester rapidement des choses sans avoir la crainte de tout péter!

Pour conclure cet article avec une jolie image, voici un cadeau customisé que j’adore que j’ai fabriqué pour de le départ mon ex-collègue.

2016-05-23-08-16-18

3 thoughts to “Passage de mes sites sous Docker : retour d’expérience”

  1. ” Voilà en gros tout ce que j’utilise sur mon serveur web, et tout ça sans avoir pourri mon serveur comme j’aurai pu le faire avant, car oui le grand avantage de docker c’est que je dispose d’une infinité de sandbox pour tester de nouvelles choses sans avoir a pourrir mon serveur en installant des trucs que je saurais jamais désinstaller ni en prenant le risque de faire planter mes sites web!

    Du coup pour aller plus loin dans la veille, c’est un véritable bijou car ça me permet de tester rapidement des choses sans avoir la crainte de tout péter! ”

    Docker est donc une solution adaptée pour les non-administrateurs systèmes qui voudraient quand même faire de l’administration système ? Merci pour ton riche retour d’expérience, malgré tout je ne vois (toujours) pas l’avantage de Docker par rapport à l’administration système “à l’ancienne” dans le cadre d’un hébergement de services perso, sans parler des autres solutions de conteneurisation (comme LXD et LXC par example). Comme tu le présente ça fait très “jouet” pour les non-initiés en fait…

  2. Salut, intéressant comme article.

    J’envisage de faire la même chose mais je profite des presque un an de ta migration pour te demander si c’est toujours en place et si c’est stable au quotidien ?

    Philippe.

Leave a Reply

Your email address will not be published. Required fields are marked *