Étude de cas : iolite-ifrit
Cloud OS — 14 crates, single binary ~4.3 MB
Iolite Ifrit
Cloud OS — API de déploiement en Rust
API légère en Rust remplaçant Portainer. Single binary ~4.3 MB, 14 crates workspace, 24 routes API. Évolue vers un Cloud OS complet absorbant monitoring, databases, SSO, backup, GitOps.
iolite-ifrit est un Cloud OS en Rust qui remplace Portainer par un single binary léger (~4.3 MB), extensible via un workspace Cargo de 14 crates couvrant déploiement, proxy, base de données, SSO, backup et observabilité.
1. Contexte et objectifs
Problématique
Portainer est trop lourd et pas assez auditable. Iolite-ifrit est un single binary Rust qui fait la même chose en ~4.3 MB de RAM. Extensible vers un Cloud OS complet.
Pourquoi remplacer Portainer ?
Légèreté
Single binary ~4.3 MB vs image Docker Portainer de plusieurs centaines de MB.
Auditabilité
Code Rust compilé, pas de runtime interprété. Chaque route est traçable.
Extensibilité
Pattern "absorb progressively" : chaque phase ajoute un crate sans toucher les autres.
Cloud OS
Évolue au-delà du déploiement : monitoring, databases, SSO, backup, GitOps.
2. Architecture : 14 crates workspace
Le projet est structuré en un Cargo workspace de 14 crates, chacun responsable d'un domaine fonctionnel distinct :
crates/
├── core/ # Shared types, RFC 9457 errors, YAML config
├── docker/ # Docker SDK wrapper, compose runner
├── engine/ # Deploy orchestration (recreate + blue-green)
├── server/ # Main API server (Axum, routes)
├── auth/ # Bearer token bcrypt, scopes middleware
├── logging/ # Tracing JSON, audit log
├── metrics/ # Prometheus registry
├── proxy/ # Traefik dynamic config per app
├── database/ # PostgreSQL provisioning (age-encrypted)
├── gitops/ # app.yml compiler + webhook parsing
├── observability/ # Prometheus scrape targets + alert rules
├── identity/ # Authentik SSO provisioning
├── backup/ # Restic + WAL-G backup/verify/forget
└── static-sites/ # Caddyfile generation, tar.gz deploy Vue d'ensemble
API Server (Axum)
├── Docker Engine → Deploy (recreate/blue-green)
├── Proxy → Traefik dynamic config
├── Database → PostgreSQL provisioning
├── Identity → Authentik SSO
├── Backup → Restic + WAL-G
├── GitOps → Webhook handlers
└── Observability → Prometheus targets 3. Blue-green deployment
Iolite-ifrit supporte deux stratégies de déploiement : recreate (stop old, start new) et blue-green (run both, swap when healthy). Le blue-green utilise 2 stacks avec swap des labels Traefik. Rollback automatique si le health check échoue.
Deploy Strategy
Enum Rust définissant les stratégies de déploiement avec configuration du timeout et du rollback automatique.
// Deploy strategy enum
pub enum DeployStrategy {
Recreate, // Stop old, start new
BlueGreen { // Run both, swap when healthy
health_timeout: Duration,
rollback_on_failure: bool,
},
} 4. Auth avec scopes glob
L'authentification utilise des Bearer tokens avec hashing bcrypt. Les scopes supportent les glob patterns pour un contrôle d'accès flexible :
*— accès totalprefix-*— toutes les apps commençant par "prefix-"exact-match— une app spécifique
5. RFC 9457 Problem Detail
Toutes les erreurs suivent le standard RFC 9457 (Problem Details for HTTP APIs). Chaque réponse d'erreur est structurée et parseable par les clients.
Problem Detail
Structure standard pour les erreurs HTTP, conforme à la RFC 9457.
#[derive(Serialize)]
pub struct ProblemDetail {
pub r#type: String,
pub title: String,
pub status: u16,
pub detail: Option<String>,
pub instance: Option<String>,
} 6. 24 routes API
L'API expose 24 routes couvrant l'ensemble des fonctionnalités du Cloud OS :
Health & Metrics
Health check, métriques Prometheus, statut du serveur.
Deploy
Déploiement recreate et blue-green, statut des déploiements en cours.
Apps & Static Sites
Gestion des applications, déploiement de sites statiques via tar.gz + Caddyfile.
Proxy & Database
Configuration dynamique Traefik, provisioning PostgreSQL avec chiffrement age.
GitOps & Webhooks
Compilation app.yml, handlers pour webhooks GitLab et GitHub.
Identity, Backup & Observability
Provisioning Authentik SSO, Restic + WAL-G backup, Prometheus scrape targets.
7. Roadmap : 8 phases
Le projet a suivi une roadmap en 8 phases. Chaque phase ajoutait un module (crate) au workspace. Toutes sont complétées sauf la Phase 6 (health removed as SPOF).
Core + Deploy
Server Axum, Docker SDK, recreate deploy
Blue-Green
Deploy blue-green avec swap Traefik
Auth + Proxy
Bearer tokens, scopes glob, Traefik config
Database
PostgreSQL provisioning, age-encrypted
GitOps
app.yml compiler, webhook handlers
Health
Removed as SPOF
Identity + Backup
Authentik SSO, Restic + WAL-G
Observability
Prometheus targets, alert rules
8. Métriques et résultats
Performance en production
9. Enseignements
Cargo workspace = modularité sans overhead
14 crates indépendants compilés ensemble. Ajout d'un module = ajout d'un crate, zero impact sur les autres.
Claude Code efficace en systems programming Rust
75 sessions pour un binary de 4.3 MB. Le typage strict de Rust et le compilateur compensent les erreurs potentielles.
Pattern "absorb progressively"
Chaque phase ajoute un crate sans toucher les autres. L'architecture grandit organiquement sans dette technique.
RFC 9457 + structured logging
Erreurs standardisées + tracing JSON = debugging facile. Chaque erreur est typée, titrée et détaillée.