Mon blog est depuis le début servi par Apache2 et MySQL. Au début ça tournait bien, mais je commence à me rendre compte que niveau performances, je peux faire mieux ! Après pas mal de recherches, j’ai opté pour un VPS SSD chez OVH. Quand aux technologies utilisées, j’opte pour Nginx et PHP7 sur du Docker, le tout managé par Docker-Compose. Le blog sera bien sûr en HTTPS géré par Let’s Encrypt.
Je vais donc vous détailler ma migration, cela pourrait aider ceux qui souhaiteraient faire le « grand » pas. Cette migration peut s’appliquer à n’importe quel site WordPress.
I- Récupérer les données du blog
Avant de commencer à migrer mon blog, j’ai dû récupérer les données de l’ancien encore en ligne afin de préparer le nouveau et pouvoir migrer sans interruption.
Il y a deux choses à récupérer sur un blog WordPress, vos fichiers du site (wp-content/ et wp-config.php) et votre base de données.
Pour les fichiers il suffit de les récupérer en SFTP (par exemple) et de les mettre de côté dans une archive. Pour la base de données, il faut se rendre sur votre serveur et effectuer un dump, comme ceci :
mysqldump -u [username] -p [database_name] > [blog.sql]
A partir de maintenant, on peut préparer notre nouveau site.
II- Installation de Docker et Docker-Compose
On va donc pouvoir maintenant installer docker-engine et docker-compose afin qu’ils puissent créer et gérer notre WordPress containérisé.
Supposons que vous partiez sur une base Debian Jessie (une bonne idée), on va ajouter la clé du dépot :
apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
On ajoute le fichier docker.list :
echo "deb https://apt.dockerproject.org/repo debian-jessie main" > /etc/apt/sources.list.d/docker.list
On installe ensuite docker-engine :
apt-get update ; apt-get install docker-engine
service docker start
Maintenant que Docker est installé et opérationnel, on peut installer Docker-compose :
apt-get install python-pip pip install docker-compose
Voilà, tous nos outils sont installés, on va pouvoir préparer notre site.
III- Préparation des containers
Pour mettre en place notre stack WordPress, nous allons déployer 3 containers :
- Nginx qui sera exposé sur TCP/80 et TCP/443
- WordPress-FPM-7.0 pour PHP 7.0
- Mariadb pour la base de données
L’image WordPress-fpm-7.0 est une image de WordPress modifié pour installer php7.0 au lieu de 5.6, il nous faudra donc la construire.
(Merci à Mercurenews pour l’astuce)
On va donc commencer par créer cette image avant tout, pour cela il faut cloner le dépot Git de l’image WordPress :
git clone https://github.com/docker-library/wordpress.git .
cd fpm
FROM php:7.0-fpm
On construit ensuite l’image :
docker build -t wordpress-fpm-7.0 .
Maintenant qu’on a construit notre image de PHP7.0, on va pouvoir lancer la construction de notre stack.
Je vous conseille de créer un répertoire où vous gérerez tous les fichiers de votre blog, par exemple /srv/Blog. On va donc créer notre fichier /srv/Blog/docker-compose.yml afin de gérer le lancement de tous nos containers.
wp_db: image: mariadb:latest restart: always volumes: - ./var/mysql:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: yourpassword wp_web: image: nginx restart: always ports: - 80:80 - 443:443 log_driver: syslog links: - wp_php volumes: - ./wp:/var/www/html - ./etc/nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./var/log/nginx:/var/log/nginx - ./etc/letsencrypt:/etc/letsencrypt - ./etc/nginx/certs/dhparam.pem:/etc/nginx/certs/dhparam.pem wp_php: image: wordpress-fpm-7.0 restart: always links: - wp_db:mysql volumes: - ./wp:/var/www/html environment: WORDPRESS_DB_NAME: blogdb WORDPRESS_TABLE_PREFIX: blog_ WORDPRESS_DB_PASSWORD: yourpassword
Le premier bloc lance MariaDB avec un mot de passe de votre choix et avec un volume dans votre répertoire courant (/srv/Blog/var/mysql).
Le second bloc lance Nginx qui expose 80 et 443, relié à PHP et avec plusieurs volumes, tous situés dans /srv/Blog (à cause du ./).
Le dernier bloc lance PHP-Fpm 7.0 relié à MariaDB avec un volume « wp » qui correspond au répertoire WordPress (le / de votre serveur web).
Notre docker-compose est maintenant prêt à lancer notre blog, on va cependant s’occuper de configurer l’HTTPS avant de le lancer.
III- Mise en place de l’HTTPS
Let’s Encrypt permet d’avoir des certificats vérifiés gratuitement sur votre domaine. Pour mettre en place le SSL Let’s Encrypt sur notre serveur, rien ne plus simple, on va lancer un container pour créer les certificats puis on va configurer correctement Nginx. On lance donc le bon container :
sudo docker run -it --rm -p 443:443 -p 80:80 --name letsencrypt \
-v "/srv/Blog/etc/letsencrypt:/etc/letsencrypt" \
-v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
quay.io/letsencrypt/letsencrypt:latest auth
Notez que le /etc/letsencrypt du container est directement relié avec notre dossier de configuration pour le blog (/srv/Blog). Le container va vous demander une adresse e-mail, de confirmer les conditions d’utilisations et enfin de saisir votre domaine (blog.ouvrard.it dans mon cas). Les certificats doivent être générés dans /srv/Blog/etc/letsencrypt.
On génère ensuite un fichier DHPARAM (Openssl) afin d’avoir une sécurité SSL forte :
cd /srv/Blog/nginx/certs/ ; openssl dhparam -out dhparam.pem 4096
IV- Lancement de la migration
cd /srv/Blog ; docker-compose up -d

Maintenant que nos containers sont démarrés, on va devoir importer l’ancienne base de données, pour cela, on va récupérer l’identifiant du container MariaDB afin de lui injecter notre fichier sql :
docker ps # repérer l'id de MariaDB
docker exec -i <id> mysql -uroot -pyourpassword < blog.sql
On peut ensuite importer notre répertoire wp-content/ et le fichier wp-config.php dans notre répertoire /srv/Blog/wp.
cd /srv/Blog/wp ; chown www-data:www-data * -R


Je vais effectuer quelques vérifications comme le temps de chargement et la qualité de la connexion SSL :
On peut dire que par rapport à l’ancien (désolé, je n’ai pas de chiffres), y’a pas photos !
Le plus pratique c’est que toutes mes données sont centralisées (dans le dossier /srv/Blog) donc pour les sauvegardes et les éventuelles autres migrations ce sera beaucoup plus simple.
Voici quelques liens qui m’ont été bien utiles pour cette migration :
- http://blog.nicolargo.com/2014/10/infra-lemp-docker.html
- https://mercurenews.com/certificat-ssl-gratuit-letsencrypt-sur-nginx-docker/
- http://depressiverobot.com/2015/02/19/mysql-dump-docker.html
- http://wpmarmite.com/migrer-wordpress-manuellement/
- https://mercurenews.com/wordpress-avec-nginx-et-php-fpm-sous-docker/
Faut-il tout reconstruire si on change de serveur ? Où installer docker et relancer les conteneurs suffit ?
Les données sont hors des containers car j’utilise des volumes. Le seul truc à faire si je change de serveur, c’est reconstruire l’image de php7.0 et ensuite monter mes containers.
Merci pour ce superbe billet.
Une question: quelle est la configuration VPS que tu as choisi chez OVH ?
Merci pour le compliment, ça fais plaisir.
Voici mon VPS :
VPS SSD 2
1 vCore
4 Go RAM
SSD 20 Go
5,99€ HT/mois
Super réactif je trouve, cependant je migrerais peut être chez Vultr qui me plaît beaucoup.
Merci pour ce post. Mais je me pose une question, concernant les mises à jour de WordPress et des modules par la suite : ça se passe comment dans ce cas ?
Perso j’aurai vu le code de wordpress (+ modules) dans un volume, pour le laisser faire sa tambouille tout seul, et ne relancer les conteneurs que lors de mise à jour des images php & co par exemple.
Hello Alexandre,
Pour la mis à jours de WP & des modules, cela se passe relativement comme une installation en dur étant donnée que ton code wordpress est externalisé du container. Pour ma part, je met Nginx et PHP à jours coté Docker et WordPress et ces plugins depuis l’interface ! 🙂 Cela répond à ta question ? En fait, ce qu’il ne faut pas faire, c’est utiliser l’image wordpress toute simple avec les données bloquées à l’intérieur car elle ne sont pas persistantes.
Hello
Merci pour ta réponse, mais je t’avoue que cela n’apparait pas clairement dans l’article que le code de wordpress est externalisé dans un volume vu que l’image wordpress utilisée au départ contient elle même le code.. Je pense que ça m’a un peu perturbé du coup 🙂
Mais dans ce cas, oui, si le code PHP de wordpress est dans un volume alors les mises à jour WP sont complètement indépendantes du conteneur. Là je comprends mieux 🙂
Merci.
En fait pour être totalement clair, toute les données sont externalisées (data+codeWP) dans un volume « wp ». Le fait d’utiliser l’image « wordpress » permet au premier lancement qu’il récupère la dernière version de WP, cependant si il y a déjà une installe présente, elle ne fais fait rien. Les données (images, uploads …) et le code (PHP de WordPress) sont de le même volume et mis à jours par l’interface WP au besoin.
Salut Valentin,
super article! j’ai une question, si je souhaite avoir plusieurs instance de wordpress sur le même serveur et que je ne dispose pas de la possiblité dont tu parles ici https://blog.ouvrard.it/2016/04/18/docker-plusieurs-ips/
Tu passerais par un container de type reverse proxy ?
Salut Hotfirenet,
Exactement, tu as vu juste, tu mets un reverse-proxy Nginx sur 80/443, puis tu exposes tout tes stacks WordPress sur des ports élevés, puis tu créer des vhosts pour chaque sites.
J’ai un petit projet en cours qui te simplifierais bien la tâches (Gestion de automatique de stacks wordpress/drupal avec auto création des vhosts et auto-génération Let’s encrypt…). Fais moi un petit mail si ça t’intérésse, je t’expliquerai mieux.
Hello, je t’ai mis un mail.
Hello Valentin, j’ai bien lu tout ton post et aimerais avoir de l’aide pour migrer mon exisant en mode dockerisé complet:
j’utilise actuellement 1 VPS OVH, avec une couche LAMP dessus.
J’ai plusieurs sites web totalement différents, dont plusieurs wordpress, un piwigo (php web gallery initialement) et un peu de statiques ainsi que des instances web pour tester des produits divers et variés de blogs ou autre… Avec un unique MySQL et Apache 2.4. PHP 5 je pense de mémoire, pas été regardé dernièrement mais je maintiens à jour régulièrement.
J’ai compris que je dois mettre un nginx en reverse-proxy en frontal, ok, puis autant d’autres instances nginx derrièrefaisant tourner les divers WP ou autres sites. J’envisage de mettre un MaraiDB derrière, autant être à jour partout et plutôt passer aussisur PHP 7, tant qu’à faire.
En revanche, j’aurais aussi un autre besoin: faire tourner un site en .Net via Monoet sans doute XPS (d’après les quelques lectures faites très récemment).
Mais je t’avoue que je n’arrive pas encore à avoir une vision claire de comment préparer et structurer proprement tous les containers dont j’aurai besoin pour assurer une migration douce et tranquille…
Donc indépendamment de ton outil qui peut sans doute répondre à tout ou partie de mon besoin, je suis preneur de tout conseil ou de liens vers des lectures complémentaires qui peuvent être bien plus détaillées et pointues pour trouver des exemples de conf « complexes » ou plus étoffées…
En gros, toute aide est la bienvenue !
Merci par avance,
Franck.
Salut Franck,
Pour tes questions, je te conseille de regarder cet ensemble de script que j’ai écrit : https://fadd.opsnotice.xyz/home/
Cela risque de bien t’aider.
N’hésite pas à me contacter par mail si tu as des questions.
A bientôt et désolé pour le temps de réponse.
WordPress tourne maintenant sur HHVM, je t’invite a essayer
Merci pour le conseil. J’avais testé il y a quelques mois, c’était pas encore assez stable. Je réessayerai peut-être. =)
Très bonne article merci.
J’ai une question cependant au niveau de la base de données, ça craint pas d’utiliser l’identifiant mysql root pour WordPress ? Est-ce cela ne serait pas mieux de lancer mysql_secure_installation et d’utiliser un compte spécial pour le WordPress ?
Pour améliorer encore la sécurité, pouvez-vous aussi désactiver les functions dangereuse via le php.ini
disable_functions =exec,passthru,shell_exec,system,proc_open,popen,exec,parse_ini_file,show_source
Salut,
Concernant l’utilisateur Root, il s’agit d’un serveur MySQL dédié à UNE application, et non du mutualisé, donc le fait d’utiliser root, n’a pas un impact énorme. Le problème qu’il pourrait se poser c’est qu’en cas de faille dans WordPress, l’attaquant pourrait « tout » faire sur le serveur SQL.
Tu peux si tu veux, lancer un mysql_secure_installation dans le shell du container MariaDB.
Vous pouvez également ajouter votre .ini dans le configuration de PHP-FPM.
🙂
Bonjour,
si on a notre base de données sur une serveur distant AWS RDS
comment modifie-t-on le docker-compose pour prendre en compte la base de donnée
distante?