L'application web Wordpress nécessite :
- Un serveur Web (Apache2, Nginx)
- PHP (8.x)
- Un serveur de base de données (MySQL)
Pendant cet atelier nous allons donc de démarrer une stack applicative complète à l'aide de containers.
________________________________________________________
______________ | _____________ __________ __________ |
| | | | | | | | | |
| Navigateur | <-> | | Nginx | <-> | PHP | <-> | MySQL | |
| Web | | | | | FPM | | | |
|____________| | |___________| |_________| |_________| |
| |
|____________________Docker____________________________|
- Le navigateur web se connecte sur le port 80 (http) d'une IP.
- Le serveur Nginx demande à PHP-FPM d'interpréter les fichiers PHP.
- Lors de cette interprétation PHP-FPM va aller chercher des données dans la base de données MySQL.
Pour pouvoir lancer notre stack en une seule ligne de commande, nous allons utiliser docker compose.
Suivre la procédure d'installation de docker-compose version 2.x. sur la VM Ubuntu 18.04 de la semaine dernière, celle où vous aviez installer Docker.
sudo apt-get remove docker docker-engine docker.io containerd runc
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg lsb-release
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get -y install docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo usermod -aG docker $USER
newgrp docker
docker run hello-world
Cela se traduit par une utilisation de la commande :
docker compose <cmd>
Profitez-en pour install git et jq.
En effet nous profiterons de ce TP pour appréhender cet outils.
apt-get update
apt-get -y install jq git
Toutes les actions suivantes seront réalisées dans un répertoire "atelier". Cloner le repo du TP avec la commande suivante, et placez-vous dedans.
git clone https://github.com/hlepesant/tppolytech.git --single-branch atelier
cd atelier
Le script télécharge la dernière version de Wordpress francisée,
décompresse l'archive dans le répertoire "wordpress",
créer quelques répertoires pour le bon fonctionnement de l'application,
et prépare le fichier de configuration de wordpress (wordpress/wp-config.php).
Nous utiliserons plus tard ce répertoire comme volume partagé avec Docker.
chmod +x getwp.sh
./getwp.sh
Contient une configuration de Nginx.
L'objectif n'étant pas d'apprendre à configure ce serveur web,
vous utiliserez un volume Docker pour monter le répertoire
nginx/config/conf.d
dans le répertoire /etc/nginx/conf.d
d'un container Nginx.
Le service PHP (son container) sera buildé.
Modifier le Dockerfile
fourni pour builder votre image PHP.
Toujours dans ce répertoire "atelier", créez le fichier docker-compose.yml.
Docker-compose utilise la syntax YAML.
Ce fichier est divisé en plusieurs éléments de "haut niveau" :
Les spécifications complète d'un fichier docker-compose.yml peuvent être trouvées ici, mais nous allons faire simple en n'utilisant que :
C'est parti, utilisez votre éditeur de texte préféré pour créer le fichier docker-compose.yml.
vi docker-compose.yml
Ajouter les lignes suivantes à votre fichier docker-compose.yml.
version: '3.8'
Avec "volumes" nous allons pouvoir créer des volumes de différents types, et les
partager entre différents services sans passer par l'option "volume_from".
Ainsi nous pouvons créer des volumes persistant et ne plus perdre les données
entre deux démarrages de container.
Notre premier volume sera celui de la base de données.
Nous l'attacherons dans un deuxième temps au service MySQL.
Nous appellerons ce volume "bdd_data".
Modifions le fichier docker-compose.yml en ajoutant la section suivante :
volumes:
bdd_data:
Lancer les commandes :
docker compose config
docker compose up -d
Qu'observez-vous ?
Lancer les commandes :
docker compose ps
docker volume list
Notez le nom du volume. Docker-compose a nommé le volume avec pour préfix le répertoire dans lequel la commande "docker-compose" a été lancée.
Maintenant inspectons le volume :
docker volume inspect atelier_bdd_data | jq .
docker volume inspect atelier_bdd_data | jq .[0]
docker volume inspect atelier_bdd_data | jq .[0].Mountpoint
Observez la coloration syntaxique offerte par "jq".
Et l'utilisation de filtre pour afficher les informations voulues.
Afficher le contenu du répertoire correspondant au "Mountpoint".
Que notez-vous ?
Dans cette section, nous allons définir les trois services suivants :
- bdd : pour le container MySQL
- php : pour le container PHP
- web : pour le container Nginx
Il existe une image Docker MySQL officielle.
Nous allons l'utiliser pour notre service "bdd".
Rechercher dans la documentation de l'image MySQL comment faire pour :
- Définir un mot de passe pour l'utilisateur "root" de MySQL ?
- Définir un username, et son mot de passe, autre que "root" ?
- Créer automatiquement une base de données "wordpress" ?
- Contourner le plugin d'authentification de MySQL 8, et revenir au plugin natif
Et dans la documentation sur les volumes, comment utiliser notre volume "bdd_data" défini plus haut.
solution service bdd
services:
bdd:
image: mysql:8.0
command: --default-authentication-plugin=mysql_native_password
volumes:
- bdd_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: password
Une fois que le fichier docker-compose.yml est sauvegardé, lancer les commandes :
docker compose up -d
docker compose logs -f
docker compose logs bdd | grep Entrypoint
- Qu'observez-vous ?
- Le container MySQL est-il toujours actif ?
- La base de données "wordpress" a-t-elle été créée ?
- Comment ?
- Afficher à nouveau le contenu du répertoire correspondant au "Mountpoint" du volume "bdd_data"
Exécuter la commande suivante :
docker compose exec -- bdd bash -c 'mysql -uroot -p$MYSQL_ROOT_PASSWORD'
Que s'est il passé ? Comparer les commandes :
docker compose exec -- bdd bash -c 'mysql -uroot -p$MYSQL_ROOT_PASSWORD'
et
docker exec -ti <CONTAINER_ID> bash -c 'mysql -uroot -p$MYSQL_ROOT_PASSWORD'
en remplaçant '<CONTAINER_ID>' par l'ID du container de la commande docker ps
.
En effet, vous êtes connecté à la base de données.
Nous allons afficher les bases de données existantes :
mysql> show databases;
Voyez-vous la base de données wordpress
?
Remarques:
Les variables d'environnement sont très souvent utilisées pour passer des options aux images Docker.
Il existe des images Docker pour PHP, cependant nous allons construire notre propre image avec un Dockerfile, en se basant sur l'image debian:bookworm-slim
Toujours dans le répertoire "atelier", utiliser le sous-répertoire "phpfpm".
vi phpfpm/Dockerfile
A noter que l'installation de PHP-FPM sur un serveur ou une machine virtuelle pourrait être fait par le script shell suivant :
export DEBIAN_FRONTEND="noninteractive"
apt-get update
apt-get install apt-transport-https lsb-release ca-certificates gnupg2 procps \
php8.2-common php8.2-cli php8.2-fpm php8.2-mysql php8.2-apcu php8.2-gd \
php8.2-imagick php8.2-curl php8.2-intl php8.2-redis
apt-get clean
apt-get autoclean
mkdir -p /var/run/php
Il faudra aussi modifier quelques fichiers.
Cependant comme vous ne pouvez pas utiliser un éditeur de texte lors du build
d'une image
/etc/php/8.2/fpm/php.ini
- Pour augmenter la verbosité de PHP-FPM :
sed -i 's/error_reporting = .*/error_reporting = E_ALL/' /etc/php/8.2/fpm/php.ini
/etc/php/8.2/fpm/php-fpm.conf
- Faire en sorte que PHP-FPM, ne soit pas lancer en arrière plan.
sed -i 's/\;daemonize.*/daemonize = no/' /etc/php/8.2/fpm/php-fpm.conf
- Rediriger les logs vers la sortie standard :
sed -i 's/error_log = .*/error_log = \/proc\/self\/fd\/2/' /etc/php/8.2/fpm/php-fpm.conf
/etc/php/8.2/fpm/pool.d/www.conf
- Configuration d'un "pool" de PHP-FPM :
sed -i 's/\;clear_env = .*/clear_env = no/' /etc/php/8.2/fpm/pool.d/www.conf
sed -i 's/^listen = .*/listen = 0.0.0.0:9000/' /etc/php/8.2/fpm/pool.d/www.conf
Je vous invite à le traduire en Dockerfile les indications ci-dessus.
A noter que le port 9000 sera exposé, et que le service PHP et Nginx doivent
partager les sources de Wordpress selon le même PATH. Cela se fera sous la forme
d'un volume Docker.
N.B:
Il est aussi possible de copier les fichiers présents dans phpfpm/config/ au bon
endroit et ne pas faire de sed en pagaille.
ADD ./config/php.ini /etc/php/8.2/fpm/php.ini
ADD ./config/php-fpm.conf /etc/php/8.2/fpm/php-fpm.conf
ADD ./config/pool.d/www.conf /etc/php/8.2/fpm/pool.d/www.conf
solution Dockerfile php
FROM debian:bookworm-slim
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update \
&& apt-get -y install apt-transport-https \
lsb-release \
ca-certificates \
gnupg2 \
procps \
php8.2-common \
php8.2-cli \
php8.2-fpm \
php8.2-mysql \
php8.2-apcu \
php8.2-gd \
php8.2-imagick \
php8.2-curl \
php8.2-intl \
php8.2-redis \
net-tools \
default-mysql-client \
&& apt-get clean \
&& apt-get autoclean
RUN sed -i 's/error_reporting = .*/error_reporting = E_ALL/' /etc/php/8.2/fpm/php.ini
RUN sed -i 's/\;daemonize.*/daemonize = no/' /etc/php/8.2/fpm/php-fpm.conf
RUN sed -i 's/error_log = .*/error_log = \/proc\/self\/fd\/2/' /etc/php/8.2/fpm/php-fpm.conf
RUN mkdir -p /var/run/php
VOLUME /usr/share/nginx/html
EXPOSE 9000
CMD ["/usr/sbin/php-fpm8.2", "--nodaemonize"]
Maintenant que votre Dockerfile build une image Docker. Intégrer la dans le fichier docker-compose.yml.
Il faudra ajouter :
- les variables d'environment que vous retrouverez dans le fichier "wordpress/wp-config.php" créer par le script "getwp.sh".
- le volume correspondant au répertoire contenant les sources de Wordpress,
- lié le service "php", au service "bdd".
Vous pouvez vous baser sur le template présent dans le répertoire "phpfpm".
solution service php
php:
build:
context: ./phpfpm
volumes:
- ./wordpress:/usr/share/nginx/html
environment:
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: password
MYSQL_HOST: bdd
links:
- bdd
Lancer les commandes suivantes :
docker compose up -d
docker compose ps
docker composer logs
Qu'observer vous ?
Comme pour MySQL, nous allons utiliser l'image officielle
pour le service web.
Le port 80 du container sera exposé et accessible par le port 8000.
Le container nginx sera "linké" au container php-fpm.
Il y aura deux volumes :
- le source de Wordpress
- un répertoire contenant un fichier de configuration d'un hôte virtuel
Le but de l'atelier n'étant pas d'apprendre à configurer Nginx. Une version est proposé dans le répertoire "nginx/conf.d/" (cf commande ci-dessous). Ce répertoire sera le deuxième volume à monter dans le container.
Nous allons utiliser le fichier de configuration "default.conf" du répertoire "nginx/conf.d/" :
solution service web
web:
image: nginx:mainline
volumes:
- ./wordpress:/usr/share/nginx/html
- ./nginx/conf.d:/etc/nginx/conf.d
ports:
- "8000:80"
links:
- php
Lancer les commandes suivantes :
docker compose up -d
docker compose ps
docker composer logs
Qu'observez-vous ?
Lancer votre navigateur et connecter vous sur l'url : http://:8000/
docker compose stop
docker compose rm