Webpack/MariaDB/Apache/Php avec docker-compose

Classé dans : Programmation | 0

Dans cet article je vous explique comment configurer un ensemble de containers Docker pour faire du développement (React/JS/PHP) en local avec tous les outils nécessaires.

Je pars du principe que Docker est installé sur votre ordinateur, si ce n’est pas le cas c’est par ici site Docker

Le découpage choisi est totalement arbitraire vous pouvez très bien tout intégrer dans un seul container, même si cela sera ensuite moins flexible pour travailler sur plusieurs projets.

L’application prise en exemple est Shyrka V5. Cette nouvelle version est décomposée en deux modules distincts :

FrontOffice : Interface utilisateur HTML/JS (React, Javascript, CSS…)
BackOffice : API PHP pour les requêtes en BDD (framework MyMVC PHP)

Les containers

Pour ce projet 3 containers vont être utilisés :

  1. Webpack liveserver (nodejs) pour compiler le code REACT et afficher le front sur un navigateur
  2. Serveur BDD (MySQL ou MariaDB) pour la base de données SQL
  3. Serveur WEB Apache/PHP pour l’api PHP

Multi-environnements

Une autre contrainte que je me suis imposée. C’est la possibilité de pouvoir utiliser ces containers dans des environnements différents : Linux, MacOS, Windows. C’est pourquoi tous les chemins absolus des ressources sont gérés dans des fichiers xxx.env.

Images Docker

Au début j’ai voulu utiliser des images ‘allégées’ type Alpine-Linux mais des complications sont vite apparues lorsqu’il fallait modifier la configuration par défaut et installer de nouveaux logiciels. Surement un manque de connaissance de ma part pour ces images… Du coup, connaissant plutôt bien Debian, j’ai opté pour cette distribution comme base principale pour Apache/php. Alpine est néanmois utilisé pour l’image Webpack/nodeJS.

Concernant le container BDD, c’est l’image officielle qui est utilisée : Mariadb

Les fichiers pour la création des images sont minimalistes. le but étant de faire en sorte que l’image soit le plus générique possible et utilisable sur plusieurs projets et/ou par plusieurs développeurs.
Le fait d’avoir découper l’infra avec 3 containers apporte beaucoup de flexibilité.

Ci dessous les fichiers Dockerfile utilisés pour créer les 3 images. La commande à utiliser est simplement :

docker build -t nomImage -f FichierDockerfile .
Par exemple : docker build -t img-webpack -f Dockerfile.webpack .

Pour vérifier si l’image est bien créée : docker image ls

Dockerfile.apachephp (debian:latest)

Voici le Dockerfile utilisé pour créer cette image. Vous remarquez que 2 fichiers sont copiés dans l’image :

my-virtualhost.conf et my-php.ini. Ces deux fichiers permettent de configurer Apache et PHP selon vos besoins.

L’image ‘expose’ le port 80 (port http par défaut). Ce port sera ensuite ‘routé’ dans le container vers un port local (localhost:9999 par exemple).

FROM php:apache

## commande pour compléter l'image par défaut
RUN apt-get update && apt-get install --no-install-recommends -y vim  mariadb-client

## config virtualhost spécifique
COPY ./my-virtualhost.conf /etc/apache2/sites-available/000-default.conf

## activation module apache rewrite
RUN a2enmod rewrite

## configuration PHP + modules addtionnels
COPY ./my-php.ini /usr/local/etc/php/php.ini

RUN docker-php-ext-install mysqli
RUN docker-php-ext-install pdo_mysql
EXPOSE 80

Contenu du fichier my-virtualhost.conf, comme vous le voyez toutes les valeurs sont ‘locales’ au container et totalement indépendantes de la structure de votre projet sur la machine hôte. C’est la magie de Docker! pas besoin de créer des fichiers virtualhost pour chaque projet.

<VirtualHost *:80>

  ## Error apache pages
  ErrorDocument 500 "Erreur serveur"
  ErrorDocument 403 "No Access"
  ErrorDocument 404 "Page introuvable!"
  ErrorDocument 402 "Erreur 402"

  ServerAdmin webmaster@localhost
  DocumentRoot /var/www/html

  <Directory /var/www/html>
    AllowOverride All 
  </Directory>

</Virtualhost>

Dockerfile.webpack (alpine:latest)

Ici c’est l’image de base alpine:latest qui est utilisée. A noter :

/tmp/src est le dossier qui sera lié (dans le container) au dossier local contenant les fichiers sources (react,js,css…) du projet

/tmp/static sera lui lié au dossier de compilation (en général /build pour webpack/react) dans le projet

Le dossier de travail est défini sur /tmp/src, notamment pour lancer le liveserver (npm run dev).

Comme pour Apache, on expose ici le port http de webpack : 8000. Ce port sera routé sur localhost:8081 dans la configuration du container.

FROM alpine:latest
RUN apk add vim nodejs npm bash python3 make g++

## installationn paquets npm
RUN npm i -g webpack webpack-cli webpack-dev-server live-server gulp

## dossier utilisé pour monter le volume en lien avec le dossier SRC sur l'hote
RUN mkdir /tmp/src
RUN mkdir /tmp/static

## dossier virtuel qui sera lié au dossier du projet react
WORKDIR /tmp/src
## port server web webpack
EXPOSE 8000

Dockerfile.bdd (mariadb:10.10)

Pour le serveur SQL, c’est l’image officielle MariaDB:10.10 qui est utilisée.

Ici aussi un fichier local est copié dans l’image. Il permet une connexion automatique à MariaDB en mode console (lorsque l’on utilise le bash du container). Voici le contenu de my.cnf

[client]
user=root
password=root

L’image expose le port 3306. Cela est nécessaire si vous avez besoin d’accéder au serveur MariaDB depuis la machine hôte. Les accès depuis les autres containers se feront via le réseau Docker (voir ci dessous).

FROM mariadb:10.10

## commande pour compléter l'image par défaut 
RUN apt-get update && apt-get install --no-install-recommends -y vim 

## copy my.cnf pour connexionn auto mysql en bash avec compte root/root
COPY ./my.cnf /root/.my.cnf
  
EXPOSE 3306

CMD ["mysqld"]

Le réseau Docker

Les containers doivent communiquer entre eux, le serveur Apache/Php utilise le serveur BDD par exemple. Il est donc nécessaire de relier les containers dans un réseau virtuel Docker. Le plan d’adressage reste libre, dans l’exemple c’est la classe 192.168.2.0/24 qui est utilisée. Il n’est pas nécessaire de créer le réseau au préalable, car Docker-compose le créera automatiquement.

Les fichiers xxx.env

Pour utiliser ces images et container dans des environnements différents, plusieurs fichiers .env sont créés.

Chaque fichier correspondant à un système (MacOS, W10, Linux…). On pourrait pousser plus loin en ajoutant certaines valeurs (les ports, les adresses IP etc…) dans ces fichiers et notre infra serait totalement indépendante et flexible.

On peut également utiliser ces fichiers lorsque plusieurs développeur travaillent sur le même projet mais chaqu’un sur leur ordinateur et donc avec des dossiers différents.

Dans ce fichier il faut déclarer les variables qui seront utilisées dans Docker-compose.yml

fichier confg-w10.env

WEBPACK_SRC="d:/git/shyrka5"
WEBPACK_BUILD="d:/git/shyrka5/build"
ROOT_MYSQL="d:/git/_mysql"
ROOT_APIWEB="d:/git/shyrka5/build/api"

fichier config-mac.env

WEBPACK_SRC="/Users/toto/Projets/shyrka5"
WEBPACK_BUILD="/Users/toto/Projets/shyrka5/build"
ROOT_MYSQL="/Users/toto/Projets/_mysql"
ROOT_APIWEB="/Users/toto/Projets/shyrka5/build/api"

Docker-compose.yml

Voici le cœur de notre infra. Le fichier Docker-compose.yml configure les 3 containers à partir des 3 images créées.

Chaque container est configuré en fonction du projet (chemin des dossiers, ports à relayer etc…)

Le format du fichier est yml, le format du fichier est important, les tabulations doivent être correctement positionnées sous peine d’avoir une erreur lors du traitement.

Les sections services décrivent chaque container : db, web et nodejs.

services image indique le nom de l’image à utiliser (reprendre les noms des images créées précédemment)

services volumes définit les liens entre un dossier local et un dossier dans le container. On retrouve ici les variables définies dans les fichiers xxx.env

service networks permet de configurer le réseau et l’adresse IP de chaque containeren lien avec la section networks (en fin de fichier), définit le nom du réseau interne, la classe d’adresses ip et le type de réseau à utiliser.

services command, définit la commande a exécuté lors du lancement du container. Comme pour tout container cette commande doit tourner en tache de fond, si elle s’arrête le container s’arrête.

Les redirections de ports sont également précisées pour chaque container :
web, le port 80 est relayé sur localhost:9999
webpack, le port 8000 est relayé sur localhost:8081

Pour construire et lancer les containers la commande est : docker-compose --env-file config-w10.env -f docker-compose.yml up

#docker-compose.yml pour infra apache/php, mariadb et nodejs/webpack 

version: '3'
services:

  db:
    container_name: srv-gen-mariadb
    hostname: mariadb
    image: img-gen-mariadb
    volumes:
      - ${ROOT_MYSQL}:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root
    networks:
      docklan:
        ipv4_address: 192.168.2.5

  web:
    container_name: sk5-web
    hostname: sk5-api
    image: img-gen-apachephp
    command: ["apache2-foreground"]
    ports:
      - 9999:80
    networks:
      docklan:
        ipv4_address: 192.168.2.7
    volumes:
      - ${ROOT_APIWEB}:/var/www/html
    restart: always

  nodejs:
    hostname: nodejs
    container_name: sk5-nodejs
    image: img-gen-nodejs
    ports:
      # port webpack expoé 8000
      - 8081:8000
    volumes:
      - ${WEBPACK_SRC}:/tmp/src
      - ${WEBPACK_BUILD}:/tmp/static
    stdin_open: true # docker run -i
    tty: true        # docker run -t
    working_dir: "/tmp/src"
    command: ["npm","run","dev"]

networks:
  docklan:
    driver: bridge
    ipam:
      config:
        - subnet: 192.168.2.0/24
          ip_range: 192.168.2.0/24
          gateway: 192.168.2.1