tag:linuxfr.org,2005:/users/albangLinuxFr.org : les contenus de albang2015-03-10T22:00:20+01:00/favicon.pngtag:linuxfr.org,2005:Diary/356212015-02-17T12:39:57+01:002015-02-17T13:36:27+01:00Migration d'une infra lamp vers dockerLicence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr<h2 class="sommaire">Sommaire</h2>
<ul class="toc">
<li><ul>
<li><a href="#intro">Intro</a></li>
<li>
<a href="#linfra">L'infra</a><ul>
<li><a href="#dockerfile">DockerFile</a></li>
<li><a href="#la-conf-apache">la conf Apache</a></li>
</ul>
</li>
<li>
<a href="#le-apache-wordpress">Le apache "Wordpress"</a><ul>
<li><a href="#dockerfile-1">DockerFile</a></li>
<li><a href="#la-conf-apache-1">la conf apache</a></li>
</ul>
</li>
<li>
<a href="#data-only-container">Data only container</a><ul>
<li><a href="#dockerfile-2">DockerFile</a></li>
</ul>
</li>
<li>
<a href="#mysql">Mysql</a><ul>
<li><a href="#dockerfile-3">DockerFile</a></li>
</ul>
</li>
<li>
<a href="#fig">Fig</a><ul>
<li><a href="#figyaml">fig.yaml</a></li>
</ul>
</li>
</ul></li>
</ul><h3 id="intro">Intro</h3>
<p>Lecteur de linuxfr depuis un bon bout de temps, voici ma première contribution.<br>
Dans cet article, je vous montrerai comment j'ai migré un site web qui tournait sur un serveur dédié vers docker en isolant chaque service dans un container</p>
<h3 id="linfra">L'infra</h3>
<p>Elle est constituée d'<strong>un serveur web</strong> avec quelques sites web et d'<strong>un serveur mysql</strong>.<br>
Pour coller avec la philosophie docker, j'ai isolé chaque site web dans un container.<br>
L'idée est de facilement pouvoir migrer un site web sans impacter le reste.</p>
<p>l'infra est constituée de : </p>
<ul>
<li> un container <strong>reverse-proxy Apache</strong> qui va orienter les requêtes vers les différents sites web</li>
<li> un container <strong>apache</strong> qui va servir le WordPress</li>
<li> un container <strong>data</strong> où le contenu du WordPress sera stocké</li>
<li> un container <strong>Mysql</strong> où sera hébergée la base de données
<img src="//img.linuxfr.org/img/68747470733a2f2f7261772e67697468756275736572636f6e74656e742e636f6d2f616c62616e672f616c62616e672e6769746875622e696f2f6d61737465722f6173736574732f6d656469612f696e667261646f636b65722e706e67/infradocker.png" alt="schema docker" title="Source : https://raw.githubusercontent.com/albang/albang.github.io/master/assets/media/infradocker.png">
## Le reverse proxy</li>
</ul><p>Pourquoi utiliser un reverse proxy ?</p>
<p>il est nécessaire de lier un port d'un container à un port de la machine hôte pour que le container soit joignable de l’extérieur.<br>
Si je décide de lancer deux containers de site web, seul le premier pourra être lié au port 80 (port standard pour le HTTP).<br>
Le second devra être lié à un autre port.<br><br>
C'est techniquement faisable mais très peu pratique.<br>
Pour remédier à cela, j'ai créé un container jouant le role de reverse-proxy.<br>
Ce container est lié au port 80 de la machine hôte et il va jouer le rôle de "passe plat".<br>
Il va rediriger les requêtes sur les container adéquat grâce au nom de serveur demandé (directive servername) dans les requêtes http.</p>
<p>Le reverse proxy n'existait pas dans ma précédente infra car tous les sites étaient sur le même Apache.</p>
<h4 id="dockerfile">DockerFile</h4>
<pre><code class="docker"><span class="k">FROM</span> ubuntu:14.04
<span class="k">MAINTAINER</span> Alban Garrigue <aban@garrigue.me>
<span class="k">RUN</span> apt-get update
<span class="k">RUN</span> apt-get install -y apache2
<span class="k">RUN</span> a2enmod proxy
<span class="k">RUN</span> a2enmod proxy_http
<span class="k">ENV</span> APACHE_RUN_USER www-data
<span class="k">ENV</span> APACHE_RUN_GROUP www-data
<span class="k">ENV</span> APACHE_LOG_DIR /var/log/apache2
<span class="k">ADD</span> ./alban.garrigue.me.conf /etc/apache2/sites-available/
<span class="k">RUN</span> a2ensite alban.garrigue.me.conf
<span class="k">ENV</span> APACHE_PID_FILE /var/run/apache2.pid
<span class="k">ENV</span> APACHE_RUN_DIR /var/run/apache2
<span class="k">ENV</span> APACHE_LOCK_DIR /var/lock/apache2
<span class="k">RUN</span> mkdir -p <span class="nv">$APACHE_RUN_DIR</span> <span class="nv">$APACHE_LOCK_DIR</span> <span class="nv">$APACHE_LOG_DIR</span>
<span class="k">ADD</span> ./alban.garrigue.me.conf /etc/apache2/sites-available/
<span class="k">RUN</span> a2ensite alban.garrigue.me.conf
<span class="k">RUN</span> a2dissite 000-default.conf
<span class="k">ENTRYPOINT</span> <span class="o">[</span><span class="s2">"/usr/sbin/apache2"</span><span class="o">]</span>
<span class="k">CMD</span> <span class="o">[</span><span class="s2">"-D"</span>, <span class="s2">"FOREGROUND"</span><span class="o">]</span></code></pre>
<h4 id="la-conf-apache">la conf Apache</h4>
<pre><code class="apache"><span class="nt"><VirtualHost</span> <span class="s">*:80</span><span class="nt">></span>
<span class="nb">ServerName</span> alban.garrigue.me
<span class="nb">ProxyPreserveHost</span> <span class="k">On</span>
<span class="nb">ProxyRequests</span> <span class="k">off</span>
<span class="nb">ProxyPass</span> / http://alban.garrigue.me/
<span class="nb">ProxyPassReverse</span> / http://alban.garrigue.me/
<span class="nt"></VirtualHost></span></code></pre>
<h3 id="le-apache-wordpress">Le apache "Wordpress"</h3>
<h4 id="dockerfile-1">DockerFile</h4>
<pre><code class="docker"><span class="k">FROM</span> ubuntu:14.04
<span class="k">MAINTAINER</span> Alban Garrigue <aban@garrigue.me>
<span class="c">#RUN apt-get update</span>
<span class="k">RUN</span> apt-get update <span class="o">&&</span> apt-get install -y apache2 php5 php5-mysql
<span class="k">ENV</span> APACHE_RUN_USER www-data
<span class="k">ENV</span> APACHE_RUN_GROUP www-data
<span class="k">ENV</span> APACHE_LOG_DIR /var/log/apache2
<span class="k">ENV</span> APACHE_PID_FILE /var/run/apache2.pid
<span class="k">ENV</span> APACHE_RUN_DIR /var/run/apache2
<span class="k">ENV</span> APACHE_LOCK_DIR /var/lock/apache2
<span class="k">RUN</span> mkdir -p <span class="nv">$APACHE_RUN_DIR</span> <span class="nv">$APACHE_LOCK_DIR</span> <span class="nv">$APACHE_LOG_DIR</span>
<span class="k">ADD</span> ./alban.garrigue.me.conf /etc/apache2/sites-available/
<span class="k">RUN</span> a2ensite alban.garrigue.me.conf
<span class="k">RUN</span> a2dissite 000-default.conf
<span class="k">RUN</span> a2enmod rewrite
<span class="k">RUN</span> a2enmod expires
<span class="k">RUN</span> a2enmod headers
<span class="k">RUN</span> a2enmod cgi
<span class="k">EXPOSE</span> <span class="m">80</span>
<span class="k">ENTRYPOINT</span> <span class="o">[</span><span class="s2">"/usr/sbin/apache2"</span><span class="o">]</span>
<span class="k">CMD</span> <span class="o">[</span><span class="s2">"-D"</span>, <span class="s2">"FOREGROUND"</span><span class="o">]</span></code></pre>
<h4 id="la-conf-apache-1">la conf apache</h4>
<p>La conf apache est assez standard </p>
<pre><code class="apache"><span class="nt"><VirtualHost</span> <span class="s">*:80</span><span class="nt">></span>
<span class="nb">DocumentRoot</span> <span class="sx">/var/www/alban.garrigue/</span>
<span class="nb">ServerName</span> alban.garrigue.me
<span class="nt"><Directory</span> <span class="s">/var/www/alban.garrigue</span><span class="nt">></span>
<span class="nb">Options</span> FollowSymLinks MultiViews
<span class="nb">AllowOverride</span> <span class="k">None</span>
<span class="nb">Order</span> allow,deny
<span class="nb">allow</span> from <span class="k">all</span>
<span class="nt"></Directory></span>
<span class="nt"><Directory</span> <span class="s">/var/www/alban.garrigue/blog</span><span class="nt">></span>
<span class="nb">Options</span> FollowSymLinks
<span class="nb">AllowOverride</span> <span class="k">All</span>
<span class="nt"></Directory></span>
<span class="nt"></VirtualHost></span></code></pre>
<p>Ce que j'ai du changer dans les fichiers de configuration du WordPress: </p>
<ul>
<li> L'adresse de la base de données dans le wp-config.php
<ul>
<li> changer 127.0.0.1 par dbalban (à voir dans le fig.yaml)</li>
</ul>
</li>
</ul><h3 id="data-only-container">Data only container</h3>
<p>Le concept de container de données est relativement simple.<br>
On ajoute des données à l'image, puis on les expose avec un volume.<br>
L'avantage de ce type de container est qu'ils n'ont pas besoin de tourner pour que les autres aient accès à leur données.<br>
Cependant il ne bénéficie pas du système de fichier unionfs et les données ne sont pas incluses dans la sauvegarde du container.</p>
<p>Pour sauvegarder ces données: </p>
<pre><code class="bash">sudo docker run -rm --volumes-from DATA -v <span class="k">$(</span><span class="nb">pwd</span><span class="k">)</span>:/backup busybox tar cvf /backup/backup.tar /data</code></pre>
<p>Pour restaurer les données:</p>
<pre><code class="bash">sudo docker run -rm --volumes-from DATA2 -v <span class="k">$(</span><span class="nb">pwd</span><span class="k">)</span>:/backup busybox tar xvf /backup/backup.tar</code></pre>
<p>source: <a href="http://stackoverflow.com/questions/21597463/how-to-port-data-only-volumes-from-one-host-to-another">Stackoverflow</a></p>
<p>Vous voyez ci dessous qu'il n'y a rien de compliqué.</p>
<h4 id="dockerfile-2">DockerFile</h4>
<pre><code class="docker"><span class="k">FROM</span> stackbrew/busybox:latest
<span class="k">MAINTAINER</span> Tom Offermann <tom@offermann.us>
<span class="c"># Create data directory</span>
<span class="c">#RUN mkdir /var/www/</span>
<span class="k">ADD</span> alban.garrigue /var/www/alban.garrigue
<span class="c"># Create /data volume</span>
<span class="k">VOLUME</span> /var/www/</code></pre>
<h3 id="mysql">Mysql</h3>
<p>Je me suis basé sur ce dépôt <a href="https://github.com/tutumcloud/tutum-docker-mysql.git">github</a></p>
<p>Ce que j'ai modifié dans le DockerFile:</p>
<ul>
<li>Ajout dump sql pour charger la base </li>
<li>Ajout du login/mot de passe du compte wordpress en variables d'environnement</li>
<li>Ajout du path de mon dump sql pour l'import</li>
</ul><h4 id="dockerfile-3">DockerFile</h4>
<pre><code class="docker"><span class="k">ADD</span> wordpress-alban.sql /tmp/wordpress-alban.sql
<span class="c"># Exposed ENV</span>
<span class="k">ENV</span> MYSQL_USER <user>
<span class="k">ENV</span> MYSQL_PASS <mot de passe>
<span class="k">ENV</span> STARTUP_SQL /tmp/wordpress-alban.sql</code></pre>
<h3 id="fig">Fig</h3>
<p><a href="http://www.fig.sh/">Fig.sh</a> permet d'orchestrer le lancement des containers et de les lier entre eux<br>
il va résoudre les liens de dépendances pour trouver le bon ordonnancement.<br>
Les links vont servir de liens entre les containers en utilisant les fichiers /etc/hosts.<br>
Ainsi il faut faire abstraction des adresses IP et raisonner en nom de container.<br>
Le fichier fig.yaml permet de lancer clairement des containers avec des options spécifiques.<br>
Personnellement je trouve ça plus clair qu'une ligne de commande à rallonge.</p>
<h4 id="figyaml">fig.yaml</h4>
<pre><code class="yaml"><span class="l-Scalar-Plain">reverse</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">image</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">reverse-proxy</span>
<span class="l-Scalar-Plain">ports</span><span class="p-Indicator">:</span>
<span class="p-Indicator">-</span> <span class="s">"80:80"</span>
<span class="l-Scalar-Plain">links</span><span class="p-Indicator">:</span>
<span class="p-Indicator">-</span> <span class="l-Scalar-Plain">webalban:alban.garrigue.me</span>
<span class="l-Scalar-Plain">webalban</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">image</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">alban-garrigue-apache</span>
<span class="l-Scalar-Plain">volumes_from</span><span class="p-Indicator">:</span>
<span class="p-Indicator">-</span> <span class="l-Scalar-Plain">webalbanstockage</span>
<span class="l-Scalar-Plain">links</span><span class="p-Indicator">:</span>
<span class="p-Indicator">-</span> <span class="l-Scalar-Plain">dbalban</span>
<span class="l-Scalar-Plain">dbalban</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">image</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">alban-garrigue-mysql</span>
<span class="l-Scalar-Plain">webalbanstockage</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">image</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">alban-garrigue-data</span></code></pre>
<p>Résumé :</p>
<p>Ça serait vous mentir si je vous dis que tout cela est tombé sous le sens du premier coup.<br>
J'ai eu du mal à comprendre la persistance des données, les concepts d'images et de containers.<br>
Les containers sont le résultat de l'instanciation d'une image.<br>
Les données à l’intérieur sont aussi pérennes que le container.<br>
Le container est arrêtable et redémarrable, si votre docker plante tout n'est pas perdu.<br>
Cependant si vous ré-instanciez l'image, vous ne bénéficierez pas des données du conteneur précédent.<br>
Les topics de stack overflow sont une source d'information précieuse.<br>
Tout ce petit monde avance très vite et de nombreux outils se développent.</p>
<p>Je vais prochainement tester :<br><br>
weave qui permet de gérer la partie réseau inter container et multi host (intéressant)<br>
consul qui fait de la découverte de service</p><div><a href="https://linuxfr.org/users/albang/journaux/migration-d-une-infra-lamp-vers-docker.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/104829/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/albang/journaux/migration-d-une-infra-lamp-vers-docker#comments">ouvrir dans le navigateur</a>
</p>
albanghttps://linuxfr.org/nodes/104829/comments.atom