import type { ReactNode } from 'react';
import { Cpu, GitBranch, Network, Radio, Server, ShieldCheck } from 'lucide-react';
import { MarketingHeader } from './MarketingHeader';
import { MarketingFooter } from './MarketingFooter';
const FLOW = [
{
title: 'Caddy (edge partagé)',
detail:
"TLS Let's Encrypt automatique, routage par nom d'hôte. Ce Caddy sert aussi six autres domaines sur ce même serveur — tripoli-edge n'a jamais eu les ports 80/443 pour lui seul.",
},
{
title: 'tripoli-edge — Rust (hyper/tokio)',
detail:
'Reverse-proxy interne (172.17.0.1:9000, passerelle docker0, jamais exposé directement). Expose /healthz et /metrics en clair, sans framework de métriques : cinq compteurs atomiques suffisaient.',
},
{
title: 'tripoli-api — Rust (axum/sqlx)',
detail:
"Authentification par session opaque (Argon2, pas de JWT — révoquer une session, c'est supprimer une ligne). Upload en streaming vers disque, recherche plein texte Postgres.",
},
{
title: 'PostgreSQL + blobs',
detail:
"Conteneur Docker dédié à Tripoli Cloud, séparé de celui d'un autre projet sur ce même serveur. Les fichiers sont nommés par UUID sur disque — le nom d'origine ne vit qu'en base.",
},
];
const LABS: { icon: ReactNode; title: string; detail: string }[] = [
{
icon: ,
title: 'Tunnel WireGuard',
detail:
"10.100.0.0/24 entre le Mac d'administration et le serveur — canal SSH/Ansible, jamais dans le chemin de trafic applicatif.",
},
{
icon: ,
title: 'tripoli-netctl',
detail:
'Netns + veth créés à la demande via rtnetlink (Rust). Testé (création, ping traversant, destruction propre) — volontairement jamais branché sur le trafic de prod.',
},
{
icon: ,
title: 'bird-lab — BGP + BFD',
detail:
'Deux namespaces en session BGP via une racine en transit (AS 65000/65010/65011). Sessions Established, BFD Up et détection de panne vérifiées, puis démonté proprement.',
},
];
const STATE: [string, string][] = [
['Frontend (app/)', 'Fait — branché sur les vraies données de tripoli-api, aucun mock.'],
['WireGuard', 'Fait — 10.100.0.0/24.'],
['tripoli-edge', 'Fait, en prod — /healthz, /metrics vérifiés.'],
['tripoli-api', 'Fait, en prod — auth, fichiers, notifications, recherche.'],
['tripoli-netctl', 'Fait — labo, jamais branché sur le trafic de prod.'],
['Observabilité', 'Fait — scrape Prometheus/Grafana partagé, alertes versionnées.'],
['bird-lab (BGP/BFD)', 'Fait, bonus — démonté après vérification.'],
['CI/CD', 'Fait — Forgejo Actions, compte deploy sans privilège.'],
['OpenTofu', 'Code écrit, non appliqué — identifiants OVH/Hetzner non fournis.'],
];
export function ArchitecturePage() {
return (
Un seul serveur, pas un cluster
Ce qui tourne réellement.
Un VPS Hetzner CPX22 (2 vCPU, 3,7 Go de RAM), partagé avec six autres projets personnels.
Ce qui suit est honnête sur ce qui est en place — pas de cluster simulé, pas de haute
disponibilité qui n'existe pas.
Le chemin d'une requête
{FLOW.map((step, i) => (
{i + 1}
{step.title}
{step.detail}
))}
Hors du chemin de trafic
Labos pédagogiques — jamais branchés sur le trafic de production.
{LABS.map((lab) => (
{lab.icon}
{lab.title}
{lab.detail}
))}
État réel
{STATE.map(([name, status], i) => (
{name}
{status}
))}
SSH public encore ouvert (choix explicite, pas encore restreint au VPN). Pas de
virtualisation imbriquée sur ce VPS. Alertes Prometheus qui se déclenchent mais ne sont
pas encore routées par notification. Détail complet dans le README du dépôt.
Code et historique de commits versionnés sur Forgejo.
);
}