CVE Watch
Cybersécuritédevsecops5 min de lecture

Docker et architecture microservices : de la théorie à la pratique

MB
Massioudath Bankole
13 mai 2026 · 50 vues

Prérequis

Avant de commencer, assure-toi d'avoir :

  • Docker installé sur ta machine
  • Un projet backend Python/FastAPI
  • Un projet frontend Next.js
  • Les bases de Docker vues dans l'article précédent

1. Le Dockerfile du backend Python/FastAPI

A la racine de ton projet backend, crée un fichier Dockerfile :

FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8000

CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

Explications :

  • FROM python:3.11-slim : on part d'une image Python officielle légère. slim signifie qu'elle ne contient que le strict nécessaire.
  • COPY requirements.txt . puis RUN pip install : on installe les dépendances avant de copier le code. Cela permet à Docker de mettre en cache cette étape — si requirements.txt ne change pas, Docker réutilise le cache et le build est plus rapide.
  • COPY . . : on copie tout le code source dans le container.
  • CMD : la commande lancée au démarrage du container.

Construire l'image :

docker build -t mon-backend .

Lancer le container :

docker run -d --name mon-backend -p 8000:8000 mon-backend

Vérifier que l'API répond :

curl http://localhost:8000/

2. Le fichier .dockerignore

Avant de construire une image, il est important de créer un fichier .dockerignore pour exclure les fichiers inutiles :

pycache *.pyc *.pyo .env .git .gitignore venv node_modules

Sans ce fichier, Docker copierait tous ces fichiers dans l'image, ce qui l'alourdirait inutilement et pourrait exposer des informations sensibles comme le fichier .env.

3. Le Dockerfile du frontend Next.js

Le frontend utilise un build multi-stage pour optimiser la taille de l'image finale.

FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm install

FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ARG NEXT_PUBLIC_API_URL
ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL
RUN npm run build

FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./public
EXPOSE 3000
CMD ["node", "server.js"]

Le build multi-stage divise la construction en trois étapes :

  • deps : installe les dépendances npm. Si package.json ne change pas, Docker réutilise le cache.
  • builder : compile le code TypeScript et génère le build Next.js.
  • runner : l'image finale qui ne contient que les fichiers nécessaires à l'exécution. Pas de node_modules de développement, pas de code source TypeScript.

Résultat : une image de production légère et sécurisée.

La variable NEXT_PUBLIC_API_URL est passée au moment du build car les variables NEXT_PUBLIC_* dans Next.js sont intégrées à la compilation et non à l'exécution.

Construire l'image en passant l'URL de l'API :

docker build --build-arg NEXT_PUBLIC_API_URL=https://mondomaine.com/api -t mon-frontend .

Lancer le container :

docker run -d --name mon-frontend -p 3000:3000 mon-frontend

4. Gérer les variables d'environnement

Les variables d'environnement sensibles (clés API, credentials de base de données) ne doivent jamais être dans le Dockerfile ou dans l'image. On les passe au container via un fichier .env :

docker run -d \
  --name mon-backend \
  --env-file /chemin/vers/.env \
  -p 8000:8000 \
  mon-backend

Le fichier .env reste sur le serveur et n'est jamais intégré à l'image Docker.

5. Faire communiquer les containers via Nginx

Les deux containers tournent sur le même serveur mais sur des ports différents. Nginx joue le rôle de reverse proxy pour les exposer sur un seul domaine.

Installer Nginx :

sudo apt update && sudo apt install -y nginx

Créer la configuration :

sudo nano /etc/nginx/sites-available/monapp
server {
    listen 80;
    server_name mondomaine.com www.mondomaine.com;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }

    location /api/ {
        proxy_pass http://localhost:8000/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Toute requête vers mondomaine.com/ est redirigée vers le frontend sur le port 3000. Toute requête vers mondomaine.com/api/ est redirigée vers le backend sur le port 8000.

Activer la configuration :

sudo ln -s /etc/nginx/sites-available/monapp /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

6. Le Docker Registry de GitLab

Plutôt que de construire les images directement sur le serveur de production, on les construit dans le pipeline CI/CD et on les stocke dans le GitLab Container Registry.

Le Registry est une bibliothèque d'images associée à ton projet GitLab. Chaque image est identifiée par son nom et son tag :

registry.gitlab.com/nom-du-groupe/nom-du-projet/nom-du-service:tag

Le pipeline CI/CD construit l'image, la pousse vers le Registry, puis le serveur de production la télécharge depuis le Registry.

docker login registry.gitlab.com
docker build -t registry.gitlab.com/mon-groupe/mon-projet/backend:latest .
docker push registry.gitlab.com/mon-groupe/mon-projet/backend:latest

Sur le serveur de production :

docker pull registry.gitlab.com/mon-groupe/mon-projet/backend:latest
docker run -d --name mon-backend -p 8000:8000 registry.gitlab.com/mon-groupe/mon-projet/backend:latest

7. Commandes Docker utiles

Voici les commandes Docker les plus utilisées au quotidien :

Lister les containers en cours d'exécution :

docker ps

Lister toutes les images :

docker images

Voir les logs d'un container :

docker logs mon-backend

Entrer dans un container en cours d'exécution :

docker exec -it mon-backend bash

Arrêter et supprimer un container :

docker stop mon-backend
docker rm mon-backend

Supprimer une image :

docker rmi mon-backend

Nettoyer les images et containers inutilisés :

docker system prune

Conclusion

On a mis en place deux microservices indépendants, chacun dans son propre container Docker, qui communiquent via Nginx. Cette architecture est la base de tout déploiement moderne en production.

Dans les articles suivants, on automatise tout ce processus avec GitLab CI/CD pour que chaque push sur la branche main déclenche automatiquement la construction des images et le déploiement sur le serveur.

devsecops
Partager cet article

Commentaires (0)

Sois le premier à commenter !

Articles similaires