Aller au contenu

Exemple 1 : Déployer une Application Microservices Complète

Ce guide est le tutoriel le plus complet de cette documentation. Nous allons prendre une application microservices complexe, api-utils, et suivre chaque étape de son intégration, sa configuration locale, et son déploiement en production sans interruption de service grâce à la plateforme Nekristo.

1. Contexte : L'application api-utils

api-utils est une plateforme de services utilitaires. Son architecture est un excellent cas d'étude :

  • Une API Gateway (api-gateway) sert de point d'entrée unique et sécurisé.
  • Une Interface d'Administration (admin-ui) en React pour gérer la plateforme.
  • 7 Microservices Spécialisés (storage, documents, notifications, ai, scheduler, management), chacun avec sa propre base de données.
  • Des Workers Asynchrones (Celery) pour les tâches longues.
  • Des Consumers (Kafka) pour la messagerie événementielle.

Notre objectif : transformer cette application complexe en un projet standardisé, facile à gérer et à déployer grâce à nekristo-cli.

2. Étape 1 : Créer le Dossier et Intégrer le Code

On commence par créer un "conteneur" pour notre application au sein de la plateforme.

nekristo-cli apps new api-utils

Suite à cette commande, déplacez l'intégralité du code source de votre projet (api-gateway/, services/, admin-ui/, etc.) dans le nouveau dossier apps/api-utils/.

3. Étape 2 : Le Manifeste nekristo.yml (Le Cœur du Système)

C'est ici que la magie opère. Nous allons décrire toute notre architecture dans un seul fichier nekristo.yml à la racine de apps/api-utils/. Ce manifeste est puissant : il déclare les dépendances, la stratégie de déploiement, les migrations, la vérification de santé et les tests.

# apps/api-utils/nekristo.yml
app_name: api-utils
version: '1.0'

# Déclare les services d'infrastructure partagée dont cette application a besoin.
# 'nekristo-cli apps start' les démarrera automatiquement si nécessaire.
infra_dependencies:
  - database
  - cache
  - messaging

components:
  # --- Composant public (exposé sur le web) ---
  - name: api-gateway
    path: ./api-gateway
    type: python
    public_port: 8000
    run_command: uvicorn main:app --host 0.0.0.0 --port 8000
    # Configuration pour le développement local (hot-reload)
    development:
      run_command: uvicorn main:app --host 0.0.0.0 --port 8000 --reload
      volumes:
        - "./api-gateway:/app"
    local_domain: api.utils.127.0.0.1.nip.io
    public_domain: api.utils.nekristo.com
    letsencrypt: true
    healthcheck:
      path: "/health"
      start_period: "20s"
    deployment:
      strategy: "blue-green"
      hooks:
        pre_deploy: "alembic upgrade head"

  - name: admin-ui
    path: ./admin-ui
    dockerfile: Dockerfile # Utilise un Dockerfile custom pour React
    public_port: 80
    local_domain: admin.utils.127.0.0.1.nip.io
    public_domain: admin.utils.nekristo.com
    letsencrypt: true
    healthcheck:
      path: "/" # Pour un site statique, la racine suffit
    deployment:
      strategy: "blue-green"

  # --- Microservices Backend (privés) ---
  - name: document-generator-service
    path: ./services/document-generator-service
    type: python
    run_command: uvicorn main:app --host 0.0.0.0 --port 8001
    development:
      run_command: uvicorn main:app --host 0.0.0.0 --port 8001 --reload
      volumes:
        - "./services/document-generator-service:/app"
    database: { name: document_generator_db, migration_command: "alembic upgrade head" }
    healthcheck: { path: "/health" }
    deployment: { hooks: { pre_deploy: "alembic upgrade head" } }

  - name: storage-service
    path: ./services/storage-service
    type: python
    run_command: uvicorn main:app --host 0.0.0.0 --port 8002
    development:
      run_command: uvicorn main:app --host 0.0.0.0 --port 8002 --reload
      volumes:
        - "./services/storage-service:/app"
    database: { name: storage_db, migration_command: "alembic upgrade head" }
    healthcheck: { path: "/health" }
    deployment: { hooks: { pre_deploy: "alembic upgrade head" } }

  - name: notifications-service
    path: ./services/notifications-service
    type: python
    run_command: uvicorn main:app --host 0.0.0.0 --port 8003
    development:
      run_command: uvicorn main:app --host 0.0.0.0 --port 8003 --reload
      volumes:
        - "./services/notifications-service:/app"
    database: { name: notifications_db, migration_command: "alembic upgrade head" }
    healthcheck: { path: "/health" }
    deployment: { hooks: { pre_deploy: "alembic upgrade head" } }

  - name: ai-service
    path: ./services/ai-service
    type: python
    run_command: uvicorn main:app --host 0.0.0.0 --port 8004
    development:
      run_command: uvicorn main:app --host 0.0.0.0 --port 8004 --reload
      volumes:
        - "./services/ai-service:/app"
    database: { name: ai_db, migration_command: "alembic upgrade head" }
    healthcheck: { path: "/health" }
    deployment: { hooks: { pre_deploy: "alembic upgrade head" } }

  - name: scheduler-service
    path: ./services/scheduler-service
    type: python
    run_command: uvicorn main:app --host 0.0.0.0 --port 8005
    development:
      run_command: uvicorn main:app --host 0.0.0.0 --port 8005 --reload
      volumes:
        - "./services/scheduler-service:/app"
    database: { name: scheduler_db, migration_command: "alembic upgrade head" }
    healthcheck: { path: "/health" }
    deployment: { hooks: { pre_deploy: "alembic upgrade head" } }

  - name: management-service
    path: ./services/management-service
    type: python
    run_command: uvicorn main:app --host 0.0.0.0 --port 8006
    development:
      run_command: uvicorn main:app --host 0.0.0.0 --port 8006 --reload
      volumes:
        - "./services/management-service:/app"
    database: { name: management_db, migration_command: "alembic upgrade head" }
    healthcheck: { path: "/health" }
    deployment: { hooks: { pre_deploy: "alembic upgrade head" } }

  # --- Workers & Consumers (tâches de fond) ---
  - name: document-worker
    path: ./services/document-generator-service
    type: python
    run_command: celery -A celery_config worker -l info -Q documents
    development: # Monter le volume pour voir les changements de code worker
      volumes: ["./services/document-generator-service:/app"]
    database: { name: document_generator_db }
    deployment: {}

  - name: storage-worker
    path: ./services/storage-service
    type: python
    run_command: celery -A celery_config worker -l info -Q storage
    development: { volumes: ["./services/storage-service:/app"] }
    database: { name: storage_db }
    deployment: {}

  - name: notifications-worker
    path: ./services/notifications-service
    type: python
    run_command: celery -A celery_config worker -l info -Q notifications
    development: { volumes: ["./services/notifications-service:/app"] }
    database: { name: notifications_db }
    deployment: {}

  - name: ai-worker
    path: ./services/ai-service
    type: python
    run_command: celery -A celery_config worker -l info -Q ai
    development: { volumes: ["./services/ai-service:/app"] }
    database: { name: ai_db }
    deployment: {}

  - name: kafka-consumer
    path: ./services/messaging
    type: python
    run_command: python kafka_consumer.py
    development: { volumes: ["./services/messaging:/app"] }
    deployment: {}

# Section pour définir comment lancer les tests pour cette application.
tests:
  run_command: "pytest"

4. Étape 3 : Centraliser la Gestion des Secrets

La gestion des secrets reste centralisée et sécurisée.

  • Utilisez nekristo-cli secrets edit --env dev pour vos secrets de développement.
  • Utilisez nekristo-cli secrets edit --env prod pour chiffrer vos secrets de production avec GPG.

5. Étape 4 : Lancement et Test en Local

Le processus de lancement local est maintenant plus simple et plus intelligent.

  1. Démarrez l'infrastructure globale (Nginx, Portainer, etc.). Cette commande ne doit être lancée qu'une seule fois.

    bash nekristo-cli up

  2. Configurez le proxy local. Le CLI va lire tous les local_domain de vos manifestes et configurer Nginx Proxy Manager automatiquement.

    bash nekristo-cli platform setup-proxy

    (Au premier lancement, il lira les identifiants depuis secrets.dev.yml ou vous les demandera. Par défaut : email admin@example.com, mot de passe changeme)

  3. Appliquez les secrets de développement. Le CLI générera les fichiers .env pour chaque application.

    bash nekristo-cli secrets apply --env dev

  4. Démarrez l'application api-utils. La magie opère ici : le CLI va lire les infra_dependencies du manifeste, créer les bases de données si elles n'existent pas, et s'assurer que l'infrastructure est démarrée avant de lancer l'application.

    bash nekristo-cli apps start api-utils

    Votre environnement de développement complet est maintenant en ligne ! Les services sont accessibles via http://api.utils.127.0.0.1.nip.io et http://admin.utils.127.0.0.1.nip.io. Le hot-reloading devrait être actif pour les services Python.

  5. Lancez les tests. Une fois l'environnement démarré, validez son intégrité en lançant la suite de tests.

    bash nekristo-cli apps test api-utils

6. Étape 5 : Préparation au Déploiement

  1. Configurez votre branche de déploiement et autres paramètres globaux dans platform.yml.

    ```yaml

    platform.yml

    deploy_branch: deploy docker_registry_prefix: "ghcr.io/votre-organisation" gpg_recipient: "votre.email@gpg.com" ```

  2. Générez le workflow de CI/CD. Cette commande crée le fichier .github/workflows/deploy.yml qui inclut maintenant les étapes de validation, test, build, scan de sécurité et déploiement.

    bash nekristo-cli ci gen-workflow

  3. Ajoutez les secrets sur GitHub. Utilisez la commande nekristo-cli ci setup-secrets (recommandé, après platform provision-vps) ou ajoutez manuellement les secrets dans Settings > Secrets and variables > Actions de votre dépôt (voir le guide vps-setup.md pour la liste complète).

7. Étape 6 : Déploiement Automatisé

Un git push sur votre branche de déploiement (deploy dans cet exemple) déclenchera le workflow. GitHub Actions va :

  • Valider tous les manifestes.
  • 🧪 Tester l'application pour s'assurer qu'il n'y a pas de régression.
  • 📦 Construire les images Docker.
  • 🛡️ Scanner chaque image avec Trivy pour détecter les vulnérabilités.
  • 🐘 Créer automatiquement les bases de données de production si elles n'existent pas.
  • 🚀 Exécuter les migrations de base de données (pre_deploy hooks).
  • 🌐 Déployer les nouvelles versions en utilisant la stratégie Blue-Green, garantissant ainsi une mise à jour sans aucune interruption de service.
  • ⚙️ Configurer Nginx Proxy Manager pour basculer le trafic et activer le HTTPS.