Hostinger

Sites : Go (Golang), Node.js et PHP !

S’entraîner en utilisant un fichier compose.yml

L’objectif de cette leçon est de mettre en pratique ce que nous avons appris en nous entraînant. Nous allons créer un fichier compose.yml pour déployer un site en Go (Golang), Node.js et PHP.

Le serveur web Nginx permettra de rediriger les « URL » selon le bon site internet.

Voici un schéma explicatif :

Quatre conteneurs : Nginx, PHP, Node.js et Go

Télécharger le dossier de travail

Nous allons nous concentrer sur la manipulation du fichier compose.yml et des fichiers Dockerfile (un pour chaque langage). Mais pour atteindre notre objectif, nous devons créer des fichiers pour chaque site. De plus, nous devons configurer Nginx, car il servira de reverse proxy pour rediriger les requêtes vers les bons services (le bon conteneur).

Pour bien commencer, je vous propose de télécharger le dossier du projet avec tous les fichiers déjà en place.

git clone https://github.com/Celtak/compose-yml-php-node-go

Nous avons maintenant notre projet et une bonne base de fichiers.

Les sites en Go, Node.js et PHP fonctionnent correctement. Il est inutile de vérifier. 😉

Voici l'arborescence du projet :

compose-yml-php-node-go/
|-- php_app/
   |-- index.php
|-- node_app/
   |-- server.js
|-- go_app/
   |-- main.go
|-- nginx.conf

Dans le projet, nous trouvons également le fichier nginx.conf, qui permet de configurer correctement Nginx. La configuration est déjà prête. Ainsi, on se concentre exclusivement sur la configuration du fichier `compose.yml`.

Vous pouvez maintenant ouvrir votre éditeur de code préféré et charger le projet compose-yml-php-node-go.

Créer le compose.yml

La première chose à faire est de créer un fichier compose.yml à la racine de notre projet.

compose-yml-php-node-go
|-- php_app
   |-- index.php
|-- node_app
   |-- server.js
|-- go_app
   |-- main.go
|-- nginx.conf
|-- compose.yml

Remplir le compose.yml

Il faut maintenant le compléter en utilisant les connaissances que nous avons acquises.

Quatre services = quatre conteneurs

Les conteneurs

Nous avons besoin de quatre services, car nous devons utiliser quatre conteneurs.

  1. Nginx
  2. Node
  3. PHP
  4. Go (Golang)

Créer les services

Ouvrez le compose.yml et ajouter les services :

services:
  nginx:
  node_app:
  php_app:
  go_app:

Nginx

Nous allons commencer par indiquer les informations du conteneur Nginx.

Nginx : L'image et le nom du conteneur

services:

  nginx:
    image: nginx:latest
    container_name: nginx_proxy

  node_app:

  php_app:

  go_app:

Ligne 4 : Nginx sera basé sur la dernière version de l’image Nginx disponible sur Docker.

Ligne 5 : On appellera notre conteneur nginx—proxy.

Nginx : Mapper les ports

Nous allons mapper le port 80 de Nginx avec le port 80 de notre machine local.

services:

  nginx:
    image: nginx:latest
    container_name: nginx_proxy
    ports:
      - "80:80"

  node_app:

  php_app:

  go_app:

Étant donné que Nginx transmet par défaut les données via le port 80, nous pourrons les récupérer sur ce même port dans notre navigateur local en accédant à localhost (équivalent à localhost:80).

Nginx : Mapper les volumes

Nous allons mapper un fichier et un dossier.

services:

  nginx:
    image: nginx:latest
    container_name: nginx_proxy
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./logs/nginx:/var/log/nginx

  node_app:

  php_app:

  go_app:

Ligne 9 : Nous mapper le fichier nginx.conf. Ainsi, le conteneur Nginx aura la bonne configuration.

Ligne 10 : Nous mappons également le dossier /var/log/nginx afin de récupérer les logs de Nginx. Cela nous permettra de vérifier les messages d’erreur.

Nginx prêt !

Le conteneur Nginx est prêt

Node.js

Nous allons maintenant compléter la section dédiée au conteneur Node.js.

Node.js : L'image et le nom du conteneur

services:

  nginx:
    image: nginx:latest
    container_name: nginx_proxy
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./logs/nginx:/var/log/nginx
  
  node_app:
    build: ./node_app
    container_name: node_app
  
  php_app:
  
  go_app:

Nous découvrons à nouveau mot-clé : build. Il remplace image.

Que signifie build ?

Il permet d’utiliser un Dockerfile au lieu d’une image prédéfinie, ce qui nous permet de créer une image personnalisée. Dans la ligne 13, nous indiquons que le Dockerfile est situé à ./node_app.

Nous allons créer le fichier.

compose-yml-php-node-go/
|-- php_app/
   |-- index.php
|-- node_app/
   |-- server.js
   |-- Dockerfile
|-- go_app/
   |-- main.go
|-- nginx.conf
|-- compose.yml

Pour le moment nous laissons vide le Dockerfile ! On le remplira plus tard.

Node.js : Mapper les ports et mapper les volumes

Il n'est pas utile de mapper des ports ou des volumes car la communication et la gestion des sites est gérée grâce au conteneur Nginx.

Node.js prêt !

Le conteneur de Node.js est prêt !

PHP

Continuons à compléter notre fichier compose.yml en nous occupant maintenant de PHP.

PHP : L'image et le nom du conteneur

services:

  nginx:
    image: nginx:latest
    container_name: nginx_proxy
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./logs/nginx:/var/log/nginx
  
  node_app:
    build: ./node_app
    container_name: node_app
  
  php_app:
    build: ./php_app
    container_name: php_app
  
  go_app:

Comme pour Node.js, nous utiliserons une image personnalisée grâce à un fichier Dockerfile.

compose-yml-php-node-go/
|-- php_app/
   |-- index.php
   |-- Dockerfile
|-- node_app/
   |-- server.js
   |-- Dockerfile
|-- go_app/
   |-- main.go
|-- nginx.conf
|-- compose.yml

PHP est prêt !

Le conteneur de PHP est prêt !

Go

Nous allons maintenant terminer le remplissage du fichier compose.yml avec Go (Golang).”

Go : L'image et le nom du conteneur

services:
  nginx:
    image: nginx:latest
    container_name: nginx_proxy
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./logs/nginx:/var/log/nginx

  node_app:
    build: ./node_app
    container_name: node_app

  php_app:
    build: ./php_app
    container_name: php_app

  go_app:
    build: ./go_app
    container_name: go_app

Tout comme pour Node.js et PHP, nous utiliserons un Dockerfile pour Go (Golang). 😉

compose-yml-php-node-go/
|-- php_app/
   |-- index.php
   |-- Dockerfile
|-- node_app/
   |-- server.js
   |-- Dockerfile
|-- go_app/
   |-- main.go
   |-- Dockerfile
|-- nginx.conf
|-- compose.yml

Go est prêt !

Go est prêt !

Remplir les fichiers Dockerfile

Nous allons maintenant remplir les fichiers Dockerfile pour Node, PHP et Go.

Node.js : Dockerfile

FROM node:23
WORKDIR /app
COPY server.js .
CMD ["node", "server.js"]

Nous allons analyser chaque ligne, car elle contient des mots-clés que nous ne connaissons pas encore.

  • Ligne 1 : Cette ligne spécifie l’image de base que Docker va utiliser pour créer le conteneur. La version choisie est la version 23.

  • Ligne 2 : WORKDIR définit le dossier de travail dans le conteneur. /app est celui qui sera utilisé par le conteneur Node.

  • Ligne 3 : COPY permet de copier un fichier vers le conteneur. Nous copions server.js qui se trouve dans notre machine locale.

  • Ligne 4 : CMD définit la commande par défaut qui sera exécutée lorsque le conteneur démarre. CMD utilise un tableau : "node", "server.js"]. On exécute node server.js, ce qui lance l’application serveur Node.js.

PHP : Dockerfile

FROM php:8.4
WORKDIR /var/www/html
COPY index.php .
CMD ["php", "-S", "0.0.0.0:8000", "-t", "/var/www/html"]

Le principe est le même que pour Node.js, mais adapté à l’écosystème de PHP.

Go : Dockerfile

FROM golang:1.18
WORKDIR /app
COPY main.go .
RUN go build -o server main.go
CMD ["./server"]

Nous retrouvons la même logique pour le language Go (Golang).

Le mot-clé RUN nous est déjà familier, car nous l’avons utilisé dans la leçon sur le Dockerfile. Cette commande compile (go build) le fichier main.go et génère un exécutable nommé server qui sera exécutée lorsque le conteneur démarre grâce à CMD.

Le fichier compose.yml est prêt ! 😍

Lancer le compose.yml

Tout est terminé ! Il en reste plus qu'à lancer notre fichier compose.yml grâce à la commande suivante :

docker compose up --build

Site : Node.js

Pour Node.js, on utilise le lien suivant : localhost/node !

Site web sous Node.js

Site : PHP

Pour PHP, on utilise le lien suivant : localhost/php !

Site web sous PHP

Site : Go

Pour Go (Golang), on utilise le lien suivant : localhost/go !

Site web sous Go (Golang)

Les erreurs ❌

Si cela ne fonctionne pas aussi bien de votre coté, je vous invite à revoir le code et à vérifier les logs de Nginx dans logs/nginx/error.log.

Amélioration

Ce fichier compose.yml n’est pas adapté pour une mise en production sur un serveur. Il a été conçut comme un exercice afin d'aider un utilisateur à comprendre le fonctionnement d'un compose.yml. Pour une mise en production, plusieurs ajustements seront nécessaires, notamment au niveau de la configuration de Nginx.

Ce sera un excellent exercice pour vous ! 😃