# Over — vue d'ensemble

Over est une plateforme perso de **déploiement + monitoring** de conteneurs Docker,
pilotée par un fichier de config YAML. Fork MIT de Haloy.

## Composants

| Binaire | Rôle | Où il tourne |
|---|---|---|
| `over` | CLI client (déploie, interroge, gère les serveurs) | ton poste / CI |
| `overd` | Agent : API HTTP, construit/lance les conteneurs, self-heal | chaque serveur cible |
| `over-proxy` | Reverse-proxy (routage domaines + TLS Let's Encrypt) | chaque serveur cible |
| `over-hub` | Plan de contrôle : monitoring flotte, dashboard, gateway, distribution binaires | nœud de contrôle |

Flux : `over` (CLI) → API `overd` (directe ou via le gateway du hub) → Docker + `over-proxy`.
`over-hub` interroge chaque `overd` en lecture et agrège l'état de la flotte.

## Modèle serveur & authentification

Un « serveur » = une base d'URL + un token Bearer, enregistrés côté client :

```
over server add <url> <token>      # stocke le token dans ~/.config/over/.env
over server list                   # liste les serveurs connus
over server delete <url>
```

Deux façons de joindre un agent :
- **Directe** : `over server add https://mon-serveur.example.com <token-agent>`
- **Via le gateway du hub** (un seul endpoint + un seul token pour toute la flotte,
  le hub relaie vers l'agent nommé et injecte le token de l'agent) :
  `over server add https://<hub>:9443/gw/<nom-serveur> <token-gateway>`

## Connecter un nouveau device (enrollment, façon Tailscale)

Sur le hub (nœud de contrôle), génère une **clé d'enrôlement à usage unique** :

```
over-hub enroll --hub https://<hub>:9443            # clé valable 15 min par défaut
```

Ça imprime une commande unique à lancer sur le nouveau device (qui doit être sur
le tailnet) — elle installe le CLI **et** connecte au hub :

```
curl -fsSL https://over.cx/install.sh | sh -s -- --enroll https://<hub>:9443 <clé>
# Windows : $env:OVER_ENROLL="https://<hub>:9443 <clé>"; irm https://over.cx/install.ps1 | iex
# déjà installé :  over enroll https://<hub>:9443 <clé>
```

Le device échange la clé contre un **token révocable** propre à lui. Gestion côté hub :

```
over-hub tokens list                 # devices connectés
over-hub tokens revoke <id>           # coupe l'accès d'un device
```

## Commandes CLI principales

| Commande | Effet |
|---|---|
| `over deploy` | Construit + déploie l'app décrite par le config du dossier courant |
| `over status` | État de l'app (dossier courant) sur son/ses serveur(s) |
| `over stop` | Arrête l'app (désir = stopped ; le self-heal ne la relance pas) |
| `over logs` | Logs de l'app |
| `over rollback` | Revient au déploiement précédent |
| `over exec -- <cmd>` | Exécute une commande one-shot dans le conteneur (config du dossier) |
| `over exec --server <url> --app <nom> -- <cmd>` | Idem **sans projet**, depuis n'importe où (ex. via le gateway) |
| `over validate-config` | Valide le fichier de config (`--show-resolved-config` pour voir le rendu) |
| `over server version -s <url>` | Version d'`overd`/`over-proxy` d'un serveur |
| `over fleet` | **État agrégé de toute la flotte** via le hub (voir plus bas) |
| `over docs` | Affiche cette documentation |
| `over update` | Télécharge + installe le dernier binaire `over` (self-update) |
| `over version` | Version du CLI |

La plupart des commandes app (`deploy`, `status`, `stop`, `logs`…) lisent le **config du
dossier courant** (`over.yaml`/`over.json`/`over.toml`). `over fleet`, `over docs`,
`over version`, `over server …` n'ont pas besoin de config.

## Fichier de config d'une app (`over.yaml`)

Clés YAML en **snake_case**. `name`, `image.repository` et `server` sont requis.

**A) Image depuis un registre :**

```yaml
name: whoami
image:
  repository: traefik/whoami        # tag optionnel: "repo:1.2.3" ou champ `tag:`
server: https://mon-serveur.example.com   # ou l'URL gateway du hub (…:9443/gw/<serveur>)
domains:
  - domain: whoami.example.com      # over-proxy route + obtient le cert TLS Let's Encrypt
    # aliases: [www.whoami.example.com]
port: "80"                          # port interne du conteneur (défaut 80)
env:
  - name: SOME_VAR
    value: "hello"
```

**B) Build local depuis un Dockerfile** — il n'existe **pas** de `image.dockerfile` ;
on active `image.build: true` et on décrit `build_config`. `repository` reste requis
(= nom de l'image construite). Par défaut l'image est **poussée vers le serveur**
(pas besoin de registre) :

```yaml
name: mon-app
image:
  repository: mon-app               # nom de l'image locale construite
  build: true
  build_config:
    context: .                      # dossier de build
    dockerfile: Dockerfile          # chemin du Dockerfile (relatif au context)
    # platform: linux/amd64
    # push: server                  # "server" (défaut) | "registry"
server: https://mon-serveur.example.com
domains:
  - domain: mon-app.example.com
port: "80"
```

Autres champs utiles : `replicas`, `volumes` (`["nom:/chemin"]`), `network`,
`health_check_path`, `pre_deploy`/`post_deploy`, `deployment_strategy`
(`rolling` défaut | `replace`), `env[].secret` / `env[].from` pour les secrets.

Plusieurs cibles (`targets:`) peuvent déployer la même app sur plusieurs serveurs ;
`--targets a,b` ou `--all` sélectionne lesquelles. Valide toujours avec
`over validate-config` avant de déployer.

## Fleet status (`over fleet`)

Interroge le hub (`/api/state`) et affiche serveurs + apps + métriques (CPU/RAM/disque),
depuis n'importe où — aucun `over.yaml` requis.

```
over fleet                 # tableau lisible
over fleet --json          # JSON brut (pour un agent / du scripting)
over fleet --hub https://<hub>:9443   # forcer l'URL du hub
```

Sans `--hub`, l'URL du hub est déduite d'un serveur gateway déjà enregistré
(la partie avant `/gw/`), ou de la variable d'env `OVER_HUB`.

## Self-heal (agent `overd`)

L'agent tient un **état désiré** par app (`running`/`stopped`) et un reconciler
(~20 s) : si une app censée tourner est arrêtée/supprimée, il la redémarre — ou la
recrée depuis le dernier déploiement stocké (sauf si elle dépend de secrets externes
non résolubles côté agent). `over stop` met le désir à `stopped` → pas de relance.

## Endpoints du hub (Tailscale-only, https :9443)

| Chemin | Usage |
|---|---|
| `/` | Dashboard web (flotte, apps, graphes) |
| `/api/state` | JSON de l'état agrégé (utilisé par `over fleet` et le dashboard) |
| `/gw/<serveur>/…` | Gateway : relaie vers l'API de l'agent nommé |
| `/dl` , `/dl/<binaire>` | Téléchargement des binaires (`over-linux-amd64`, `over-windows-amd64.exe`, …) |
| `/install-over.sh` , `/install-overd.sh` | Scripts d'installation |
| `/docs` | Cette documentation (markdown) |
| `/healthz` | Health check |

## Endpoints de l'agent `overd`

`/health` (non authentifié), puis (Bearer token) : `/v1/version`, `/v1/apps`
(auto-découverte des apps + état désiré), `/v1/metrics` (CPU/RAM/disque/load/uptime),
`/v1/status/{app}`, `/v1/deploy`, `/v1/stop/{app}`, `/v1/logs/{app}`.

## Alerting

Le hub peut poster sur un **webhook Discord** aux transitions (serveur/app DOWN →
🔴, recovered → 🟢), avec debounce. Activé en renseignant `alerts.discord.webhookUrl`
dans la config du hub.
