Aller au contenu principal

Déploiement Docker

Vue d'ensemble

Chaque service dispose de son propre Dockerfile et peut être déployé indépendamment.

┌─────────────────────────────────────────────────────────────────┐
│ DOCKER COMPOSE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ traefik │ │ landing │ │ frontend │ │generator │ │
│ │ │ │ │ │ │ │ │ │
│ │ :80/443 │ │ :80 │ │ :4000 │ │ :5001 │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘

Frontend Angular

Dockerfile

# front-dedicaces/Dockerfile

# Stage 1: Build
FROM node:20-alpine AS builder

WORKDIR /app

COPY package*.json ./
RUN npm ci

COPY . .
RUN npm run build

# Stage 2: Production
FROM node:20-alpine

WORKDIR /app

# Copier le build SSR
COPY --from=builder /app/dist/front-dedicaces ./dist/front-dedicaces
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./

EXPOSE 4000

CMD ["node", "dist/front-dedicaces/server/server.mjs"]

Build et Run

cd front-dedicaces

# Build
docker build -t momentscollectifs-frontend .

# Run
docker run -d \
-p 4000:4000 \
--name frontend \
momentscollectifs-frontend

Video Generator

Dockerfile

# dedicace-generator/Dockerfile

FROM node:20-bookworm

# Dépendances système
RUN apt-get update && apt-get install -y \
ffmpeg \
chromium \
fonts-noto-color-emoji \
fonts-noto-cjk \
fonts-liberation \
libvips-dev \
--no-install-recommends \
&& rm -rf /var/lib/apt/lists/*

# Configuration Puppeteer
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium

WORKDIR /app

COPY package*.json ./
RUN npm ci --only=production

COPY . .

# Créer les dossiers de travail
RUN mkdir -p presentations backgrounds

VOLUME ["/app/presentations", "/app/backgrounds"]

EXPOSE 5001

CMD ["npm", "start"]

Build et Run

cd dedicace-generator

# Build
docker build -t momentscollectifs-generator .

# Run
docker run -d \
-p 5001:5001 \
-v $(pwd)/presentations:/app/presentations \
-v $(pwd)/backgrounds:/app/backgrounds \
-e SUPABASE_SERVICE_KEY=${SUPABASE_SERVICE_KEY} \
--name generator \
momentscollectifs-generator

Landing Page

Dockerfile

# landing-page-kazadedicate/Dockerfile

FROM nginx:alpine

COPY nginx.conf /etc/nginx/nginx.conf
COPY . /usr/share/nginx/html

EXPOSE 80

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

nginx.conf

events {
worker_connections 1024;
}

http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

gzip on;
gzip_types text/plain text/css application/javascript;

server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;

# URLs propres
location / {
try_files $uri $uri.html $uri/ =404;
}

# Cache statique
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 7d;
add_header Cache-Control "public, immutable";
}

# Page 404
error_page 404 /404.html;
}
}

Build et Run

cd landing-page-kazadedicate

# Build
docker build -t momentscollectifs-landing .

# Run
docker run -d \
-p 8080:80 \
--name landing \
momentscollectifs-landing

Docker Compose Complet

docker-compose.yml

version: '3.8'

services:
traefik:
image: traefik:v2.10
command:
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge=true"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
- "--certificatesresolvers.letsencrypt.acme.email=admin@momentscollectifs.fr"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./letsencrypt:/letsencrypt
networks:
- web
restart: unless-stopped

landing:
build: ./landing-page-kazadedicate
labels:
- "traefik.enable=true"
- "traefik.http.routers.landing.rule=Host(`momentscollectifs.fr`)"
- "traefik.http.routers.landing.entrypoints=websecure"
- "traefik.http.routers.landing.tls.certresolver=letsencrypt"
- "traefik.http.services.landing.loadbalancer.server.port=80"
# Redirect www to non-www
- "traefik.http.routers.landing-www.rule=Host(`www.momentscollectifs.fr`)"
- "traefik.http.routers.landing-www.middlewares=redirect-www"
- "traefik.http.middlewares.redirect-www.redirectregex.regex=^https://www\\.(.*)"
- "traefik.http.middlewares.redirect-www.redirectregex.replacement=https://$${1}"
networks:
- web
restart: unless-stopped

frontend:
build: ./front-dedicaces
environment:
- NODE_ENV=production
labels:
- "traefik.enable=true"
- "traefik.http.routers.frontend.rule=Host(`app.momentscollectifs.fr`)"
- "traefik.http.routers.frontend.entrypoints=websecure"
- "traefik.http.routers.frontend.tls.certresolver=letsencrypt"
- "traefik.http.services.frontend.loadbalancer.server.port=4000"
networks:
- web
restart: unless-stopped

generator:
build: ./dedicace-generator
environment:
- NODE_ENV=production
- PORT=5001
- SUPABASE_SERVICE_KEY=${SUPABASE_SERVICE_KEY}
volumes:
- ./presentations:/app/presentations
- ./backgrounds:/app/backgrounds
labels:
- "traefik.enable=true"
- "traefik.http.routers.generator.rule=Host(`api.momentscollectifs.fr`)"
- "traefik.http.routers.generator.entrypoints=websecure"
- "traefik.http.routers.generator.tls.certresolver=letsencrypt"
- "traefik.http.services.generator.loadbalancer.server.port=5001"
networks:
- web
restart: unless-stopped

networks:
web:
external: true

Démarrage

# Créer le réseau externe
docker network create web

# Créer le fichier .env
cat > .env << EOF
SUPABASE_SERVICE_KEY=eyJ...
EOF

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

# Voir les logs
docker compose logs -f

# Arrêter
docker compose down

Scripts de Déploiement

deploy.sh

#!/bin/bash

set -e

echo "🚀 Déploiement MomentsCollectifs"

# Variables
DEPLOY_DIR="/opt/momentscollectifs"
REPO_URL="https://github.com/user/momentscollectifs.git"

# Mise à jour du code
echo "📥 Mise à jour du code..."
cd $DEPLOY_DIR
git pull origin main

# Build des images
echo "🔨 Build des images Docker..."
docker compose build --no-cache

# Redémarrage des services
echo "🔄 Redémarrage des services..."
docker compose down
docker compose up -d

# Nettoyage
echo "🧹 Nettoyage des images inutilisées..."
docker image prune -f

# Vérification
echo "✅ Vérification des services..."
sleep 10
docker compose ps

echo "🎉 Déploiement terminé!"

rollback.sh

#!/bin/bash

set -e

echo "⏪ Rollback MomentsCollectifs"

# Revenir au commit précédent
cd /opt/momentscollectifs
git checkout HEAD~1

# Rebuild et redémarrage
docker compose build
docker compose down
docker compose up -d

echo "✅ Rollback effectué"

Maintenance

Voir les Logs

# Tous les services
docker compose logs -f

# Un service spécifique
docker compose logs -f frontend

# Les 100 dernières lignes
docker compose logs --tail 100 generator

Redémarrer un Service

# Redémarrer le frontend
docker compose restart frontend

# Rebuild et redémarrer
docker compose up -d --build frontend

Mise à Jour d'un Service

# Pull les nouvelles images
docker compose pull

# Rebuild si nécessaire
docker compose build generator

# Redémarrer avec les nouvelles versions
docker compose up -d

Backup des Volumes

# Backup des présentations générées
tar -czvf presentations-backup-$(date +%Y%m%d).tar.gz ./presentations

# Restauration
tar -xzvf presentations-backup-20240301.tar.gz