Démarrage rapide¶
Installez Repod et uploadez votre premier paquet en moins de 10 minutes.
Prérequis¶
- Docker 24+
- Docker Compose plugin v2
- Linux ou macOS (Windows : utiliser WSL2)
- 2 Go de RAM minimum (ClamAV charge ~800 Mo de signatures au démarrage)
Étape 1 — Récupérer et configurer le projet¶
git clone https://github.com/getautoflow/repod
cd repod
cp .env.example .env
cp backend.env.example backend.env
.env contrôle Docker Compose (ports, URLs publiques, POSTGRES_PASSWORD).
backend.env contrôle le backend FastAPI (secrets, connexion à la base de données).
Ouvrir backend.env et définir les secrets requis — générer chacun avec
openssl rand -hex 32 :
DATABASE_URL=postgresql://repod:CHANGE_MOI@db:5432/repod
JWT_SECRET_KEY=votre-secret-hex-64-caracteres
SETTINGS_ENCRYPTION_KEY=un-autre-secret-hex-64-caracteres
WEBHOOK_SECRET=un-autre-secret-hex-64-caracteres
Si vous changez POSTGRES_PASSWORD dans .env, mettez à jour le mot de passe
dans DATABASE_URL pour qu'il corresponde — les deux fichiers alimentent le même
conteneur db (PostgreSQL 16).
Aucun compte admin n'est créé à ce stade — vous le créerez via l'assistant de configuration à l'étape 4, lors du premier accès à l'interface web.
Pré-provisionner un admin (optionnel, déploiements automatisés)
Si vous préférez ne pas utiliser l'assistant de configuration (déploiements scriptés/CI), vous pouvez pré-créer le premier compte admin en définissant :
Générer le hash bcrypt avec :
docker run --rm python:3.12-slim python -c \
"from passlib.hash import bcrypt; print(bcrypt.hash('MonMotDePasse1!'))"
Échapper les $ dans les fichiers .env
Les hashs bcrypt commencent par $2b$. Dans tout fichier *.env lu par
Docker Compose, chaque $ doit être doublé en $$ pour éviter
l'interpolation de variables. Si ADMIN_PASSWORD_HASH est absent, vide
ou n'est pas un hash bcrypt valide, aucun admin n'est créé et l'assistant
de configuration reste disponible — c'est le comportement sûr par défaut.
Protéger l'assistant de configuration (optionnel)
Entre le démarrage du conteneur et la création du premier admin, quiconque
peut atteindre le backend sur le réseau peut appeler POST /api/v1/setup.
Pour fermer cette fenêtre, définissez :
Si défini, POST /api/v1/setup exige un header X-Setup-Token
correspondant (voir étape 4). GET /api/v1/setup/status reste public dans
tous les cas.
Étape 2 — Choisir vos formats de paquets (REPO_FORMAT)¶
Repod est un backend unique capable de servir des paquets .deb, .rpm et
Alpine .apk. La variable d'environnement REPO_FORMAT (définie sur le
service backend dans docker-compose.yaml) contrôle les formats actifs :
REPO_FORMAT |
Formats servis | Outillage de dépôt |
|---|---|---|
apt (par défaut) |
.deb |
reprepro |
rpm |
.rpm |
createrepo_c |
apk |
.apk |
apk index |
both |
.deb + .rpm |
reprepro + createrepo_c |
all |
.deb + .rpm + .apk |
reprepro + createrepo_c + apk index |
Le docker-compose.yaml fourni est configuré avec REPO_FORMAT: all et démarre
deux conteneurs Nginx de dépôt (depot-apt pour .deb/.apk, depot-rpm pour
.rpm), plus un backend et un frontend. Si vous n'avez besoin que d'un seul
format, modifiez REPO_FORMAT et retirez le service de dépôt inutilisé de
docker-compose.yaml (ou laissez-le tourner — il est inoffensif, juste inutilisé).
Pile RPM autonome
docker-compose.rpm.yml est une pile séparée et autonome, avec sa propre
base PostgreSQL, son propre réseau et ses propres noms de conteneurs,
préconfigurée avec REPO_FORMAT=rpm. Démarrez-la avec
docker compose -f docker-compose.rpm.yml up -d — voir
Déploiement en production pour savoir quand l'utiliser.
Étape 3 — Démarrer la pile¶
Par défaut (REPO_FORMAT=all), cinq conteneurs démarrent :
| Conteneur | Rôle | Port par défaut |
|---|---|---|
repod-db |
PostgreSQL 16 — base de données applicative | (interne) |
depot-apt |
Nginx — sert les dépôts .deb (APT) et .apk (Alpine) |
:80 |
depot-rpm |
Nginx — sert les dépôts .rpm (YUM/DNF/Zypper) |
:8080 |
backend-api |
FastAPI — API REST + pipeline de sécurité | :8000 |
frontend-ui |
React — interface web | :3003 |
Suivre les logs de démarrage :
Attendre :
Le premier démarrage est plus lent
ClamAV charge sa base de signatures (~800 Mo) au premier démarrage. Cela
prend 20 à 60 secondes selon la vitesse du disque. Les démarrages suivants
sont plus rapides car la base est mise en cache dans le volume
repos/clamav-db/. PostgreSQL effectue également sa propre initialisation
au premier démarrage dans le volume postgres_data.
Étape 4 — Créer le compte admin¶
Si vous avez pré-provisionné ADMIN_USERNAME/ADMIN_PASSWORD_HASH à l'étape 1,
passez directement à l'étape 5 et connectez-vous
avec ces identifiants.
Sinon, exécutez l'assistant de configuration une seule fois — il crée le premier compte admin et retourne un JWT prêt à l'emploi :
curl -X POST http://localhost:8000/api/v1/setup/ \
-H "Content-Type: application/json" \
-d '{"admin_username":"admin","admin_password":"VotreMotDePasse1!"}'
Si SETUP_TOKEN est défini à l'étape 1, ajoutez le header :
POST /api/v1/setup retourne 409 si un admin existe déjà — l'assistant ne
peut être exécuté qu'une seule fois.
Étape 5 — Ouvrir l'interface¶
Aller sur http://localhost:3003.
Se connecter avec l'identifiant/mot de passe que vous venez de créer.
Changez le mot de passe immédiatement s'il s'agissait d'un mot de passe temporaire
Aller dans Compte → Changer le mot de passe dès la première connexion.
Étape 6 — Générer une clé de signature GPG¶
Les index de dépôt doivent être signés GPG. Sans clé de signature, les paquets ne peuvent pas être publiés (APT/RPM) ni signés (APK).
- Ouvrir Paramètres → GPG
- Cliquer sur Générer une clé
- Copier l'empreinte de la clé publique — vous en aurez besoin pour configurer les machines clientes
Aucun terminal interactif requis
La génération de clé utilise --pinentry-mode loopback. La clé GPG est
stockée dans le volume partagé /repos/gnupg et ne quitte jamais le serveur.
Étape 7 — Initialiser les distributions¶
Toutes les distributions pour les formats activés par REPO_FORMAT sont
initialisées automatiquement au premier démarrage par
auto_init_distributions(). Aucune action manuelle n'est requise.
Pour ré-initialiser après une corruption de configuration :
TOKEN=$(curl -s -X POST http://localhost:8000/api/v1/auth/token \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"VotreMotDePasse"}' \
| jq -r .access_token)
curl -X POST http://localhost:8000/api/v1/distributions/init \
-H "Authorization: Bearer $TOKEN"
Voir Distributions supportées ci-dessous pour la liste complète.
Étape 8 — Uploader votre premier paquet¶
- Aller dans Upload dans la barre latérale
- Glisser-déposer votre fichier
.deb,.rpmou.apk - Choisir une distribution (ex.
jammy,almalinux9,alpine3.20) - Cliquer Upload
Le pipeline s'exécute en temps réel :
# Authentification
TOKEN=$(curl -s -X POST http://localhost:8000/api/v1/auth/token \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"VotreMotDePasse"}' \
| jq -r .access_token)
# Upload d'un .deb (réponse JSON standard)
curl -X POST http://localhost:8000/api/v1/upload/ \
-H "Authorization: Bearer $TOKEN" \
-F "file=@monpaquet_1.0.0_amd64.deb" \
-F "distribution=jammy"
# Upload (Server-Sent Events en streaming — même endpoint pour tous les formats)
curl -X POST http://localhost:8000/api/v1/upload/stream \
-H "Authorization: Bearer $TOKEN" \
-F "[email protected]_64.rpm" \
-F "distribution=almalinux9"
File de revue CVE
Si l'analyse CVE détecte des vulnérabilités critiques correspondant à votre
politique, le statut du paquet devient pending_review. Il est stocké mais
non publié jusqu'à ce qu'un admin l'approuve dans Sécurité → File de revue.
Étape 9 — Configurer une machine cliente¶
# 1. Importer la clé GPG publique du dépôt
curl -fsSL http://VOTRE_HOTE:80/repos/gpg.key \
| gpg --dearmor \
| sudo tee /etc/apt/trusted.gpg.d/repod.gpg > /dev/null
# 2. Ajouter la source APT
echo "deb http://VOTRE_HOTE:80/repos jammy main" \
| sudo tee /etc/apt/sources.list.d/repod.list
# 3. Mettre à jour et installer
sudo apt update
sudo apt install monpaquet
# 1. Importer la clé GPG publique
sudo rpm --import http://VOTRE_HOTE:8080/repos/gpg.key
# 2. Créer le fichier de dépôt
sudo tee /etc/yum.repos.d/repod.repo << 'EOF'
[repod]
name=Repod Private Repository
baseurl=http://VOTRE_HOTE:8080/repos/almalinux9/x86_64/
enabled=1
gpgcheck=1
gpgkey=http://VOTRE_HOTE:8080/repos/gpg.key
EOF
# 3. Installer
sudo dnf install monpaquet
# 1. Importer la clé publique GPG/abuild
curl -fsSL http://VOTRE_HOTE:80/apk/repod.rsa.pub \
-o /etc/apk/keys/repod.rsa.pub
# 2. Ajouter le dépôt
echo "http://VOTRE_HOTE:80/apk/alpine3.20/main" \
| sudo tee -a /etc/apk/repositories
# 3. Mettre à jour et installer
sudo apk update
sudo apk add monpaquet
Remplacer VOTRE_HOTE par le nom d'hôte ou l'IP de la machine exécutant Repod,
et le port par celui mappé à depot-apt (:80 par défaut) ou depot-rpm
(:8080 par défaut).
Guide complet de configuration client →
Distributions supportées¶
| Codename | Distribution |
|---|---|
jammy |
Ubuntu 22.04 LTS |
noble |
Ubuntu 24.04 LTS |
focal |
Ubuntu 20.04 LTS |
bookworm |
Debian 12 |
| Codename | Distribution |
|---|---|
almalinux8 |
AlmaLinux 8 |
almalinux9 |
AlmaLinux 9 |
rocky8 |
Rocky Linux 8 |
rocky9 |
Rocky Linux 9 |
centos-stream9 |
CentOS Stream 9 |
oraclelinux8 |
Oracle Linux 8 |
fedora |
Fedora (dernière version) |
opensuse-leap-15.6 |
openSUSE Leap 15.6 |
opensuse-tumbleweed |
openSUSE Tumbleweed |
| Codename | Distribution |
|---|---|
alpine3.18 |
Alpine Linux 3.18 |
alpine3.19 |
Alpine Linux 3.19 |
alpine3.20 |
Alpine Linux 3.20 |
alpine3.21 |
Alpine Linux 3.21 |
Étapes suivantes¶
-
Comprendre le pipeline de validation en 6 étapes par lequel passe chaque paquet.
-
Exposer Repod en HTTPS avec Nginx, Traefik ou Caddy.
-
Publier des paquets automatiquement depuis GitHub Actions ou GitLab CI.
-
Checklist complète de production avec règles de firewall, sauvegardes et durcissement.