0 XP
?
Docker : de zéro à professionnel/Projet final : architecture complète
Avancé120 min100 XP

Objectifs de cette leçon

  • Assembler une stack complète multi-services
  • Déployer une application full-stack conteneurisée
  • Appliquer toutes les bonnes pratiques Docker

Projet final : architecture complète 🏗️

Architecture cible

┌─────────────────────────────────────────────────────────┐
│                    Docker Compose                         │
├──────────────┬──────────────┬──────────────┬─────────────┤
│   Nginx      │   Next.js    │   Laravel    │   MySQL     │
│  (reverse    │  (frontend)  │   (API)      │   (BDD)     │
│   proxy)     │  Port 3000   │  Port 8000   │  Port 3306  │
│  Port 80     │              │              │             │
├──────────────┼──────────────┼──────────────┼─────────────┤
│              │              │              │   Redis     │
│              │              │              │  (cache)    │
│              │              │              │  Port 6379  │
└──────────────┴──────────────┴──────────────┴─────────────┘

Structure du projet

architecture-complete/
├── frontend/              # Next.js
│   ├── src/
│   ├── Dockerfile
│   ├── package.json
│   └── .env.local
├── api/                   # Laravel
│   ├── app/
│   ├── routes/
│   ├── Dockerfile
│   └── .env
├── nginx/                 # Configuration Nginx
│   └── default.conf
├── docker-compose.yml
├── .env
└── README.md

docker-compose.yml complet

version: '3.8'

services:
  # Nginx - Reverse proxy
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - frontend
      - api
    networks:
      - app-network
    restart: unless-stopped

  # Frontend Next.js
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    environment:
      - NEXT_PUBLIC_API_URL=http://api:8000
    networks:
      - app-network
    restart: unless-stopped

  # API Laravel
  api:
    build:
      context: ./api
      dockerfile: Dockerfile
    environment:
      - DB_CONNECTION=mysql
      - DB_HOST=mysql
      - DB_PORT=3306
      - DB_DATABASE=${DB_DATABASE}
      - DB_USERNAME=${DB_USERNAME}
      - DB_PASSWORD=${DB_PASSWORD}
      - REDIS_HOST=redis
      - REDIS_PORT=6379
    volumes:
      - ./api:/var/www/html
    depends_on:
      - mysql
      - redis
    networks:
      - app-network
    restart: unless-stopped

  # MySQL
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
      MYSQL_DATABASE: ${DB_DATABASE}
      MYSQL_USER: ${DB_USERNAME}
      MYSQL_PASSWORD: ${DB_PASSWORD}
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql
    networks:
      - app-network
    restart: unless-stopped

  # Redis
  redis:
    image: redis:alpine
    ports:
      - "6379:6379"
    networks:
      - app-network
    restart: unless-stopped

volumes:
  mysql-data:

networks:
  app-network:
    driver: bridge

Configuration Nginx (reverse proxy)

# nginx/default.conf
upstream frontend {
    server frontend:3000;
}

upstream api {
    server api:8000;
}

server {
    listen 80;
    server_name localhost;

    # Frontend Next.js
    location / {
        proxy_pass http://frontend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
    }

    # API Laravel
    location /api {
        proxy_pass http://api;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    # Fichiers statiques du frontend
    location /_next/static {
        proxy_pass http://frontend;
        proxy_cache_valid 200 1y;
    }
}

.env (racine)

# Base de données
DB_ROOT_PASSWORD=rootsecret123
DB_DATABASE=app_database
DB_USERNAME=app_user
DB_PASSWORD=app_secret

# Laravel
APP_KEY=base64:xxx
APP_DEBUG=false
APP_URL=https://monapp.com

# Redis
REDIS_PASSWORD=redis_secret

Dockerfile Frontend (Next.js)

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

FROM node:18-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ENV NEXT_TELEMETRY_DISABLED 1
RUN npm run build

FROM node:18-alpine AS runner
WORKDIR /app
ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs
EXPOSE 3000
CMD ["node", "server.js"]

Dockerfile Backend (Laravel)

FROM php:8.2-fpm-alpine

RUN apk add --no-cache \
    libzip-dev \
    oniguruma-dev \
    libpng-dev \
    icu-dev

RUN docker-php-ext-install pdo_mysql mbstring zip bcmath gd intl

COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

WORKDIR /var/www/html
COPY . .
RUN composer install --no-dev --optimize-autoloader

RUN chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache

EXPOSE 9000
CMD ["php-fpm"]

Commandes de lancement

# 1. Construire toutes les images
docker compose build

# 2. Démarrer l'infrastructure
docker compose up -d mysql redis

# 3. Installer les dépendances Laravel
docker compose run --rm api composer install

# 4. Générer la clé APP_KEY
docker compose run --rm api php artisan key:generate

# 5. Lancer les migrations
docker compose run --rm api php artisan migrate

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

# 7. Vérifier
docker compose ps
# NAME       IMAGE                  STATUS          PORTS
# nginx      nginx:alpine           Up 2 minutes   0.0.0.0:80->80/tcp
# frontend   frontend:latest        Up 2 minutes
# api        api:latest             Up 2 minutes   9000/tcp
# mysql      mysql:8.0              Up 2 minutes   3306/tcp
# redis      redis:alpine           Up 2 minutes   6379/tcp

Vérification

# Tester le frontend
curl http://localhost
# → Page Next.js s'affiche

# Tester l'API
curl http://localhost/api/health
# → {"status": "ok"}

# Voir les logs
docker compose logs -f nginx
docker compose logs -f api

Déploiement en production

# Sur le serveur de production
git pull origin main
docker compose -f docker-compose.prod.yml build
docker compose -f docker-compose.prod.yml up -d

# Ou avec CI/CD (GitHub Actions)
# .github/workflows/deploy.yml

Récapitulatif du cours

LeçonConcept clé
1. Pourquoi DockerLe problème « ça marche sur ma machine »
2. VM vs ConteneursIsolation légère vs lourde
3. InstallationPremières commandes
4. ImagesCouches et cache
5. ConteneursCycle de vie
6. VolumesPersistance des données
7. RéseauxCommunication entre conteneurs
8. DockerfileÉcrire des recettes
9. Docker ComposeOrchestrer plusieurs services
10. Node.jsDockeriser une app JS
11. LaravelStack PHP complète
12. React/Next.jsFrontend Dockerisé
13. DebuggingOutils de diagnostic
14. OptimisationBonnes pratiques
15. Projet finalArchitecture complète

Félicitations ! 🎉

Tu as terminé le cours Docker : de zéro à professionnel !

Tu maîtrises maintenant :

  • Les concepts fondamentaux de Docker
  • L'écriture de Dockerfiles
  • L'orchestration avec Docker Compose
  • La dockerisation d'applications réelles
  • Le debugging et l'optimisation
  • La mise en production

Prochaine étape : Applique ces connaissances à tes propres projets ! 🚀

Projet final : Architecture complète
Cliquez pour explorer
docker compose up -d

Lancement de tous les services

🌐
3000
⚙️
8000
6379
🗄️
5432
🐳
443/80
1/7