33800 Docs

← Retour

Smart-Deploy System - Documentation Technique

Version : 1.0.0 Dernière mise à jour : 21/01/2026 Auteur : Claude + Gouroubleu

Vue d'ensemble

Smart-Deploy est un système de déploiement hybride combinant GitLab CI/CD avec des scripts bash modulaires. Il supporte plusieurs stratégies de déploiement (Docker, Files, Remote) avec health check obligatoire et rollback automatique.

┌─────────────────────────────────────────────────────────────────┐
│                      SMART-DEPLOY SYSTEM                        │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  git push → GitLab CI → Runner → smart-deploy.sh               │
│                                       │                         │
│                    ┌──────────────────┼──────────────────┐      │
│                    ▼                  ▼                  ▼      │
│               [docker.sh]        [files.sh]        [remote.sh]  │
│                    │                  │                  │      │
│                    ▼                  ▼                  ▼      │
│              prod-portainer      nginx/pve          o2switch    │
│                    │                  │                  │      │
│                    └──────────────────┼──────────────────┘      │
│                                       ▼                         │
│                              [health check]                     │
│                                       │                         │
│                              ┌────────┴────────┐                │
│                              ▼                 ▼                │
│                          [SUCCESS]         [ROLLBACK]           │
│                              │                 │                │
│                              ▼                 ▼                │
│                         [notify]          [notify]              │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Architecture des fichiers

/stock_8to/33800-stack/scripts/deploy/
├── smart-deploy.sh              # Script principal (appelé par CI/CD)
├── rollback.sh                  # Script rollback manuel
├── machines-registry.json       # Registre des machines cibles
├── README.md                    # Documentation utilisateur
│
├── lib/                         # Modules partagés
│   ├── common.sh                # Fonctions utilitaires (log_*, require_*)
│   ├── parse-yaml.sh            # Parser YAML pour conf.gouroubleu.yml
│   ├── targets.sh               # Résolution des targets
│   ├── services.sh              # Injection variables de services
│   ├── dns.sh                   # Gestion DNS O2switch
│   ├── nginx.sh                 # Génération config Nginx
│   ├── notifications.sh         # Notifications push (ntfy)
│   ├── registry.sh              # Registre des services déployés
│   └── health.sh                # Health check enrichi
│
├── strategies/                  # Stratégies de déploiement
│   ├── docker.sh                # Docker (build, push, compose)
│   ├── files.sh                 # Files (releases + symlinks)
│   └── remote.sh                # Remote (rsync/git vers o2switch)
│
└── templates/                   # Templates
    ├── Dockerfile.node
    ├── Dockerfile.bun
    ├── Dockerfile.python
    ├── Dockerfile.rust
    ├── Dockerfile.static
    └── nginx-*.conf.template

Phases de développement

Phase Description Status
1 Infrastructure de base (scripts, registry)
2 Stratégie Docker (templates, build, push)
3 Services & Variables (injection auto)
4 DNS & Nginx (auto-génération)
5 Stratégies Files & Remote
6 Notifications & Registre
7 Health Check & Documentation

Configuration (conf.gouroubleu.yml)

Exemple complet

name: "mon-api"
target: "prod-portainer"    # Machine cible
type: "node"                # node, bun, python, rust, static
port: 3000                  # Port d'écoute
domain: "api.33800.nowhere84.com"

# Services à injecter (variables auto)
services:
  - supabase    # DATABASE_URL, SUPABASE_URL, SUPABASE_ANON_KEY
  - redis       # REDIS_URL
  - ntfy        # NTFY_URL, NTFY_TOPIC

# Nginx (auto-généré si enabled)
nginx:
  enabled: true
  ssl: true
  websocket: false

# Health check (obligatoire)
health: "/health"

# Logs Loki
logs: true

# Pour stratégie files
storage:
  shared: "logs data uploads"
  keep_releases: 5

# Pour stratégie remote
deploy:
  method: rsync           # rsync ou git
  dest: "mon-app"
  backup: true
  pre_deploy: "npm install"
  post_deploy: "pm2 restart"

Champs

Champ Obligatoire Description
name Oui Nom unique du service
target Oui Machine cible (prod-portainer, nginx, o2switch...)
type Non Type de projet (auto-détecté si absent)
port Non Port d'écoute (requis pour health check)
domain Non Domaine public
health Non Endpoint health check (défaut: /health)
services Non Liste des services à injecter
nginx Non Configuration Nginx
storage Non Configuration stockage (stratégie files)
deploy Non Configuration déploiement (stratégie remote)

Targets disponibles

Target Type IP Usage
prod-portainer docker 192.168.1.12 Containers PROD
dev-portainer docker 192.168.1.51 Containers DEV
nginx files 192.168.1.104 Sites statiques, apps Node
pve files 192.168.1.4 Scripts, services locaux
o2switch remote yellow.o2switch.net Dashboard, sites externes
win11 files 192.168.1.30 Apps Windows
gitlab files 192.168.1.196 Services GitLab

Stratégies de déploiement

Docker (prod-portainer, dev-portainer)

  1. Auto-détection du type de projet
  2. Génération Dockerfile si absent
  3. Build de l'image
  4. Push vers registry.33800.nowhere84.com
  5. Génération docker-compose.yml
  6. Déploiement via docker compose up -d
  7. Health check
  8. Rollback si échec

Files (nginx, pve, win11, gitlab)

Structure Capistrano-like :

/opt/33800-services/mon-app/
├── releases/
│   ├── 2026-01-21_12-00-00-abc1234/
│   └── 2026-01-21_13-00-00-def5678/
├── shared/
│   ├── logs/
│   ├── data/
│   └── config/
└── current -> releases/2026-01-21_13-00-00-def5678
  1. Création nouvelle release
  2. Rsync des fichiers (avec exclusions)
  3. Symlinks vers shared/
  4. Mise à jour symlink current
  5. Hooks post_deploy
  6. Cleanup anciennes releases

Remote (o2switch)

  1. Vérification connexion SSH
  2. Backup optionnel
  3. Rsync vers destination
  4. Hooks pre/post deploy distants
  5. Init bare repo git si méthode git

Health Check

Format requis

Le service doit exposer un endpoint /health (configurable) retournant :

{
  "status": "healthy",
  "version": "1.2.3",
  "uptime": {
    "seconds": 3600,
    "human": "1h 0m 0s"
  },
  "timestamp": "2026-01-21T12:00:00Z",
  "system": {
    "hostname": "container-id",
    "platform": "linux",
    "nodeVersion": "v20.20.0",
    "memory": {
      "used": 128,
      "total": 512,
      "unit": "MB"
    },
    "cpu": "1.23"
  },
  "scheduledJobs": [
    {
      "name": "cleanup",
      "cron": "0 0 * * *",
      "description": "Daily cleanup",
      "enabled": true
    }
  ],
  "dependencies": [
    {
      "name": "database",
      "status": "healthy",
      "url": "postgres://***:***@host:5432/db"
    }
  ],
  "metrics": {
    "requestsTotal": 1234,
    "errorsTotal": 5
  }
}

Comportement

Condition Action
HTTP 200 + status="healthy" Déploiement réussi
HTTP 200 + status!="healthy" Retry (max 10 fois)
HTTP 503 Rollback immédiat
Timeout (30s) Retry puis rollback
Connexion impossible Retry puis rollback

Configuration

HEALTH_CHECK_TIMEOUT=30      # Timeout par requête (secondes)
HEALTH_CHECK_RETRIES=10      # Nombre de tentatives
HEALTH_CHECK_INTERVAL=3      # Secondes entre tentatives

Rollback

Automatique

Déclenché si :

Manuel

# Rollback 1 version en arrière
/stock_8to/33800-stack/scripts/deploy/rollback.sh conf.prod.gouroubleu.yml 1

# Rollback 2 versions
/stock_8to/33800-stack/scripts/deploy/rollback.sh conf.prod.gouroubleu.yml 2

Notifications

Envoyées via ntfy (https://ntfy.33800.nowhere84.com/deploy)

Événement Priorité Tags
Deploy Start low 🚀
Deploy Success default
Deploy Failure high ❌⚠️
Health Check Failed urgent 🚑🚨
Rollback high ⏪⚠️

Registre des services

Fichier

/stock_8to/33800-stack/monitoring/services-registry.json

Structure

{
  "services": {
    "mon-service": {
      "target": "prod-portainer",
      "strategy": "docker",
      "last_deploy": "2026-01-21T12:00:00Z",
      "commit": "abc1234",
      "version": "1.2.3",
      "domain": "mon-service.33800.nowhere84.com",
      "port": 3000,
      "status": "running",
      "branch": "main",
      "env": "prod"
    }
  },
  "last_updated": "2026-01-21T12:00:00Z"
}

Dashboard

https://dashboard.nowhere84.com/services.html

GitLab CI/CD

Template .gitlab-ci.yml

stages:
  - deploy

deploy-prod:
  stage: deploy
  tags:
    - prod-runner
  image: docker:27
  before_script:
    - apk add --no-cache bash curl jq openssh-client rsync
    - echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY
  script:
    - bash /mnt/stock_8to/33800-stack/scripts/deploy/smart-deploy.sh
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
  variables:
    DEPLOY_ENV: "prod"
    DEPLOY_CONFIG: "conf.prod.gouroubleu.yml"
    CI_REGISTRY: "registry.33800.nowhere84.com"
    CI_REGISTRY_USER: "gouroubleu"
    CI_REGISTRY_PASSWORD: "glpat-yaowLwWBJhXfzJEC8UBC"

Workflow

  1. Push sur branche main → Deploy PROD
  2. Push sur branche develop → Deploy DEV (si configuré)

Exemple : Déployer un nouveau service

1. Créer le projet

mkdir mon-api && cd mon-api
npm init -y
npm install express

2. Ajouter le code avec health check

// index.js
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;
const startTime = Date.now();
const pkg = require('./package.json');

app.get('/health', (req, res) => {
  res.json({
    status: 'healthy',
    version: pkg.version,
    uptime: {
      seconds: Math.floor((Date.now() - startTime) / 1000),
      human: formatUptime(Math.floor((Date.now() - startTime) / 1000))
    },
    timestamp: new Date().toISOString()
  });
});

app.listen(PORT, () => console.log(`Running on ${PORT}`));

3. Créer la config

# conf.prod.gouroubleu.yml
name: "mon-api"
target: "prod-portainer"
type: "node"
port: 3000
domain: "mon-api.33800.nowhere84.com"
health: "/health"

4. Créer le pipeline CI/CD

Copier le template .gitlab-ci.yml ci-dessus.

5. Pousser vers GitLab

git init
git remote add origin git@gitlab.33800.nowhere84.com:gouroubleu/mon-api.git
git add .
git commit -m "Initial commit"
git push -u origin main

6. Vérifier

Troubleshooting

Pipeline échoue avec "Config non trouvée"

Le fichier conf.prod.gouroubleu.yml n'existe pas à la racine du projet.

Health check timeout

  1. Vérifier que le service expose /health
  2. Vérifier le port dans la config
  3. Augmenter le timeout :
    export HEALTH_CHECK_TIMEOUT=60
    export HEALTH_CHECK_RETRIES=20

Rollback échoue

Pas de notification

  1. Vérifier ntfy : curl https://ntfy.33800.nowhere84.com/health
  2. Vérifier NTFY_ENABLED=true

Permission denied sur registre

Le fichier a été créé par root. Corriger :

sudo chown gouroubleu:gouroubleu /stock_8to/33800-stack/monitoring/services-registry.json

Maintenance

Nettoyer les anciennes releases (files)

Les releases sont automatiquement nettoyées selon keep_releases (défaut: 5).

Nettoyer les images Docker

docker image prune -a --filter "until=168h"

Vérifier l'état des services

cat /stock_8to/33800-stack/monitoring/services-registry.json | jq '.services | to_entries[] | {name: .key, status: .value.status}'

Historique des versions

Date Version Changements
20/01/2026 0.1 Phase 1-6 : Infrastructure, Docker, Files, Remote, Notifications
21/01/2026 1.0 Phase 7 : Health check enrichi, documentation, dashboard services