Auto-héberger le serveur de synchronisation

Le serveur est une petite pile FastAPI + Postgres + Caddy. N'importe quel VPS à 4 €/mois suffit ; il ne fait que déplacer du chiffré, donc 2 vCPU / 4 Go sont généreux. Le disque est la seule ressource qui grandit vraiment : comptez environ 1 Go par utilisateur intensif (PDF chiffrés et, là où c'est activé, fichiers du projet ; les sorties d'expériences restent locales, hormis ce que les runs à distance renvoient, plafonné à 100 Mo par fichier).

L'auto-hébergement est optionnel : pendant la bêta, vous pouvez simplement utiliser le serveur hébergé https://sync-dev.tramea.org (l'inscription est protégée par votre code d'invitation).

Déployer en cinq étapes

# 1. un VPS (Ubuntu 24.04) + un enregistrement DNS A : sync.yourdomain.org → IP du VPS
# 2. sur le VPS
apt update && apt install -y docker.io docker-compose-v2 ufw
ufw allow 22 && ufw allow 80 && ufw allow 443 && ufw --force enable

# 3. copier le répertoire server/, puis configurer
cp .env.example .env
#   ROS_SERVER_SECRET=$(openssl rand -base64 48)
#   POSTGRES_PASSWORD=$(openssl rand -hex 24)
#   SERVER_DOMAIN=sync.yourdomain.org
#   ROS_SERVER_INVITE_CODE=…        # optionnel : inscription sur invitation

# 4. lancer — Caddy obtient un certificat Let's Encrypt automatiquement
docker compose up -d --build

# 5. vérifier
curl https://sync.yourdomain.org/v1/health
Un vrai certificat est requis pour l'application mobile — elle n'acceptera pas de TLS auto-signé. Nom d'hôte public + Caddy = automatique.

Inscription sur invitation

Définissez ROS_SERVER_INVITE_CODE dans .env pour exiger un code d'invitation à l'inscription — remettez le code aux personnes que vous invitez. Laissez-le vide pour une inscription ouverte.

Optionnel : relais IA et IA locale au labo

Les deux sont désactivés tant que vous ne les configurez pas ; la synchronisation ne dépend d'aucun des deux.

  • Relais IA hébergé — pour proposer à vos utilisateurs le fournisseur d'assistant « crédits de l'offre », définissez ROS_SERVER_AI_KEY (et, en option, ROS_SERVER_AI_PROVIDER / ROS_SERVER_AI_MODEL ; par défaut, Anthropic avec un modèle de classe Haiku) dans .env. Les questions sont comptabilisées par compte et par mois, transmises au fournisseur, et jamais stockées ni journalisées — c'est l'unique trajet en clair du serveur, et les utilisateurs doivent le sélectionner explicitement. Sans la clé, le point d'accès répond 503 et le fournisseur n'apparaît tout simplement pas dans les applications.
  • IA locale au labo — branchez les membres d'un lab sur un modèle compatible OpenAI hébergé sur le matériel du labo (Ollama, vLLM, …) : org-ai ORG_ID http://ai.lab.local:11434/v1 --model mistral-small (voir Administration ci-dessous). Les applications des membres le détectent comme fournisseur « Serveur du labo (modèle local) » et le prennent par défaut ; les requêtes ne quittent alors jamais le réseau du labo. Passez un point d'accès vide pour le déconnecter.

Administration

Une petite CLI d'administration tourne dans le conteneur de l'application :

docker compose exec app python -m ros_server.admin stats
docker compose exec app python -m ros_server.admin accounts
docker compose exec app python -m ros_server.admin backup -o backup.tar.gz
docker compose exec app python -m ros_server.admin set-plan you@lab.org pro
docker compose exec app python -m ros_server.admin create-org my-lab --seats 20
docker compose exec app python -m ros_server.admin org-add <org-id> member@lab.org
docker compose exec app python -m ros_server.admin org-ai <org-id> http://ai.lab.local:11434/v1
docker compose exec app python -m ros_server.admin team-create <org-id> "Équipe Mémoire"
docker compose exec app python -m ros_server.admin team-add <team-id> lead@labo.fr --lead
docker compose exec app python -m ros_server.admin set-org-role pi@labo.fr admin
docker compose exec app python -m ros_server.admin org-remove member@lab.org --revoke

La dernière est le parcours de départ : elle retire un membre de l'organisation, et avec --revoke le retire aussi de chaque espace et équipe appartenant à l'organisation — le serveur refuse ses récupérations ultérieures. Ses espaces personnels et ses données locales restent intacts.

Tout ce qu'elle touche est de la métadonnée — offres, sièges, compteurs d'usage, sauvegardes. Elle ne peut lire le contenu de personne ; il n'existe aucune clé pour le lire.

Exploitation

  • Sauvegardes : docker compose exec db pg_dump -U ros ros > backup.sql chaque semaine, plus le volume des blobs. Même la perte totale du serveur est surmontable — chaque appareil détient les données en clair.
  • Mises à jour : copiez le nouveau server/, puis docker compose up -d --build.
  • Comptes : les utilisateurs se gèrent eux-mêmes — changement de phrase secrète, récupération, révocation d'appareil et suppression de compte se font en autonomie dans l'application.