
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 :
- Webpack liveserver (nodejs) pour compiler le code REACT et afficher le front sur un navigateur
- Serveur BDD (MySQL ou MariaDB) pour la base de données SQL
- 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