Déploiement MecaPy
Vue d’ensemble
Section intitulée « Vue d’ensemble »MecaPy utilise une stratégie de déploiement multi-environnements avec des services découplés pour maximiser la flexibilité et la scalabilité.
Architecture de déploiement
Section intitulée « Architecture de déploiement »graph TB subgraph "Production" LB[Load Balancer] API1[API Instance 1] API2[API Instance N] FE[Frontend Static] DB[(PostgreSQL)] S3[Object Storage] KC[Keycloak] end
subgraph "Staging" STAG_API[Staging API] STAG_FE[Staging Frontend] STAG_DB[(Staging DB)] end
subgraph "Development" DEV[Local Docker] end
Internet --> LB LB --> API1 LB --> API2 API1 --> DB API2 --> DB API1 --> S3 API2 --> S3Environnements
Section intitulée « Environnements »1. Développement local
Section intitulée « 1. Développement local »Configuration : Docker Compose
version: '3.8'services: api: build: context: ./repos/api dockerfile: Dockerfile.dev ports: - "8000:8000" environment: - DATABASE_URL=sqlite:///./dev.db - KEYCLOAK_URL=http://keycloak:8080 - TOKEN_VERIFICATION_ENABLED=false volumes: - ./repos/api:/app depends_on: - keycloak - postgres
frontend: build: context: ./repos/frontend dockerfile: Dockerfile.dev ports: - "3000:3000" environment: - NEXT_PUBLIC_API_URL=http://localhost:8000 - NODE_ENV=development volumes: - ./repos/frontend:/app - /app/node_modules
keycloak: image: quay.io/keycloak/keycloak:latest command: start-dev --import-realm ports: - "8080:8080" environment: KEYCLOAK_ADMIN: admin KEYCLOAK_ADMIN_PASSWORD: admin KC_DB: postgres KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak KC_DB_USERNAME: keycloak KC_DB_PASSWORD: keycloak volumes: - ./keycloak/realm-export.json:/opt/keycloak/data/import/realm.json depends_on: - postgres
postgres: image: postgres:15-alpine ports: - "5432:5432" environment: POSTGRES_DB: mecapy POSTGRES_USER: mecapy POSTGRES_PASSWORD: mecapy_dev POSTGRES_MULTIPLE_DATABASES: keycloak volumes: - postgres_data:/var/lib/postgresql/data - ./scripts/create-multiple-dbs.sh:/docker-entrypoint-initdb.d/create-multiple-dbs.sh
volumes: postgres_data:Commandes :
# Démarrage environnement completdocker-compose -f docker-compose.dev.yml up -d
# Logs en temps réeldocker-compose -f docker-compose.dev.yml logs -f
# Redémarrage servicedocker-compose -f docker-compose.dev.yml restart api
# Nettoyagedocker-compose -f docker-compose.dev.yml down -v2. Staging/Préprod
Section intitulée « 2. Staging/Préprod »Infrastructure : Services cloud managés
- API : Clever Cloud app de staging
- Frontend : Vercel preview deployment
- Database : PostgreSQL managé (petite instance)
- Keycloak : Instance dédiée ou partagée
Configuration :
# Variables d'environnement stagingENVIRONMENT=stagingDATABASE_URL=postgresql://staging_user:pass@staging-db.clever-cloud.com/mecapy_stagingKEYCLOAK_URL=https://auth-staging.mecapy.comCORS_ALLOW_ORIGINS=https://staging.mecapy.comLOG_LEVEL=DEBUG3. Production
Section intitulée « 3. Production »Infrastructure : Multi-cloud avec redondance
- API : Clever Cloud avec scaling automatique
- Frontend : Vercel avec CDN global
- Database : PostgreSQL managé avec réplication
- Storage : Scaleway Object Storage
- Monitoring : Sentry + DataDog (futur)
Déploiement API (Clever Cloud)
Section intitulée « Déploiement API (Clever Cloud) »1. Configuration
Section intitulée « 1. Configuration »Procfile :
web: gunicorn mecapy_api.main:app -w 4 -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:$PORTVariables d’environnement :
# Clever Cloud variablesCC_PYTHON_VERSION=3.13CC_PIP_REQUIREMENTS_FILE=requirements.txt
# ApplicationDATABASE_URL=postgresql://... # Auto-provisionedKEYCLOAK_URL=https://auth.mecapy.comKEYCLOAK_REALM=mecapyKEYCLOAK_CLIENT_ID=mecapy-apiKEYCLOAK_CLIENT_SECRET=xxx
# Scaleway Object StorageSCW_ACCESS_KEY=xxxSCW_SECRET_KEY=xxxCLOUD_BUCKET_UPLOADS=mecapy-uploadsCLOUD_REGION=fr-par
# SecurityTOKEN_VERIFICATION_ENABLED=trueCORS_ALLOW_ORIGINS=https://mecapy.comDéploiement :
# Clone dépôt sur Clever Cloudgit remote add clever-cloud git+ssh://git@push-par-clevercloud-customers.services.clever-cloud.com/app_xxx.git
# Push vers productiongit push clever-cloud main
# Logs de déploiementclever logs --alias mecapy-api2. Scaling automatique
Section intitulée « 2. Scaling automatique »Configuration Clever Cloud :
{ "deploy": { "runtimeVersion": "3.13" }, "hooks": { "postDeploy": "alembic upgrade head" }, "scaling": { "minInstances": 1, "maxInstances": 10, "targetCPU": 70, "targetMemory": 80 }}Déploiement Frontend (Vercel)
Section intitulée « Déploiement Frontend (Vercel) »1. Configuration
Section intitulée « 1. Configuration »vercel.json :
{ "framework": "nextjs", "buildCommand": "pnpm build", "devCommand": "pnpm dev", "installCommand": "pnpm install", "outputDirectory": ".next", "env": { "NEXT_PUBLIC_API_URL": "https://api.mecapy.com" }, "regions": ["cdg1", "iad1", "syd1"], "rewrites": [ { "source": "/api/:path*", "destination": "https://api.mecapy.com/:path*" } ], "headers": [ { "source": "/(.*)", "headers": [ { "key": "X-Content-Type-Options", "value": "nosniff" }, { "key": "X-Frame-Options", "value": "DENY" }, { "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" } ] } ]}Variables d’environnement :
# ProductionNEXT_PUBLIC_API_URL=https://api.mecapy.comNEXT_PUBLIC_KEYCLOAK_URL=https://auth.mecapy.comNEXT_PUBLIC_ENVIRONMENT=production
# Preview/StagingNEXT_PUBLIC_API_URL=https://api-staging.mecapy.comNEXT_PUBLIC_ENVIRONMENT=stagingDéploiement :
# Installation Vercel CLInpm i -g vercel
# Configuration projetvercel init
# Déploiement productionvercel --prod
# Déploiement previewvercel2. Optimisations
Section intitulée « 2. Optimisations »next.config.mjs :
/** @type {import('next').NextConfig} */const nextConfig = { // Performance experimental: { optimizeCss: true, optimizeServerReact: true, },
// Images images: { domains: ['mecapy-uploads.s3.fr-par.scw.cloud'], formats: ['image/avif', 'image/webp'], },
// Compression compress: true,
// Security headers async headers() { return [ { source: '/(.*)', headers: [ { key: 'X-DNS-Prefetch-Control', value: 'on' }, { key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubDomains; preload' }, ], }, ]; },};
export default nextConfig;Base de données
Section intitulée « Base de données »1. PostgreSQL managé
Section intitulée « 1. PostgreSQL managé »Providers recommandés :
- Clever Cloud : PostgreSQL intégré
- Neon : Serverless PostgreSQL
- Railway : PostgreSQL avec backup automatique
- AWS RDS : Enterprise grade
Configuration :
# Connection stringDATABASE_URL=postgresql://user:password@host:5432/mecapy
# Pool configurationDB_POOL_SIZE=10DB_MAX_OVERFLOW=20DB_POOL_TIMEOUT=30DB_POOL_RECYCLE=36002. Migrations
Section intitulée « 2. Migrations »Déploiement automatique :
# Dans le hook post-deployalembic upgrade head
# Ou via script de déploiement#!/bin/bashset -e
echo "Running database migrations..."python -m alembic upgrade head
echo "Starting application..."exec "$@"Rollback procedure :
# Identifier version ciblealembic history
# Rollback vers version spécifiquealembic downgrade <revision>
# Rollback une versionalembic downgrade -13. Backup et restauration
Section intitulée « 3. Backup et restauration »Backup automatique :
#!/bin/bashBACKUP_DIR="/backups/postgres"TIMESTAMP=$(date +%Y%m%d_%H%M%S)BACKUP_FILE="mecapy_backup_${TIMESTAMP}.sql"
# Créer backuppg_dump $DATABASE_URL > ${BACKUP_DIR}/${BACKUP_FILE}
# Compressergzip ${BACKUP_DIR}/${BACKUP_FILE}
# Upload vers S3 (optionnel)aws s3 cp ${BACKUP_DIR}/${BACKUP_FILE}.gz s3://mecapy-backups/postgres/
# Nettoyer anciens backups (> 30 jours)find ${BACKUP_DIR} -name "*.sql.gz" -mtime +30 -deleteCron job :
# Backup quotidien à 2h du matin0 2 * * * /scripts/backup-db.sh >> /var/log/backup.log 2>&1Monitoring et Logs
Section intitulée « Monitoring et Logs »1. Logs centralisés
Section intitulée « 1. Logs centralisés »Structure logs :
{ "timestamp": "2024-01-15T10:30:00Z", "level": "INFO", "service": "mecapy-api", "environment": "production", "version": "1.0.0", "request_id": "req_123456", "user_id": "user_789", "endpoint": "/upload", "method": "POST", "status_code": 200, "duration_ms": 150, "message": "File uploaded successfully", "metadata": { "file_size": 1024, "file_type": "application/pdf" }}Clever Cloud logs :
# Logs en directclever logs --alias mecapy-api
# Logs avec filtreclever logs --alias mecapy-api --filter "ERROR"
# Export logsclever logs --alias mecapy-api --since 1h > api-logs-1h.txt2. Monitoring applicatif
Section intitulée « 2. Monitoring applicatif »Health checks :
@app.get("/health")async def health_check(): checks = { "api": "ok", "database": await check_database(), "keycloak": await check_keycloak(), "storage": await check_storage(), "timestamp": datetime.utcnow().isoformat() }
# Détermine status global status = "ok" if all(v == "ok" for v in checks.values() if v != checks["timestamp"]) else "degraded"
return {"status": status, "checks": checks}
async def check_database(): try: # Test simple query await database.execute("SELECT 1") return "ok" except Exception: return "error"Uptime monitoring :
- Uptimerobot : Monitoring externe gratuit
- Pingdom : Monitoring professionnel
- DataDog : Monitoring intégré (futur)
3. Error tracking
Section intitulée « 3. Error tracking »Sentry integration :
# Sentry configurationimport sentry_sdkfrom sentry_sdk.integrations.fastapi import FastApiIntegration
sentry_sdk.init( dsn="https://xxx@xxx.ingest.sentry.io/xxx", environment="production", traces_sample_rate=0.1, integrations=[ FastApiIntegration(auto_enabling_integrations=False), ],)Frontend (Next.js) :
import * as Sentry from "@sentry/nextjs";
Sentry.init({ dsn: process.env.NEXT_PUBLIC_SENTRY_DSN, environment: process.env.NEXT_PUBLIC_ENVIRONMENT, tracesSampleRate: 0.1,});CI/CD Pipeline
Section intitulée « CI/CD Pipeline »1. GitHub Actions
Section intitulée « 1. GitHub Actions ».github/workflows/deploy.yml :
name: Deploy MecaPy
on: push: branches: [main] pull_request: branches: [main]
jobs: test-api: runs-on: ubuntu-latest defaults: run: working-directory: ./repos/api
services: postgres: image: postgres:15 env: POSTGRES_PASSWORD: postgres options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
steps: - uses: actions/checkout@v4
- name: Set up Python uses: actions/setup-python@v4 with: python-version: '3.13'
- name: Install uv run: pip install uv
- name: Install dependencies run: uv install --dev
- name: Run tests run: uv run pytest env: DATABASE_URL: postgresql://postgres:postgres@localhost:5432/mecapy_test
- name: Run linting run: uv run ruff check
- name: Run type checking run: uv run mypy .
test-frontend: runs-on: ubuntu-latest defaults: run: working-directory: ./repos/frontend
steps: - uses: actions/checkout@v4
- name: Set up Node.js uses: actions/setup-node@v4 with: node-version: '18' cache: 'pnpm' cache-dependency-path: './repos/frontend/pnpm-lock.yaml'
- name: Install pnpm run: npm install -g pnpm
- name: Install dependencies run: pnpm install
- name: Run linting run: pnpm lint
- name: Run type checking run: pnpm build
- name: Run tests run: pnpm test # À implémenter
deploy-api: needs: [test-api] runs-on: ubuntu-latest if: github.ref == 'refs/heads/main'
steps: - uses: actions/checkout@v4 with: fetch-depth: 0
- name: Deploy to Clever Cloud run: | git remote add clever-cloud ${{ secrets.CLEVER_CLOUD_GIT_URL }} git subtree push --prefix=repos/api clever-cloud main env: CLEVER_CLOUD_GIT_URL: ${{ secrets.CLEVER_CLOUD_GIT_URL }}
deploy-frontend: needs: [test-frontend] runs-on: ubuntu-latest if: github.ref == 'refs/heads/main'
steps: - uses: actions/checkout@v4
- name: Deploy to Vercel uses: amondnet/vercel-action@v25 with: vercel-token: ${{ secrets.VERCEL_TOKEN }} vercel-org-id: ${{ secrets.VERCEL_ORG_ID }} vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }} working-directory: ./repos/frontend vercel-args: --prod2. Secrets management
Section intitulée « 2. Secrets management »GitHub Secrets :
# Clever CloudCLEVER_CLOUD_GIT_URL=git+ssh://git@push-par-clevercloud-customers.services.clever-cloud.com/app_xxx.git
# VercelVERCEL_TOKEN=xxxVERCEL_ORG_ID=xxxVERCEL_PROJECT_ID=xxx
# SentrySENTRY_AUTH_TOKEN=xxxSENTRY_DSN=xxx3. Rollback strategy
Section intitulée « 3. Rollback strategy »API Rollback :
# Via Clever Cloud console ou CLIclever restart --alias mecapy-api --commit <previous_commit>
# Ou rollback base de données si nécessairealembic downgrade <previous_revision>Frontend Rollback :
# Via Vercel dashboard ou CLIvercel rollback <deployment_url>Sécurité déploiement
Section intitulée « Sécurité déploiement »1. Secrets et configuration
Section intitulée « 1. Secrets et configuration »Bonnes pratiques :
- Jamais de secrets en dur dans le code
- Variables d’environnement différentes par environnement
- Rotation régulière des clés API
- Accès minimum requis (principle of least privilege)
2. Network security
Section intitulée « 2. Network security »Production :
- HTTPS obligatoire (Let’s Encrypt)
- WAF (Web Application Firewall) si nécessaire
- Rate limiting par IP
- Monitoring des tentatives d’intrusion
3. Database security
Section intitulée « 3. Database security »PostgreSQL :
- Connexions SSL uniquement
- Users avec permissions minimales
- Backup encryption
- Regular security updates
Disaster Recovery
Section intitulée « Disaster Recovery »1. Backup strategy
Section intitulée « 1. Backup strategy »Composants à sauvegarder :
- Base de données (quotidien)
- Configuration Keycloak (hebdomadaire)
- Code source (Git + mirrors)
- Fichiers Object Storage (stratégie définie)
2. Recovery procedures
Section intitulée « 2. Recovery procedures »Database Recovery :
# Restauration depuis backuppsql $DATABASE_URL < backup.sql
# Ou point-in-time recovery si supporté# Dépend du provider de DBApplication Recovery :
# Redéploiement depuis Gitgit checkout <stable_commit>git push clever-cloud main
# Rollback migrations si nécessairealembic downgrade <revision>3. RTO/RPO Targets
Section intitulée « 3. RTO/RPO Targets »- RTO (Recovery Time Objective) : < 4 heures
- RPO (Recovery Point Objective) : < 24 heures
- Availability Target : 99.5% (43.8 heures downtime/an)
Version : 1.0.0
Dernière mise à jour : 2024-01-15