/ Docker

Alpine Linux/Docker pour héberger mon site web

Plus d’informations sur le site officiel

https://alpinelinux.org/

Et le Wiki

https://wiki.alpinelinux.org/wiki/Main_Page

Petit tutoriel sur comment monter un serveur Nginx avec Docker, le containeur Alpine Linux, PHP et Maria DB pour ouvrir sa page web en une fraction de secondes.

Docker nous permet de simplifier beaucoup de processus. Ainsi je me suis dit pourquoi ne pas mettre en place une stack LEMP. J’ai naturellement utilisé des images docker. Nous allons pouvoir lancer en quelques secondes tout un environnement.

docker-compose-lemp-1024x536

Qu’est-ce que LEMP ?

LEMP est une variation de la très connue stack LAMP utilisé pour le développement et le déploiement d’application. En temps normal, LAMP est constitué de Linux, Apache, MySQL et PHP. Avec LEMP, on remplace Apache par le très léger et puissant Nginx, dockerisé et containeurisé avec Alpine Linux.

Alpine Linux ?  Quésaco ?

Alpine Linux est une distribution Linux basée sur la bibliothèque musl libc et BusyBox. Axée sécurité, elle est aussi beaucoup plus légère qu’Ubuntu : la dernière image .iso, livrée au début de l’année, pèse 82 Mo. Les conteneurs Docker n’ont pas besoin de tous les logiciels fournis avec Ubuntu, et ce changement pourrait effectivement réduire le volume des images, comme l’a fait remarquer dès lundi The VAR Guy, le premier à rapporter l’information. Comparativement, « l’image officielle d’Ubuntu en téléchargement sur le Docker Hub pèse 188 Mo. Elle a été téléchargée plus de 40 millions de fois, ce qui représente plus de 7520 To de données transférées entre le Docker Hub et les utilisateurs dans le monde entier, uniquement pour récupérer cette image », a déclaré vendredi dans un blog l’architecte cloud Brian Christner. « Si l’on multiplie ce volume par le nombre d’images officielles, la quantité de données transférées devient ahurissante ».

Avec Alpine Linux, « un container n’a pas besoin de plus de 8 Mo, et une installation minimale occupe environ 130 Mo d’espace disque », selon ses créateurs. « Pour les utilisateurs de Docker, les avantages sont multiples, à commencer par des vitesses de téléchargement plus rapides,une meilleure sécurité du fait d’une surface d’attaque plus petite, et une migration plus rapide entre les hôtes », a ajouté Brian Christner.

In lemondeinformatique.fr

Alpine Docker

Comme Alpine Linux est une distribution légère et réputée pour sa sécurité, les utilisateurs de Docker se tournent vers elle et laissent de côté Ubuntu, Debian, Centos et compagnie. Quelques exemples :

Vous souhaitez héberger un site avec Nginx : Alpine ;

  • Besoin de Jenkins pour vos développements : Alpine ;
  • Node.js : Alpine ;
  • Redis : Alpine ;
  • Elasticsearch : Alpine ;
  • Apache Tomcat : Alpine ;
    etc.

Et là, je ne parle que des applications officielles (les plus connues) et portées par leurs développeurs.

Création de notre stack

Nous avons une distribution Linux à utiliser pour notre travail du jour, qui pèse 5Mo et nous fait gagner du temps et offre une vraie qualité en terme de vitesse de connexion dû à sa légèreté. Nous avons donc besoin de différents dockers afin de mettre en place cette stack :

  • Nginx (evild/alpine-nginx)
  • PHP (evild/alpine-php)
  • MYSQL (mariadb)

Pour gérer nos différents dockers, nous allons utiliser docker-compose, (pour rappel comment installer Docker-Compose :

sudo apt-get install python-pip -y sudo pip install --upgrade pip sudo pip install docker-compose
 
Pour vérifier si l’installation s’est bien passée :

docker-compose --version

Vous devriez obtenir la réponse suivante :

docker-compose version: 1.5.1
 
Afin de mettre en place quelques bonnes pratiques, le fichier devra être en version 2. Pour faire cela, il suffit de mettre version: ‘2’ au début du fichier. Ensuite de mettre chacun des dockers sous services:

Cela donnerai donc :

version: '2' services : nginx: php: mariadb:

Nginx, notre serveur web

Notre premier container va contenir Nginx. L’image utilisée sera evild/alpine-nginx avec le tag 1.9.15-libressl. Vous pouvez également utiliser le tag 1.9.15-openssl ou encore le tag latest. On rajoute également un volume afin d’ajouter nos fichiers php, html. Pour simplifier la configuration de nginx, on remplacera toujours celle par défaut grâce au volume. Afin de le rendre accessible au public, on ajoute les ports 80 et 443.

nginx: image: evild/alpine-nginx:1.9.15-
libressl restart: always links:

*- php volumes:

  • ./html:/var/www/html/:ro
  • ./nginx/conf/nginx.conf:/etc/nginx/conf/nginx.conf:ro
  • ./nginx/conf.d:/etc/nginx/conf.d:ro 
    ports: - 80:80 - 443:443*

On aura donc besoin de créer quelques dossiers au même endroit que notre fichier docker-compose :

html nginx 
└── conf 
└── conf.d

Le fichier nginx.conf désactive le daemon et inclut un fichier de configuration pour nos pages web :

workerprocesses 1; daemon off; events { workerconnections 1024; } errorlog /var/log/nginx/error.log warn; pid /var/run/nginx.pid; http { include/etc/nginx/conf/mime.types; defaulttype application/octet-stream; logformat main '$remoteaddr - $remoteuser [$timelocal] "$request" ' '$status$bodybytessent "$httpreferer" ' '"$httpuseragent" "$httpxforwardedfor"'; accesslog /var/log/nginx/access.log main; sendfile on; #tcpnopush on; keepalivetimeout 65; gzip on; gzipdisable "msie6"; gzipvary on; gzipproxied any; gzipcomplevel 6; gzipbuffers 16 8k; gziphttpversion1.1; gziptypes text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; # tells the server to use on-the-fly gzip compression. include /etc/nginx/conf.d/.conf; }

Concernant notre fichier default.conf se trouvant dans le dossier conf.d, celui-ci met en place un upstream pour nos fichiers php. La configuration reste très basique. Vous pouvez l’adapter à vos besoins.

upstream php { server php:9000; } server { root /var/www/html; index index.php index.html; location / { tryfiles $uri $uri/ /index.php?$args; } location~ .php$ { include fastcgi.conf; fastcgiintercepterrors on; fastcgipass php; } location ~ .(js|css|png|jpg|jpeg|gif|ico)$ { expires max; lognotfoundoff; } }

Au tour de PHP

Nous voilà à notre deuxième conteneur. Ici encore nous allons utiliser une image Alpine : evild/alpine-php. Pour de meilleures performances et afin d’être à jour on utilisera la dernière version de PHP soit 7.0.6.

*php: image: evild/alpine
-php:7.0.6 containername: lempphp restart: always 
volumes: - ./html:/var/www/html dependson:

  • db links:
  • dbenvironment:
  • DBNAME=lempbdd
  • TABLEPREFIX=lemp
  • DBHOST=lemp
  • DBPASSWORD=password*

Notre base de données MariaDB

J’ai choisi de prendre une image officielle de mariadb car cette base de données ne dispose pas de support sur Alpine Linux.

*db: image: mariadb:latest containername: lempmariadb restart: always volumes: - db-data:/var/lib/mysql environment:

  • MYSQLROOTPASSWORD=password volumes: db-data: driver: local*

Les données seront stockées dans le volume db-data. Mais vous pouvez également les mettre directement sur votre machine.**

Fusion de chaque élément

On met tout ensemble dans notre docker-compose et on patiente pour le miracle :

*version: '2' 
services: nginx:
image: evild/alpine-nginx:1.9.15-openssl
containername: lempnginx
restart: always
links: - php volumes: - ./html:/var/www/html/:ro - ./nginx/conf/nginx.conf:/etc/nginx/conf/nginx.conf:ro - ./nginx/conf.d:/etc/nginx/conf.d:ro ports: - 80:80 - 443:443 
php: image: evild/alpine-php:7.0.6
containername: lempphp restart:
always volumes: - ./html:/var/www/html
dependson: - db
links: - db
environment: - DBNAME=lempbdd - TABLEPREFIX=lemp - DBHOST=lemp - DBPASSWORD=password
db: image: mariadb:latest
containername: lempmariadb
restart: always volumes:

  • db-data:/var/lib/mysql
  • environment: - MYSQLROOTPASSWORD=password v
  • olumes: db-data:
  • driver: local*

Fusion des éléments

Vous pouvez télécharger l’intégralité des fichiers sur mon github. Pour lancer tous nos dockers, une simple commande suffit :

docker-compose up

Après quelques secondes votre stack devrait être opérationnel. Si tout a fonctionné vous pouvez accéder à l’ip de votre machine dans votre navigateur. Vous allez apercevoir une page PHPINFO.

unnamed

Pour arrêter tous nos dockers d’un coup, nous utilisons la commande suivante :

docker-compose down

Pour ma part, j’ai ensuite tenté d’ajouter un nouvel affichage et d’utiliser le serveur LEMP léger comme une plume comme ceci :
 
J’ai commencé par me connecter en SSH à mon serveur local sur lequel j’ai implanté la configuration, il s’agit de mon serveur Docker tournant sur Ubuntu serveur avec l’orchestrateur Rancher.

gabriel@pcgabriel ~ $ sudo ssh gabriel@192.168.1.31 Mot de passe : 
The authenticity of host '192.168.1.31 (192.168.1.31)' can't be established. ECDSA key fingerprint is *****
. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '192.168.1.31' (ECDSA) to the list of known hosts. gabriel@192.168.1.31's password:
Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-62-generic x86_64)

12 paquets peuvent être mis à jour.
7 mises à jour de sécurité.

*** Le système doit être redémarré ***
Last login: Tue Aug 1 22:54:20 2017 from 192.168.1.98

Puis j’ai cherché mon dossier Lemp sur mon serveur et je m’y suis faufilé avec les commandes ls et cd :

gabriel@Ubuntu-server3:~$ ls docker-compose-lemp docker-compose.yml
gabriel@Ubuntu-server3:~$ cd docker-compose-lemp
gabriel@Ubuntu-server3:~/docker-compose-lemp$ ls ci docker-compose.yml html LICENSE.md nginx README.md

Ensuite j'ai cherché le dossier html et j'y suis entré avec cd :

*gabriel@Ubuntu-server3:~/docker-compose-lemp$ cd html 
gabriel@Ubuntu-server3:~/docker-compose-lemp/html$ ls 
css fonts index.html js LICENSE 
gabriel@Ubuntu-server3:~/docker-compose-lemp/html$ *

Et vous constaterez qu'il y a déjà du monde dans mon serveur web tournant sur le port 80, j'ai ajouté via FTP et Filezilla les dossiers nécessaires pour faire tourner une application web, j'ai utilisé le framework suivant pour le test : http://materializecss.com/getting-started.html

Voici le résultat lorsque j’interroge désormais mon serveur en tapant son adresse ip dans mon navigateur :

Capture-du-2017-08-04-00-48-01

Cela fonctionne bien évidemment par le biais du web et non pas qu’en local grâce au paramétrage de ma Box et aux redirections DDNS :

IMG_0277

Comme en atteste cette capture d’écran réalisée depuis mon smartphone en 4G, le site web répond parfaitement et mon serveur local également, de plus il rayonne sur internet depuis n’importe quel point de connexion.

Question cruciale : et la vitesse ?

Merci de poser la question. Cela va bien mieux (on parle tout de même de millisecondes pour ouvrir un site web). La comparaison est toutefois difficile au vu des conditions d’hébergement. En effet, j’héberge mon site sur un serveur perso’ installé en local chez moi et branché en ethernet directement derrière ma Box, pour rappel :

IMG_0302

Malheureusement au vu de mon faible débit proposé actuellement par mon fournisseur d’accès internet (ce qui va changer en fin d’année avec l’arrivée de la fibre à l’abonné sur Bourg-lès-Valence), il apparaît comme très difficile de proposer un service digne d’un hébergeur spécialisé avec lequel j’ai mené des tests comparatifs. Ci-dessus on peut noter que ma bande passante propose un débit descendant de 7 Mégas… ça laisse rêveur.

Et voici la différence mesuré par l’outil Pingdom Website Speed Test

Capture-du-2017-08-05-11-21-38

Comparé avec mon blog hébergé chez Hostinger avec un hébergement classique sans surcoût :

On constate plusieurs différences à première vue :

  • Le lieu du ping est identique (Stockholm, c’est volontaire évidemment),
  • Le site hébergé est mieux classé que mon blog en terme de qualité générale 94 > 85,
  • Le blog est évidemment plus lourd qu’une simple page web sans modification aucune,
  • Le blog répond toutefois beaucoup plus vite, à raison de 5,62 secondes en comparaison le site  hébergé répond en 18,05 secondes depuis Stockholm, ce qui est très long !

Les premiers résultats ne sont donc pas vraiment encourageant, je vais toutefois mener une expérimentation sur le même pied d’égalité cette fois.

VPS vs Hébergement classique chez le même hébergeur

J’ai donc choisi de poursuivre le test jusqu’au bout en comparant ce qui est comparable, c’est à dire la performance de la containeurisation de sites web grâce à Alpine Linux et sa légèreté sans égal. J’ai souscris à un VPS (Virtual Private Server) chez le même hébergeur que mon blog ou mon site web, pour une durée d’un mois pour le moment.

J’ai fait le choix de partir sur la même configuration que mon serveur local (Ubuntu serveur et Docker CE)

Avec ce VPS auquel je me connecte via SSH grâce aux données fournies par mon hébergeur, je vais suivre le process d’installation de Docker sur la machine virtuelle :

*root@gabriel-sagnard:~# sudo apt-get install \ > apt-transport-https \ > ca-certificates \ > curl \ > software-properties-common

root@gabriel-sagnard:~# curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - OK*

Puis :

root@gabriel-sagnard:~# sudo add-apt-repository \ > "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ > $(lsbrelease -cs) \ > stable"

Un coup d’update :

root@gabriel-sagnard:~# sudo apt-get update Hit:1 http://archive.canonical.com/ubuntu xenial InRelease Hit:2 http://security.ubuntu.com/ubuntuxenial-security InRelease Hit:3 http://archive.ubuntu.com/ubuntu xenial InRelease Get:4 https://download.docker.com/linux/ubuntu xenial InRelease [38.9 kB] Hit:5 http://archive.ubuntu.com/ubuntu xenial-updates InRelease Get:6 https://download.docker.com/linux/ubuntuxenial/stable amd64 Packages [1966 B] Fetched 40.9 kB in 0s (56.8 kB/s) Reading package lists... Done

Et on peut lancer l’installation :

root@gabriel-sagnard:~# sudo apt-get install docker-ce

Puis on savoure, comme à chaque fois avec Docker :

root@vps441972:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4946decb11f2 evild/alpine-nginx:1.9.15-openssl "/init" 4 minutes ago Up 4 minutes 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp lempnginx b9d3b6522b45 evild/alpine-php:7.0.6 "/init" 4 minutes ago Up 4 minutes 9000/tcp lempphp 35dfdf3ced83 mariadb:latest "docker-entrypoint..." 14 hours ago Up 4 minutes 3306/tcp lempmariadb

Puis on se replace dans le dossier où l’on va poser notre dossier web et on l’injecte depuis mon dépôt Github du framework Materialize:
 
root@vps441972:~# cd docker-compose-lemp/html
root@vps441972:~/docker-compose-lemp/html# ls
index.php
root@vps441972:~/docker-compose-lemp/html# git clone https://github.com/gabrielsagnard/materialize.git Cloning into 'materialize'... remote: Counting objects: 27, done. remote: Compressing objects: 100% (25/25), done. remote: Total 27 (delta 2), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (27/27), done. Checking connectivity... done. root@vps441972:~/docker-compose-lemp/html# ls index.php materializeroot@vps441972:~/docker-compose-lemp/html#

Et enfin on vérifie en page web à l’adresse ip de notre VPS :
 
Capture-du-2017-08-06-14-23-50

Ok c’est fonctionnel à l’adresse ip et le dossier de notre site web, on va maintenant pouvoir comparer :
 
– Notre VPS avec le même template web tournant sur les mêmes containeurs Alpine Linux que mon serveur local ET mon blog par exemple, en suivant la même procédure que précédemment :

Capture-du-2017-08-06-14-27-53-1

OUTCH !! pour rappel le résultat obtenu au test par mon blog :

Capture-du-2017-08-05-11-23-47-1

Cela fait quand même très mal ! Alpine Linux s’avère extraordinairement performant par rapport à un blog tournant sur WordPress, certes réputé comme lent, mais hébergé de la même façon chez un hébergeur spécialisé et non en local.
 
Le site s’ouvre en 378 ms (!!) depuis Stockholm et s’avère plus rapide que 98% des sites web (!!). Le reste des données parlent d’elles-même…
 
Pour le fun on va comparer ce résultat à un site mondialement connu et puissant, certes beaucoup plus chargé en contenu mais avec une redondance assurée par des serveurs dans le monde entier, j’ai nommé Netflix :

Capture-du-2017-08-06-14-35-48

On note qu’en terme de taille il y a un écart léger 1 MB pour Netflix.com et 939 KB pour mon VPS, Netflix s’ouvrant en 1,82 secondes et présentant une vitesse supérieure à 74 % des sites web.
Conclusion

Alpine Linux est donc une véritable aubaine pour le monde du Caas, Container as a service, et présente en combinaison avec Docker, un vrai plus pour le portage de sites web. Le principal avantage, nous l’avons vu étant sa taille infime et donc sa vitesse d ‘exécution.