33800 Docs

← Retour

Smart-Deploy System

Système de déploiement hybride combinant GitLab CI/CD avec des scripts bash modulaires.

Quick Start

1. Ajouter la config à votre projet

Créer conf.prod.gouroubleu.yml à la racine du projet :

name: "mon-api"
target: "prod-portainer"
type: "node"
port: 3000
domain: "mon-api.33800.nowhere84.com"

nginx:
  enabled: true
  ssl: true

health: "/health"
logs: true

2. Ajouter le pipeline CI/CD

Créer .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"

3. Push et déployer

git add .
git commit -m "Add CI/CD deployment"
git push origin main

Configuration complète

Champs obligatoires

Champ Description Exemple
name Nom unique du service mon-api
target Machine cible prod-portainer, nginx, o2switch

Champs recommandés

Champ Description Exemple
type Type de projet node, bun, python, rust, static
port Port d'écoute 3000
domain Domaine public api.33800.nowhere84.com
health Endpoint health check /health (défaut)

Sections optionnelles

Services (injection automatique de variables)

services:
  - supabase    # DATABASE_URL, SUPABASE_URL, SUPABASE_ANON_KEY
  - redis       # REDIS_URL
  - ntfy        # NTFY_URL, NTFY_TOPIC
  - ai          # ORCHESTRATOR_URL, WIN11_HOST
  - monitoring  # GRAFANA_URL, PROMETHEUS_URL, LOKI_URL
  - gitlab      # GITLAB_URL, GITLAB_TOKEN

Nginx

nginx:
  enabled: true
  ssl: true
  websocket: false
  rate_limit: "10r/s"

Deploy (stratégie remote)

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

Storage (stratégie files)

storage:
  shared: "logs data uploads"
  keep_releases: 5

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)

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/
└── current -> releases/2026-01-21_13-00-00-def5678

Remote (o2switch)


Health Check

Le health check est obligatoire pour tous les services exposés.

Endpoint requis

Votre service doit exposer un endpoint /health (configurable) qui retourne :

{
  "status": "healthy",
  "version": "1.2.3",
  "uptime": {
    "seconds": 3600,
    "human": "1h 0m 0s"
  },
  "system": {
    "hostname": "container-id",
    "memory": { "used": 128, "total": 512, "unit": "MB" }
  },
  "scheduledJobs": [
    {
      "name": "cleanup",
      "cron": "0 0 * * *",
      "description": "Daily cleanup",
      "enabled": true
    }
  ],
  "dependencies": [
    { "name": "database", "status": "healthy" }
  ]
}

Comportement

  1. Après déploiement, attente 5s puis health check
  2. 10 tentatives espacées de 3s
  3. Si status != "healthy" ou HTTP 503 → rollback automatique
  4. Notification push via ntfy

Rollback

Rollback automatique

Déclenché si :

Rollback 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

Déploiement manuel

# Depuis le répertoire du projet
cd /chemin/vers/mon-projet

# Définir les variables
export CI_PROJECT_DIR="$(pwd)"
export DEPLOY_ENV="prod"
export DEPLOY_CONFIG="conf.prod.gouroubleu.yml"

# Exécuter le déploiement
/stock_8to/33800-stack/scripts/deploy/smart-deploy.sh

Notifications

Les notifications sont envoyées via ntfy :

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

Registre des services

Les services déployés sont trackés dans :

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

Consulter le registre

# Via jq
cat /stock_8to/33800-stack/monitoring/services-registry.json | jq .

# Liste des services
cat /stock_8to/33800-stack/monitoring/services-registry.json | jq -r '.services | keys[]'

Dashboard

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


Troubleshooting

Le déploiement échoue avec "Config non trouvée"

Vérifier que le fichier conf.prod.gouroubleu.yml existe à la racine du projet.

Health check timeout

  1. Vérifier que le service expose /health
  2. Vérifier que le port est correct
  3. Augmenter le timeout si le service démarre lentement :
    export HEALTH_CHECK_TIMEOUT=60
    export HEALTH_CHECK_RETRIES=20

Rollback échoue

Pour Docker, vérifier que le tag :previous existe dans le registre. Pour Files/Remote, vérifier qu'une release précédente existe.

Pas de notification

Vérifier :

  1. Service ntfy actif : curl https://ntfy.33800.nowhere84.com/health
  2. Variable NTFY_ENABLED=true

Architecture

scripts/deploy/
├── smart-deploy.sh          # Script principal
├── rollback.sh              # Rollback manuel
├── machines-registry.json   # Registre des machines
├── lib/
│   ├── common.sh            # Fonctions utilitaires
│   ├── parse-yaml.sh        # Parser YAML
│   ├── targets.sh           # Résolution targets
│   ├── services.sh          # Injection variables
│   ├── dns.sh               # Gestion DNS
│   ├── nginx.sh             # Config Nginx
│   ├── notifications.sh     # Notifications ntfy
│   ├── registry.sh          # Registre services
│   └── health.sh            # Health check
├── strategies/
│   ├── docker.sh            # Stratégie Docker
│   ├── files.sh             # Stratégie Files
│   └── remote.sh            # Stratégie Remote
└── templates/
    ├── Dockerfile.node
    ├── Dockerfile.bun
    └── nginx-*.conf.template

Exemples

API Node.js (Docker)

name: "mon-api"
target: "prod-portainer"
type: "node"
port: 3000
domain: "api.33800.nowhere84.com"

services:
  - supabase
  - redis

nginx:
  enabled: true
  ssl: true

health: "/health"
logs: true

Site statique (O2switch)

name: "mon-site"
target: "o2switch"
type: "static"
domain: "monsite.nowhere84.com"

deploy:
  method: rsync
  dest: "public_html/monsite"
  backup: true

App Node sur nginx

name: "mon-app"
target: "nginx"
type: "node"
port: 3100

storage:
  shared: "logs uploads"
  keep_releases: 3

deploy:
  post_deploy: "pm2 restart mon-app || pm2 start current/index.js --name mon-app"