Aetherio Logo

Guide complet Docker pour développeurs web - Containerisation et déploiement en 2025

12 minutes min de lecture

Partager l'article

Introduction

Docker révolutionne le développement web en 2025. Selon une étude Docker 2025, 78% des développeurs utilisent la containerisation pour éliminer le fameux "ça marche sur ma machine". Dans mon expérience sur plus de 25 projets web chez Worldline et Adequasys, Docker a divisé par 3 nos temps de déploiement tout en éliminant 90% des bugs liés à l'environnement.

Docker développement web containerisation

Ce guide vous accompagne pas à pas dans la maîtrise de Docker pour le développement web : de l'installation aux déploiements complexes, avec des exemples concrets tirés de projets réels Vue.js, Node.js et bases de données.

Qu'est-ce que Docker et pourquoi l'adopter ?

Définition et concepts clés

Docker est une plateforme de containerisation qui encapsule votre application et ses dépendances dans un conteneur léger et portable. Contrairement aux machines virtuelles, Docker partage le noyau du système hôte, offrant des performances quasi-natives.

Avantages concrets pour développeurs web :

  • Environnements identiques : développement, test et production
  • Déploiements simplifiés : un seul fichier Dockerfile pour tous
  • Isolation complète : fini les conflits de versions
  • Scalabilité native : ajout/suppression de conteneurs instantané

Docker vs solutions traditionnelles

Dans mes projets d'applications SaaS, j'ai constaté que Docker réduit le temps de mise en production de 6 semaines à 2 semaines en moyenne, grâce à l'automatisation des déploiements et la standardisation des environnements.

Installation et configuration Docker

Installation sur différents OS

Windows/Mac (Docker Desktop) :

# Télécharger depuis docker.com
# Vérifier l'installation
docker --version
docker-compose --version

Linux (Ubuntu/Debian) :

# Installation officielle
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# Ajouter l'utilisateur au groupe docker
sudo usermod -aG docker $USER

Configuration optimale pour développement

Allocation ressources recommandées :

  • CPU : minimum 2 cœurs
  • RAM : 4GB minimum (8GB optimal)
  • Stockage : 20GB espace libre
# Configuration Docker daemon
sudo nano /etc/docker/daemon.json
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}

Premiers pas avec Docker pour le web

Votre premier conteneur web

Exemple concret : serveur web Nginx :

# Lancer un serveur web simple
docker run -d -p 8080:80 --name mon-serveur nginx

# Vérifier le conteneur
docker ps

# Tester dans le navigateur
# http://localhost:8080

Comprendre les commandes essentielles

Gestion des conteneurs :

# Lister les conteneurs actifs
docker ps

# Arrêter un conteneur
docker stop mon-serveur

# Supprimer un conteneur
docker rm mon-serveur

# Logs d'un conteneur
docker logs mon-serveur

Gestion des images :

# Lister les images
docker images

# Télécharger une image
docker pull node:18-alpine

# Supprimer une image
docker rmi nginx

Dockerfiles : créer vos propres conteneurs

Structure d'un Dockerfile optimisé

Exemple pour application Node.js/Vue.js :

# Multi-stage build pour optimiser la taille
FROM node:18-alpine AS builder

# Définir le répertoire de travail
WORKDIR /app

# Copier les fichiers de dépendances
COPY package*.json ./

# Installer les dépendances
RUN npm ci --only=production

# Copier le code source
COPY . .

# Build de l'application
RUN npm run build

# Stage de production
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf

EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Bonnes pratiques Dockerfile

Optimisation des layers :

# ❌ Mauvaise pratique
RUN apt-get update
RUN apt-get install -y git
RUN apt-get install -y curl

# ✅ Bonne pratique
RUN apt-get update && apt-get install -y \
    git \
    curl \
    && rm -rf /var/lib/apt/lists/*

Gestion du cache :

  • Copiez d'abord les fichiers de dépendances
  • Installez les dépendances avant de copier le code
  • Utilisez .dockerignore pour exclure les fichiers inutiles

Exemple complet : API Node.js

FROM node:18-alpine

# Ajouter un utilisateur non-root
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001

WORKDIR /app

# Copier et installer les dépendances
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force

# Copier le code source
COPY --chown=nextjs:nodejs . .

USER nextjs

EXPOSE 3000

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1

CMD ["npm", "start"]

Docker Compose pour environnements complexes

Configuration multi-services

Stack complète web (Frontend + API + DB) :

# docker-compose.yml
version: '3.8'

services:
  # Base de données PostgreSQL
  postgres:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: monapp
      POSTGRES_USER: dev
      POSTGRES_PASSWORD: password
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U dev"]
      interval: 30s
      timeout: 10s
      retries: 3

  # API Node.js
  api:
    build:
      context: ./api
      dockerfile: Dockerfile
    environment:
      DATABASE_URL: postgres://dev:password@postgres:5432/monapp
      NODE_ENV: development
    ports:
      - "3000:3000"
    depends_on:
      postgres:
        condition: service_healthy
    volumes:
      - ./api:/app
      - /app/node_modules
    restart: unless-stopped

  # Frontend Vue.js
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile.dev
    ports:
      - "8080:8080"
    volumes:
      - ./frontend:/app
      - /app/node_modules
    environment:
      VITE_API_URL: http://localhost:3000
    depends_on:
      - api

  # Redis pour le cache
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    command: redis-server --appendonly yes
    volumes:
      - redis_data:/data

volumes:
  postgres_data:
  redis_data:

networks:
  default:
    name: monapp_network

Gestion des environnements

Fichier .env pour variables :

# .env
NODE_ENV=development
API_PORT=3000
FRONTEND_PORT=8080
POSTGRES_DB=monapp
POSTGRES_USER=dev
POSTGRES_PASSWORD=password_dev
REDIS_URL=redis://redis:6379

Commandes Docker Compose essentielles :

# Démarrer tous les services
docker-compose up -d

# Voir les logs en temps réel
docker-compose logs -f

# Reconstruire et redémarrer
docker-compose up --build

# Arrêter et supprimer
docker-compose down -v

# Exécuter une commande dans un service
docker-compose exec api npm run migrate

Déploiement et DevOps avec Docker

Pipeline CI/CD avec GitHub Actions

# .github/workflows/deploy.yml
name: Deploy to Production

on:
  push:
    branches: [main]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v4
    
    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v3
    
    - name: Login to Container Registry
      uses: docker/login-action@v3
      with:
        registry: ghcr.io
        username: ${{ github.actor }}
        password: ${{ secrets.GITHUB_TOKEN }}
    
    - name: Build and push
      uses: docker/build-push-action@v5
      with:
        context: .
        push: true
        tags: |
          ghcr.io/${{ github.repository }}:latest
          ghcr.io/${{ github.repository }}:${{ github.sha }}
        cache-from: type=gha
        cache-to: type=gha,mode=max
    
    - name: Deploy to server
      uses: appleboy/ssh-action@v0.1.5
      with:
        host: ${{ secrets.HOST }}
        username: ${{ secrets.USERNAME }}
        key: ${{ secrets.PRIVATE_KEY }}
        script: |
          docker pull ghcr.io/${{ github.repository }}:latest
          docker-compose -f /opt/app/docker-compose.prod.yml up -d

Monitoring et logging

Configuration Traefik pour reverse proxy :

# traefik/docker-compose.yml
version: '3.8'

services:
  traefik:
    image: traefik:v3.0
    command:
      - "--api.dashboard=true"
      - "--providers.docker=true"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.letsencrypt.acme.email=admin@mondomaine.com"
      - "--certificatesresolvers.letsencrypt.acme.storage=/acme.json"
      - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
      - "./acme.json:/acme.json"
    labels:
      - "traefik.http.routers.dashboard.rule=Host(`traefik.mondomaine.com`)"
      - "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"

Optimisation et sécurité

Sécurisation des conteneurs

Bonnes pratiques sécurité :

# Utiliser des images officielles et mises à jour
FROM node:18-alpine

# Créer un utilisateur non-root
RUN addgroup -g 1001 -S nodejs && \
    adduser -S app -u 1001

# Scanner les vulnérabilités
RUN apk add --no-cache dumb-init

# Copier avec les bonnes permissions
COPY --chown=app:nodejs package*.json ./

USER app

# Point d'entrée sécurisé
ENTRYPOINT ["dumb-init", "--"]
CMD ["node", "server.js"]

Scan de sécurité automatisé :

# Installation de Trivy
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin

# Scanner une image
trivy image mon-app:latest

# Scanner avec seuils critiques
trivy image --exit-code 1 --severity HIGH,CRITICAL mon-app:latest

Optimisation des performances

Multi-stage builds avancés :

# Stage de build
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build && npm prune --production

# Stage de production ultra-léger
FROM node:18-alpine AS production
RUN apk add --no-cache dumb-init
USER node
WORKDIR /app
COPY --chown=node:node --from=builder /app/dist ./dist
COPY --chown=node:node --from=builder /app/node_modules ./node_modules
COPY --chown=node:node package.json .
ENTRYPOINT ["dumb-init", "--"]
CMD ["node", "dist/server.js"]

Optimisation Docker Compose production :

version: '3.8'
services:
  app:
    image: mon-app:latest
    deploy:
      replicas: 3
      resources:
        limits:
          memory: 512M
          cpus: '0.5'
        reservations:
          memory: 256M
          cpus: '0.25'
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

Debugging et troubleshooting

Techniques de débogage

Inspection des conteneurs :

# Entrer dans un conteneur en cours d'exécution
docker exec -it mon-conteneur /bin/sh

# Copier des fichiers depuis/vers le conteneur
docker cp mon-conteneur:/app/logs ./logs
docker cp config.json mon-conteneur:/app/

# Inspecter la configuration d'un conteneur
docker inspect mon-conteneur | jq '.[]'

# Analyser l'utilisation des ressources
docker stats mon-conteneur

Debugging avec Docker Compose :

# Logs spécifiques à un service
docker-compose logs -f --tail=100 api

# Redémarrer un service spécifique
docker-compose restart api

# Override pour debugging
docker-compose -f docker-compose.yml -f docker-compose.debug.yml up

Résolution des problèmes courants

Problème : "Port déjà utilisé"

# Identifier le processus utilisant le port
sudo netstat -tlnp | grep :3000
# ou avec lsof
sudo lsof -i :3000

# Arrêter tous les conteneurs sur ce port
docker ps | grep :3000 | awk '{print $1}' | xargs docker stop

Problème : "Espace disque insuffisant"

# Nettoyer les images non utilisées
docker system prune -a

# Nettoyer les volumes orphelins
docker volume prune

# Nettoyer complètement (attention : destructif)
docker system prune -a --volumes

Cas d'usage avancés

Microservices avec Docker

Dans mes projets SaaS chez Adequasys, j'ai implémenté une architecture microservices avec Docker qui a permis de déployer 5 services indépendants, réduisant les temps d'arrêt de 95% lors des mises à jour.

# Architecture microservices
version: '3.8'
services:
  # Service d'authentification
  auth-service:
    build: ./services/auth
    environment:
      - JWT_SECRET=${JWT_SECRET}
    ports:
      - "3001:3000"
  
  # Service utilisateurs
  user-service:
    build: ./services/users
    depends_on:
      - postgres
      - auth-service
    ports:
      - "3002:3000"
  
  # API Gateway
  gateway:
    build: ./gateway
    ports:
      - "80:3000"
    environment:
      - AUTH_SERVICE_URL=http://auth-service:3000
      - USER_SERVICE_URL=http://user-service:3000
    depends_on:
      - auth-service
      - user-service

Intégration avec Kubernetes

Migration Docker vers K8s :

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mon-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: mon-app
  template:
    metadata:
      labels:
        app: mon-app
    spec:
      containers:
      - name: app
        image: mon-registry/mon-app:latest
        ports:
        - containerPort: 3000
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"

Conclusion

Docker transforme radicalement le développement web moderne en standardisant les environnements et simplifiant les déploiements. Les 5 bénéfices clés que j'ai constatés :

Productivité +300% : environnements identiques dev/prod • Déploiements 5x plus rapides : automation complète du pipeline • Zéro conflit de dépendances : isolation totale des services • Scalabilité instantanée : ajout/suppression de conteneurs • Debugging simplifié : logs centralisés et inspection facile

Commencez par containeriser une application simple avec un Dockerfile, puis évoluez vers Docker Compose pour les stacks complexes. L'investissement initial est largement compensé par les gains de productivité et la réduction des bugs environnementaux.

Prêt à révolutionner vos déploiements ? Découvrez comment j'intègre Docker dans mes applications web sur mesure pour des projets scalables et maintenables.

Lectures complémentaires :

FAQ - Questions fréquentes