Vue d'ensemble de l'architecture
Gitrust est une plateforme d'hébergement Git auto-hébergée construite sur le framework rustwarden-core. L'application expose deux points d'entrée réseau (HTTP + SSH) et persiste ses données dans PostgreSQL.
Vue d'ensemble
graph TB
subgraph Clients
Browser["Navigateur Web"]
GitCLI["Git CLI (ssh/https)"]
end
subgraph "Gitrust Binary (src/main.rs)"
Main["main()"]
end
subgraph "Crates Gitrust"
Web["gitrust-web<br/><i>Routes HTTP, templates,<br/>handlers Axum</i>"]
SSH["gitrust-ssh<br/><i>Serveur SSH (russh),<br/>auth par clé, sessions</i>"]
SshGuard["gitrust-ssh-guard<br/><i>SecureListener, détecteurs,<br/>BanManager, AuthTracker</i>"]
Hooks["gitrust-hooks<br/><i>impl RustwardenHooks<br/>(on_user_registered, ...)</i>"]
Core["gitrust-core<br/><i>Models, services, migrations,<br/>rôles, types, DTOs</i>"]
Git["gitrust-git<br/><i>Bare repos, tree browser,<br/>pack protocol (git2)</i>"]
end
subgraph "Framework"
RW["rustwarden-core<br/><i>Auth, users, JWT, sessions,<br/>ResourceService, i18n</i>"]
end
subgraph "Stockage"
PG[(PostgreSQL)]
FS[("Système de fichiers<br/>bare repos .git")]
end
subgraph "CI/CD (optionnel)"
CiWorker["CiWorker<br/><i>tokio::spawn, mpsc,<br/>sous-processus Dagger</i>"]
Dagger["Dagger Engine<br/><i>Containers isolés,<br/>cache, exécution</i>"]
CiEngine["ci-engine<br/><i>Module Dagger Python<br/>(Easy Mode)</i>"]
Syft["Syft (optionnel)<br/><i>Génération SBOM<br/>CycloneDX</i>"]
DTrack["Dependency-Track<br/>(optionnel)<br/><i>Analyse vulnérabilités</i>"]
end
Browser -->|HTTP :4000| Web
GitCLI -->|SSH :2222| SshGuard
SshGuard -->|"AcceptOutcome::Accepted"| SSH
GitCLI -->|HTTPS :4000| Web
Main --> Web
Main --> SSH
Main --> SshGuard
Main --> Hooks
Main -.->|"si CI_ENABLED"| CiWorker
Web --> Core
Web --> Git
Web -.->|"admin ACL/ban"| SshGuard
SSH --> Core
SSH --> Git
SSH --> SshGuard
SshGuard --> Core
Hooks --> Core
Core --> RW
Core --> PG
Git --> FS
CiWorker --> Core
CiWorker -->|"dagger call"| Dagger
Dagger -->|"Easy Mode"| CiEngine
Dagger -->|"Power Mode"| FS
CiWorker -.->|"si CI_SBOM_ENABLED"| Syft
Syft -.->|"si CI_DTRACK_ENABLED"| DTrack
Démarrage de l'application
Le diagramme suivant détaille la séquence d'initialisation depuis main() jusqu'au démarrage des serveurs HTTP et SSH.
sequenceDiagram
participant Main as main()
participant Builder as RustwardenBuilder
participant App as RustwardenApp
participant Mig as AppMigrator
participant DB as PostgreSQL
participant SMTP as Serveur SMTP
Main->>Main: GitrustConfig::from_env()
Main->>Main: Arc<GitrustHooks> (hooks FS)
Main->>Builder: builder().from_env()
Note over Builder: Charge .env, init tracing
Main->>Builder: .headless().auto_migrate(false)
Main->>Builder: .merge_routes(app_routes(hooks))
Note over Builder: Routes = framework API<br/>+ pages SSR gitrust<br/>+ Extension(hooks)
Main->>Builder: .build().await
Builder->>DB: Connexion pool
Builder->>DB: Migrations rustwarden-core
Builder->>SMTP: EmailQueueProcessor.start()
Note over SMTP: Worker de fond : dépile<br/>email_queue toutes les 30s
Builder-->>Main: RustwardenApp
Main->>Mig: run_migrations(app.database())
Mig->>DB: core_migrations() + gitrust_migrations()
Note over DB: Tables: users, resources,<br/>repositories, ssh_keys,<br/>teams, team_members,<br/>team_repository_access
Mig-->>Main: Ok
Main->>Main: tokio::spawn(SSH server :2222)
alt CI_ENABLED=true
Main->>Main: CiWorker::start(config.ci)
Note over Main: Vérifie dagger dans PATH<br/>Si CI_SBOM_ENABLED: vérifie syft<br/>Si CI_DTRACK_ENABLED: vérifie API DT
Main->>Main: tokio::spawn(CiWorker loop)
Note over Main: Écoute mpsc channel<br/>pour les jobs CI
end
Main->>App: app.run().await
Note over App: HTTP :4000 démarre
Principes de conception
Séparation framework / métier gitrust
Gitrust est construit au-dessus de rustwarden-core, un framework Rust d'authentification et de gestion d'utilisateurs. Cette séparation est intentionnelle :
- rustwarden-core gère : auth JWT, sessions, users, roles génériques, i18n, SMTP, OAuth, audit log générique.
- gitrust-core gère : tout ce qui est spécifique à la forge Git — dépôts, clés SSH, équipes, permissions RBAC à 4 niveaux, CI, import de dépôts.
La règle fondamentale : ne jamais modifier crates/rustwarden-core/. Toute extension passe par des wrappers, des hooks (RustwardenHooks) ou des traits implémentés côté gitrust.
Mode headless
gitrust-web opère en mode headless() : les pages UI standard de rustwarden (login, register, settings) sont désactivées et réimplémentées entièrement dans gitrust-web/templates/. Cela permet un design cohérent (sidebar Git, DaisyUI) sans compromis avec l'UI générique du framework.
SSR + HTMX, zéro CDN
L'interface est rendue côté serveur via Askama (templates Rust compilés). HTMX gère les interactions dynamiques (mises à jour partielles de page, SSE pour les notifications et les logs CI). Aucun asset externe : tout CSS/JS est servi depuis static/ — imposé par la Content Security Policy du framework.
Bare repos sur le système de fichiers
gitrust-git est découplé de la base de données. Les opérations Git (navigation d'arbre, lecture de blobs, pack protocol) travaillent directement sur les bare repos ({GIT_REPOS_BASE_PATH}/{owner}/{slug}.git/) via libgit2. La base ne stocke que les métadonnées (nom, description, visibilité, ownership). Ce découplage permet de remplacer ou tester gitrust-git indépendamment.
CI hybride : Dagger comme abstraction d'exécution
Plutôt que d'implémenter un runner CI from scratch, gitrust délègue l'exécution à Dagger, qui garantit l'isolation (containers), la reproductibilité (cache) et la portabilité (local ou runner distant via SSH+rsync). Le CiWorker est une tâche Tokio dans le processus principal — pas un daemon séparé — ce qui simplifie le déploiement (un seul binaire).
Pour aller plus loin
- Référence structurelle complète (tables de modules, routes, dépendances) : Architecture des crates
- Diagrammes de séquence détaillés (clone SSH, push, permissions) : Flux de requêtes
- Conception de la couche de durcissement SSH : Conception de ssh-guard et Crate gitrust-ssh-guard
- Règles de code et gates QA : Règles QA et conformité ANSSI
GitRust