Spaces:
Sleeping
Déploiement institutionnel — Picarones
Ce guide cible les DSI de bibliothèques nationales et services d'archives qui souhaitent héberger Picarones sur leur propre infrastructure (intranet, derrière SSO, avec stockage centralisé) plutôt que sur HuggingFace Space public.
Pour le déploiement HuggingFace Space ou un usage local rapide, voir
how-to/install.md.
Pré-requis
Système
- Linux x86_64 ou ARM64 (Debian 12+, RHEL 9+, Ubuntu 22.04+ LTS, Rocky 9+).
- Python 3.11 ou 3.12 (3.13 informationnel).
- Tesseract OCR ≥ 5.3 (avec packs
fra,lat,engau minimum). - 3 GB RAM pour un worker FastAPI exécutant
max_in_flight=4documents en parallèle dans le ThreadPool duCorpusRunner(profil mémoire dominé par Pillow + jiwer + les modèles OCR locaux chargés une fois par instance). - 5 GB de disque pour l'application + 50 GB recommandés pour les uploads et la base SQLite des jobs.
Réseau
- Sortant : optionnel (HF Datasets / Gallica / HTR-United uniquement si vous activez les imports distants).
- Entrant : un seul port HTTP (défaut 7860) à exposer derrière votre reverse proxy (Nginx, Apache, Traefik).
Optionnel
- PostgreSQL 14+ (en remplacement de SQLite si vous montez en multi-instance — voir § Architecture cible).
- Reverse proxy SSO (Shibboleth, CAS, OIDC, OAuth2 proxy).
- Stack observabilité (Prometheus + Grafana, ou ELK/Loki).
Architecture cible
Mono-instance (recommandé pour < 10 utilisateurs simultanés)
[Utilisateur] → [Reverse proxy SSO] → [Picarones Docker] → [SQLite jobs.db]
↓
[Volume persistant uploads/]
↓
[Volume persistant reports/]
Configuration minimale, rétro-compatible avec le déploiement HuggingFace Space. Le reverse proxy ajoute l'authentification (SSO institutionnel) et la terminaison TLS.
Multi-instance (charge > 50 jobs/h)
[Utilisateur] → [Load balancer + SSO] → [Picarones × N]
↓
[PostgreSQL jobs (centralisé)]
↓
[Volume NFS uploads/ partagé]
Notes :
- PostgreSQL :
JobStoreutilise SQLite par défaut. Pour PostgreSQL, dériver une classePostgresJobStorequi implémente la même API (create_job,update_progress,get_job, etc.). À défaut, partager la BD SQLite via NFS ne fonctionne pas — le mode WAL exige un filesystem local. - Volume NFS pour
uploads/etreports/afin que tous les workers voient les mêmes fichiers. - Sticky sessions sur le LB pour SSE (les progress streams doivent rester sur le même worker).
Configuration
Toutes les variables sont documentées dans
.env.example. Les principales pour un
déploiement institutionnel :
# Sécurité (Sprints A4 + 24)
PICARONES_PUBLIC_MODE= # vide ou 0 = mode dev (autorise OCR cloud)
PICARONES_CSRF_REQUIRED=1 # OBLIGATOIRE derrière SSO
PICARONES_CSRF_SECRET="$(openssl rand -hex 32)"
# Restrictions
PICARONES_BROWSE_ROOTS="/var/lib/picarones/uploads:/data/corpus"
PICARONES_MAX_UPLOAD_MB=500
PICARONES_MAX_CONCURRENT_JOBS=8
PICARONES_RATE_LIMIT_PER_HOUR=0 # 0 = illimité (le SSO gère l'identité)
# Persistance
PICARONES_JOBS_DB=/var/lib/picarones/jobs.sqlite
# RGPD
PICARONES_UPLOAD_RETENTION_DAYS=7
PICARONES_LOG_IP_RETENTION_HOURS=24
Intégration SSO
Picarones n'implémente pas de mécanisme d'authentification
natif — l'authentification est déléguée à votre reverse proxy.
Pattern recommandé : header trusté X-Remote-User.
Nginx + Shibboleth (université, Renater)
location / {
auth_request /shibauthorizer;
proxy_set_header X-Remote-User $http_remote_user;
proxy_set_header X-Remote-Groups $http_remote_groups;
proxy_pass http://picarones-backend:7860;
# SSE long-polling
proxy_buffering off;
proxy_read_timeout 24h;
}
Apache + CAS (CRU, ESR français)
<Location />
AuthType CAS
Require valid-user
RequestHeader set X-Remote-User %{REMOTE_USER}s
ProxyPass http://localhost:7860/
ProxyPassReverse http://localhost:7860/
</Location>
Traefik + OIDC (déploiements modernes)
http:
middlewares:
oidc-auth:
forwardAuth:
address: "http://oauth2-proxy:4180/auth"
trustForwardHeader: true
authResponseHeaders:
- X-Auth-Request-User
- X-Auth-Request-Email
routers:
picarones:
rule: "Host(`picarones.institution.fr`)"
service: picarones
tls:
certResolver: letsencrypt
middlewares:
- oidc-auth
Sauvegarde et restauration
Composants à sauvegarder
| Élément | Chemin | Stratégie |
|---|---|---|
| BD jobs | /var/lib/picarones/jobs.sqlite* |
Snapshot quotidien (mode WAL : sauvegarder .sqlite, .sqlite-wal, .sqlite-shm ensemble) |
| Uploads | /var/lib/picarones/uploads/ |
Snapshot hebdomadaire, rétention 30 jours (cf. RGPD) |
| Rapports | /var/lib/picarones/reports/ |
Snapshot hebdomadaire, rétention illimitée (artefacts citables) |
| Historique longitudinal | /var/lib/picarones/history.sqlite |
Snapshot quotidien |
| Configuration | /etc/picarones/, .env |
Versionner dans le système de gestion de config (Ansible, Salt) |
Restauration
# Arrêt du service
systemctl stop picarones
# Restauration BD
cp backups/jobs.sqlite-2026-05-01.sqlite /var/lib/picarones/jobs.sqlite
# Restauration uploads
rsync -av backups/uploads-2026-05-01/ /var/lib/picarones/uploads/
# Redémarrage
systemctl start picarones
# Vérification : marquage des jobs orphelins
curl http://localhost:7860/api/status
Les jobs running au moment du snapshot sont automatiquement
marqués interrupted au redémarrage. Le tableau de
bord sera donc cohérent.
Migration de schéma BD
Picarones évolue sa BD via une stratégie append-only —
nouvelles colonnes ajoutées avec ALTER TABLE ADD COLUMN ... DEFAULT NULL. Aucune migration destructive entre versions
mineures.
Pour vérifier la compatibilité d'une BD existante avec une nouvelle version :
sqlite3 jobs.sqlite "PRAGMA table_info(jobs);" > current_schema.txt
# Comparer avec docs/schema/jobs.sqlite.X.Y.Z.sql versionné
Si une migration majeure est nécessaire (changement de moteur SQL,
structure incompatible), elle sera annoncée 2 versions mineures
avant et un script de migration sera fourni dans scripts/migrate/.
Observabilité
Logs structurés
Picarones logge en format texte simple par défaut. Pour ELK / Loki / Datadog, ajouter un wrapper JSON :
# /etc/picarones/logging.conf
[handler_json]
class = pythonjsonlogger.jsonlogger.JsonFormatter
format = %(asctime)s %(levelname)s %(name)s %(message)s
Variable d'env : PICARONES_LOG_FORMAT=json (à implémenter dans
un sprint ultérieur — actuellement les logs sont en plain text).
Métriques Prometheus (recommandé)
L'exposition Prometheus n'est pas livrée par défaut. Pour
l'ajouter, monter un conteneur sidecar prometheus_client_python
qui expose :
picarones_jobs_total{status="..."}picarones_jobs_duration_secondspicarones_uploads_size_bytes_totalpicarones_engine_invocations_total{engine="..."}
Voir docs/operations/observability.md.
Healthcheck
Un endpoint /health minimal répond en < 50 ms
sans toucher à la BD ni aux engines. Configurer le LB pour le
cibler avec un timeout court (5 s).
Sécurité réseau
Liste blanche réseau
Si vos engines cloud sont activés (PICARONES_PUBLIC_MODE non
défini), autoriser en sortie uniquement :
| Domaine | Usage |
|---|---|
api.openai.com |
OpenAI / GPT-4o |
api.anthropic.com |
Claude |
api.mistral.ai |
Mistral OCR + LLM |
vision.googleapis.com |
Google Vision |
*.cognitiveservices.azure.com |
Azure Doc Intelligence |
huggingface.co |
Imports HF Datasets (optionnel) |
gallica.bnf.fr |
Imports Gallica (optionnel) |
Politique de mots de passe
Les clés API LLM/OCR sont passées en variables d'environnement
uniquement (jamais sur le filesystem en clair). Voir SECURITY.md.
Mise à l'échelle
| Charge | Configuration |
|---|---|
| < 5 jobs/h, < 5 utilisateurs | Mono-instance, SQLite, 2 vCPU / 4 GB RAM |
| 5–50 jobs/h, < 20 utilisateurs | Mono-instance, SQLite, 4 vCPU / 8 GB RAM, max_in_flight=8 |
| > 50 jobs/h | Multi-instance derrière LB, PostgreSQL centralisé, NFS uploads |
| > 500 jobs/h | Considérer un orchestrateur de tâches dédié (Celery + Redis), hors scope Picarones |
Checklist déploiement
- Tesseract installé avec packs de langues nécessaires.
- Variables d'env configurées (mode dev/public, CSRF, browse roots).
- Volume persistant pour
uploads/,reports/, BD. - Reverse proxy SSO en place (CSRF activé !).
- Backup automatique configuré (cron quotidien minimum).
- Healthcheck
/healthconfiguré dans le LB. - TLS terminé au reverse proxy.
- Liste blanche réseau si engines cloud actifs.
- Rétention RGPD configurée
(cf.
data-retention-rgpd.md). - Audit RGAA externe planifié si prestation publique
(cf.
accessibility.md). - Issue tracking institutionnel (Mantis, JIRA, Redmine) synchronisé avec les issues GitHub si pertinent.
Aide et support
- Issues GitHub étiquetées
deployment: https://github.com/maribakulj/Picarones/issues?q=label%3Adeployment - Pour un support contractualisé (SLO renforcés, intégration spécifique), contractualiser une prestation séparément (modalités hors-projet, à définir au cas par cas).
Dernière mise à jour : 2 mai 2026.