Variables d'environnement¶
Toute la configuration runtime est injectée via des variables d'environnement.
Le backend les lit au démarrage depuis le fichier backend.env (chargé par
Docker Compose via env_file), plus quelques-unes définies directement dans
docker-compose.yaml (chemins, REPO_FORMAT, DATABASE_URL). Le frontend
lit un petit sous-ensemble intégré au moment du build.
Échappement des variables Docker Compose
Dans tout fichier chargé avec env_file:, les caractères $ littéraux
doivent être échappés en $$. Cela concerne les hashs bcrypt
($$2b$$12$$...) et toute valeur contenant un signe dollar.
Variables backend¶
Base de données¶
| Variable | Type | Défaut | Obligatoire | Description |
|---|---|---|---|---|
DATABASE_URL |
string |
— | Oui | Chaîne de connexion PostgreSQL : postgresql://repod:<mot-de-passe>@db:5432/repod. db/engine.py lève une RuntimeError au démarrage si absente. Toutes les données relationnelles (utilisateurs, index des manifestes, inventaire, jobs d'installation, recherche de paquets, ssh_known_hosts) y sont stockées, gérées via SQLAlchemy Core + Alembic. |
Format de dépôt¶
| Variable | Type | Défaut | Description |
|---|---|---|---|
REPO_FORMAT |
string |
apt |
Lu une seule fois au démarrage par format_router.py. Une valeur parmi apt, rpm, apk, both (apt+rpm), ou all (apt+rpm+apk). Toute autre valeur est rejetée (avertissement journalisé, repli sur apt). |
Authentification et sécurité¶
| Variable | Type | Défaut | Obligatoire | Description |
|---|---|---|---|---|
JWT_SECRET_KEY |
string |
— | Oui | Clé de signature HMAC-SHA256 pour les tokens JWT. Générer avec openssl rand -hex 32. Minimum 32 caractères. L'application refuse de démarrer en production si cette valeur est vide ou correspond à un défaut connu comme faible. |
JWT_EXPIRE_MINUTES |
integer |
60 |
Non | Durée de vie du token en minutes. Les tokens expirent et doivent être réémis après cette période. Les tokens API ont leur propre expiration définie à la création. |
SETTINGS_ENCRYPTION_KEY |
string |
repli sur JWT_SECRET_KEY |
Non (recommandé) | Clé dédiée utilisée pour chiffrer les secrets stockés dans settings.json (mot de passe SMTP/LDAP, client_secret OIDC). Générer avec openssl rand -hex 32. La garder distincte de JWT_SECRET_KEY permet de faire tourner la clé JWT sans casser le déchiffrement de ces secrets stockés. |
ADMIN_USERNAME |
string |
— | Non | Nom d'utilisateur d'un compte admin à pré-provisionner au démarrage. N'a d'effet qu'associé à un ADMIN_PASSWORD_HASH valide. Si absent, aucun admin n'est créé et l'assistant de configuration au premier lancement (/api/v1/setup) est utilisé à la place. |
ADMIN_PASSWORD_HASH |
string |
— | Non | Hash bcrypt du mot de passe admin (doit commencer par $2a$, $2b$, ou $2y$). Générer avec python -c "from passlib.hash import bcrypt; print(bcrypt.hash('password'))". Échapper chaque $ en $$ dans le fichier env. Si vide ou non valide comme hash bcrypt, aucune ligne admin n'est créée — l'assistant de configuration reste disponible (défaut sûr). |
SETUP_TOKEN |
string |
— | Non | Si défini, POST /api/v1/setup exige un header X-Setup-Token correspondant (comparé avec hmac.compare_digest), fermant la fenêtre de course entre le démarrage du conteneur et la création du premier admin. GET /api/v1/setup/status n'est pas affecté. |
WEBHOOK_SECRET |
string |
— | Oui (production) | Secret HMAC utilisé pour vérifier les signatures sur /webhooks/github et /webhooks/kev, et validé par le garde-fou SSRF pour les webhooks de notification sortants. Générer avec openssl rand -hex 32. L'application refuse de démarrer en production si cette valeur est vide ou correspond à un placeholder par défaut connu. |
REPOD_LICENSE_VENDOR_KEY |
string |
— | Oui (production, Enterprise) | Secret HMAC-SHA256 pour signer/vérifier les clés de licence Enterprise. L'application refuse de démarrer en production si cette valeur est le défaut. |
TRUSTED_PROXIES |
string |
127.0.0.1,172.16.0.0/12,192.168.0.0/16 |
Non | Liste d'adresses IP ou de plages CIDR séparées par des virgules, de confiance pour définir X-Forwarded-For. Utilisé par le limiteur de débit (slowapi) pour extraire l'IP client réelle derrière un reverse proxy. |
CORS_ORIGINS |
string |
http://localhost:3003 |
Non | Liste d'origines CORS autorisées séparées par des virgules. Inclure l'URL de votre frontend en production (ex. https://repod.example.com). |
Chemins de stockage¶
Ces variables contrôlent où Repod stocke ses données. Les valeurs par défaut correspondent aux montages de volumes Docker Compose et ne devraient pas être modifiées sans savoir précisément ce que vous faites.
| Variable | Type | Défaut | Description |
|---|---|---|---|
POOL_DIR |
path |
/repos/pool |
Stockage canonique des paquets — tous les binaires .deb/.rpm validés y atterrissent à l'upload. Servi en lecture seule par les conteneurs Nginx de dépôt. |
MANIFEST_DIR |
path |
/repos/manifests |
Répertoire pour les manifestes JSON par paquet et le catalogue central index.json. |
STAGING_INCOMING |
path |
/repos/staging/incoming |
Zone d'atterrissage temporaire pour les fichiers uploadés avant validation. Jamais servi en HTTP. |
STAGING_QUARANTINE |
path |
/repos/staging/quarantine |
Destination des fichiers ayant échoué à la validation ou bloqués par la politique CVE. |
AUDIT_DIR |
path |
/repos/audit |
Fichiers de journal d'audit JSONL en écriture seule ajout, un par jour (YYYY-MM-DD.jsonl). |
INDEX_PATH |
path |
/repos/manifests/index.json |
Chemin du fichier JSON d'index central des paquets (écritures atomiques via tempfile + os.replace()). |
INDEX_DIR |
path |
/repos/package-index |
Répertoire de travail pour l'indexation de synchronisation/import. Les données de recherche full-text du package-index vivent elles-mêmes dans PostgreSQL. |
IMPORTS_DIR |
path |
/repos/imports |
Répertoire de travail pour les paquets importés depuis des sources externes (sync/mirror). |
SETTINGS_PATH |
path |
/repos/settings.json |
Fichier de paramètres persistants (config LDAP, webhook, politique CVE, rétention, mirror, backup, etc.). |
SECURITY_DIR |
path |
/repos/security |
Répertoire pour les décisions CVE, le cache CISA KEV, et le cache EPSS. |
GNUPG_HOME |
path |
/repos/gnupg |
Répertoire du trousseau GPG partagé entre le backend et les conteneurs de dépôt (depot-apt, depot-rpm). |
NGINX_LOGS_DIR |
path |
/repos/logs |
Répertoire où les conteneurs Nginx de dépôt écrivent access.log. Analysé par l'endpoint de statistiques de téléchargement. |
CLAMAV_DB_DIR |
path |
/var/lib/clamav |
Répertoire de la base de signatures ClamAV. Peuplé par freshclam au démarrage et mis à jour quotidiennement. |
GRYPE_DB_CACHE_DIR |
path |
/repos/grype-db |
Cache de la base de vulnérabilités Grype. Mis à jour automatiquement lorsqu'obsolète (> 24 h). |
SSH_KEY_PATH |
path |
/home/appuser/.ssh/id_ed25519 |
Clé privée Ed25519 utilisée par ssh_scanner.py pour le scan d'inventaire via SSH (Enterprise). |
SBOM_DIR |
path |
/repos/sboms |
SBOM CycloneDX stockés, capturés au moment du scan (services/component_sbom.py), utilisés pour le re-matching CVE sans rouvrir le fichier de paquet d'origine. |
MANIFEST_CACHE_TTL |
integer |
30 |
TTL du cache en mémoire des manifestes, en secondes (services/manifest.py). |
Registre OCI (Zot)¶
Utilisé lorsque l'overlay docker-compose.oci.yml est déployé.
| Variable | Type | Défaut | Description |
|---|---|---|---|
ZOT_URL |
string |
http://depot-oci:5000 |
URL interne du conteneur du registre OCI Zot. Réservé aux appels admin/lecture du backend — docker push/pull ne transitent jamais par le backend. |
OCI_SIGNING_KEY_PATH |
path |
/repos/oci/keys/private.pem |
Clé privée RSA utilisée pour signer les tokens Bearer OCI (RS256). Générer avec scripts/gen-oci-signing-keys.sh. |
OCI_TOKEN_ISSUER |
string |
repod-oci-registry |
Claim iss sur les tokens OCI émis. Doit correspondre à la valeur service configurée dans Zot. |
OCI_TOKEN_TTL_SECONDS |
integer |
300 |
Durée de vie, en secondes, d'un token Bearer OCI émis. |
TRIVY_SERVER_URL |
string |
http://depot-trivy:4954 |
URL du sidecar serveur Trivy utilisé par la fonctionnalité de vérification croisée dual-scan (services/dual_scan.py). SaaS uniquement — défini uniquement par docker-compose.saas.yml, absent en EE on-premise/CE. |
Cache amont (proxy pull-through)¶
Utilisé lorsque le service depot-cache est déployé.
| Variable | Type | Défaut | Description |
|---|---|---|---|
UPSTREAM_CACHE_DATA_DIR |
path |
/repos/upstream-cache/data |
Fichiers de paquets/index amont mis en cache. Accessible en écriture par le backend, afin qu'une purge puisse supprimer les données en cache. Monté au même chemin absolu dans depot-cache. |
UPSTREAM_CACHE_CONF_DIR |
path |
/repos/upstream-cache/conf |
Fragments de configuration Nginx générés par cible, surveillés par scripts/cache-reload-watcher.sh dans depot-cache pour déclencher un reload. |
Intégration license server & HA (Redis)¶
| Variable | Type | Défaut | Obligatoire | Description |
|---|---|---|---|---|
LICENSE_SERVER_INTERNAL_TOKEN |
string |
— | Oui (DEPLOYMENT_MODE=saas) |
Secret partagé vérifié sur GET /internal/tenants, appelé par l'outil vendeur autonome license-server/ pour son panneau de statut SaaS en lecture seule. Doit correspondre à la même variable dans license-server/.env. |
REDIS_URL |
string |
— | Non | redis://host:6379/0. Alimente le cache de réponses de services/cache.py. Absent signifie un cache en mémoire (le défaut partout aujourd'hui — le service Compose redis:7-alpine est opt-in via le profil ha-active-active). Fail-soft : une erreur de connexion au démarrage se replie sur le mode en mémoire. |
JOB_STATE_BACKEND |
string |
local |
Non | local ou redis. Sélectionne le backend d'état pour scan_manager/install_manager/mirror_manager/sync_manager (services/job_state_backend.py), le backend pub/sub de sse_bus (services/sse_redis_bus.py), et le backend pub/sub + historique borné de logging_config (services/logs_redis_bus.py). redis exige que JOB_STATE_REDIS_URL/REDIS_URL soit joignable au démarrage, sinon chaque composant se replie indépendamment sur local (journalisé en ERROR ; visible par flux sur GET /health → checks.info.ha.job_state_backend). |
JOB_STATE_REDIS_URL |
string |
repli sur REDIS_URL |
Non | Surcharge optionnelle de REDIS_URL spécifiquement pour JOB_STATE_BACKEND=redis, pour les opérateurs souhaitant faire transiter le trafic de coordination des jobs sur une instance/base Redis distincte du cache de réponses. |
Chemins mode APT¶
Utilisés lorsque REPO_FORMAT vaut apt, both, ou all.
| Variable | Type | Défaut | Description |
|---|---|---|---|
REPREPRO_BASE |
path |
/repos |
Répertoire de base passé à reprepro -b. Reprepro attend conf/, db/, dists/, et pool/ sous ce chemin. Également utilisé par services/reprepro.py:add_package() pour invoquer reprepro includedeb directement (sans wrapper shell). |
DISTS_DIR |
path |
/repos/dists |
Arborescence de distribution APT gérée par reprepro. Servie par depot-apt. |
CONF_DIR |
path |
/repos/conf |
Répertoire de configuration de reprepro. Contient le fichier distributions généré à l'initialisation. |
Chemins mode RPM¶
Utilisés lorsque REPO_FORMAT vaut rpm, both, ou all.
| Variable | Type | Défaut | Description |
|---|---|---|---|
ADD_RPM_SCRIPT |
path |
/scripts/add-rpm.sh |
Chemin du script shell qui copie le .rpm dans le répertoire de distribution et invoque createrepo_c --update. |
REPO_BASE |
path |
/repos/rpm |
Répertoire de base pour les arborescences de distribution RPM. Chaque couple distribution/architecture obtient un sous-répertoire <codename>/<arch>/ sous ce chemin, servi par depot-rpm. |
Chemins mode APK¶
Utilisés lorsque REPO_FORMAT vaut apk ou all.
| Variable | Type | Défaut | Description |
|---|---|---|---|
APK_REPO_BASE |
path |
/repos/apk |
Répertoire de base pour les dépôts Alpine. Chaque distribution obtient une arborescence <codename>/main/<arch>/APKINDEX.tar.gz, servie par depot-apt sous /apk/. |
Intégrations externes¶
| Variable | Type | Défaut | Description |
|---|---|---|---|
LDAP_URL |
string |
— | URL du serveur LDAP (ex. ldap://dc.example.com:389 ou ldaps://dc.example.com:636). Laisser vide pour désactiver l'authentification LDAP. Configuré via Paramètres → LDAP, stocké dans settings.json — listé ici à titre de référence uniquement. |
SMTP_* |
string |
— | Hôte/port/utilisateur/mot de passe/adresse d'expédition SMTP pour les notifications par email (alertes SLA). Configuré via Paramètres → Email, stocké chiffré dans settings.json. |
WEBHOOK_URL |
string |
— | URL vers laquelle envoyer (POST) des payloads JSON d'événements lors d'événements de sécurité (blocages CVE, dépassements de SLA, résultats de sync/mirror). Configuré via Paramètres → Notifications, validé par le garde-fou SSRF avant chaque requête. |
Réseau / proxy sortant¶
| Variable | Type | Défaut | Description |
|---|---|---|---|
HTTP_PROXY / HTTPS_PROXY |
string |
— | Variables d'environnement de proxy standard, honorées automatiquement par le client HTTP Python, Grype, et le CLI Docker/skopeo (utilisé pour l'import OCI) — à définir dans backend.env si le serveur n'a pas d'accès internet direct. |
NO_PROXY |
string |
— | Liste d'hôtes à joindre directement, en contournant le proxy, séparés par des virgules (typiquement les serveurs LDAP/SMTP internes, votre license-server si auto-hébergé). |
ClamAV nécessite sa propre configuration
freshclam (mises à jour des signatures ClamAV) ne lit pas
HTTP_PROXY/HTTPS_PROXY — il requiert une directive de proxy dans son
propre fichier de configuration. Voir
Configuration du proxy (anglais)
pour la liste complète des dépendances externes et un exemple travaillé
avec Squid.
Comportement runtime¶
| Variable | Type | Défaut | Description |
|---|---|---|---|
ENV |
string |
development |
Définir sur production pour activer le mode strict (rejette les JWT_SECRET_KEY/WEBHOOK_SECRET/REPOD_LICENSE_VENDOR_KEY faibles, désactive Swagger UI). |
APP_VERSION |
string |
dev |
Chaîne de version retournée par l'endpoint /health. À définir sur un tag semver dans les images de production. |
Variables frontend (build-time)¶
Build-time uniquement
Les variables d'environnement React préfixées par REACT_APP_ sont
intégrées dans le bundle JavaScript au moment du docker build. Les
modifier après la construction de l'image n'a aucun effet. Passez-les
comme build.args de Docker Compose.
| Variable | Défaut | Description |
|---|---|---|
REACT_APP_API_URL |
(vide) | URL de base de l'API backend. Doit rester vide en déploiement normal — le frontend utilise alors des URLs relatives (/api/v1/...) et s'appuie sur son reverse proxy Nginx. La définir intègre une URL absolue dans le bundle et casse l'accès cross-host. |
REACT_APP_REPO_URL |
http://localhost |
URL de base du serveur de dépôt APT/APK, affichée aux utilisateurs dans les instructions de configuration client. |
REACT_APP_RPM_REPO_URL |
http://localhost:8080 |
URL de base du serveur de dépôt RPM, affichée aux utilisateurs dans les instructions de configuration client. |
Variables Docker Compose (fichier .env)¶
Ces variables sont interpolées par Docker Compose lui-même avant le
lancement des conteneurs. Placez-les dans un fichier .env à côté de
docker-compose.yaml (cp .env.example .env).
| Variable | Défaut | Description |
|---|---|---|
BIND_HOST |
0.0.0.0 |
Interface hôte sur laquelle publier tous les ports. Définir sur 127.0.0.1 en production quand un reverse proxy gère le trafic externe. |
BACKEND_PORT |
8000 |
Port hôte mappé vers le conteneur backend-api. |
FRONTEND_PORT |
3003 |
Port hôte mappé vers le conteneur frontend-ui. |
APT_PORT |
80 |
Port hôte mappé vers depot-apt (sert .deb + .apk). |
RPM_REPO_PORT |
8080 |
Port hôte mappé vers depot-rpm (sert .rpm). |
POSTGRES_PASSWORD |
repod_dev_password |
Mot de passe de l'utilisateur PostgreSQL repod — doit correspondre au mot de passe dans DATABASE_URL (backend.env). À changer en production. |
APT_TLS_PORT |
8085 |
Utilisé par docker-compose.tls.yml ; depot-apt se replie sur ce port lorsque nginx-proxy occupe le port 80 pour la redirection HTTPS. |
REACT_APP_API_URL |
(vide) | Passé comme argument de build à l'image frontend — garder vide. |
REACT_APP_REPO_URL |
http://localhost |
Passé comme argument de build à l'image frontend. |
REACT_APP_RPM_REPO_URL |
http://localhost:8080 |
Passé comme argument de build à l'image frontend. |
Exemple : backend.env de production¶
# ── Base de données ──────────────────────────────────────────────────────────
DATABASE_URL=postgresql://repod:CHANGE_ME@db:5432/repod
# ── Format de dépôt ──────────────────────────────────────────────────────────
REPO_FORMAT=all
# ── Sécurité ──────────────────────────────────────────────────────────────────
JWT_SECRET_KEY=a3f8c2e1d4b7a9f0e2c5d8b1a4f7e0c3d6b9a2f5e8c1d4b7a0f3e6c9d2b5a8f1
JWT_EXPIRE_MINUTES=60
SETTINGS_ENCRYPTION_KEY=7f1e4a9c2b8d5f0a3e6c9b2d5f8a1c4e7b0d3f6a9c2e5b8d1f4a7c0e3b6d9f2a
WEBHOOK_SECRET=9d2f5b8e1a4c7f0d3b6e9c2a5f8d1b4e7c0a3f6d9b2e5c8f1a4d7b0e3c6f9a2d
# Optionnel : pré-provisionner le premier admin (sinon, utiliser l'assistant
# de configuration, POST /api/v1/setup, au premier accès — recommandé)
#ADMIN_USERNAME=admin
#ADMIN_PASSWORD_HASH=$$2b$$12$$exampleHashHere...
# Optionnel : protéger POST /api/v1/setup avant la création du premier admin
#SETUP_TOKEN=4e7a0d3f6b9c2e5a8d1f4b7e0c3a6d9f2b5e8c1a4d7f0b3e6c9a2d5f8b1e4c7a
# ── Environnement ────────────────────────────────────────────────────────────
ENV=production
APP_VERSION=v1.2.0
# ── Reverse proxy ────────────────────────────────────────────────────────────
TRUSTED_PROXIES=127.0.0.1,10.0.0.0/8
CORS_ORIGINS=https://repod.example.com
LDAP, SMTP, l'URL de webhook, les sources de mirror, la rétention, et la
politique CVE sont configurés via Paramètres dans l'interface web et
stockés (chiffrés le cas échéant) dans settings.json — voir
Référence configuration
(anglais).