5.7 KiB
5.7 KiB
| description |
|---|
| Déploiement de dynamic.alpinux.org — app Flask, Gunicorn, Apache reverse proxy, AlpID OIDC. |
Déploiement de dynamic.alpinux.org
Application Flask de quiz interactifs, partiellement publique et partiellement réservée aux membres AlpID.
!!! note "Pour qui ?" Procédure pour les mainteneurs avec accès SSH au serveur.
Architecture
Navigateur
│ HTTPS
▼
Apache (reverse proxy, SSL)
│ HTTP (port local dédié)
▼
Gunicorn (2 workers)
│
▼
Flask app (dynamic/)
│ │
▼ ▼
SQLite AlpID OIDC
(scores.db) (alpid.alpinux.org)
Installation (première fois)
1. Cloner le dépôt sur le serveur
ssh <user>@alpinux.org
git clone https://gitea.alpinux.org/alpinux.cedrica5l/alpinux.site.2026.git \
$APP_DIR
2. Créer l'environnement Python
cd $APP_DIR/dynamic
python3 -m venv venv
venv/bin/pip install -r requirements.txt gunicorn
3. Configurer les variables d'environnement
sudo mkdir /etc/dynamic-alpinux
sudo cp $APP_DIR/dynamic/.env.example /etc/dynamic-alpinux/config.env
sudo nano /etc/dynamic-alpinux/config.env
Remplissez les valeurs :
SECRET_KEY=<générer avec : python3 -c "import secrets; print(secrets.token_hex(32))">
ALPID_CLIENT_ID=<client-id-configuré-dans-keycloak>
ALPID_CLIENT_SECRET=<obtenir depuis la console Keycloak AlpID>
ALPID_DISCOVERY_URL=https://alpid.alpinux.org/realms/alpinux/.well-known/openid-configuration
DATABASE=<chemin vers le fichier scores.db>
sudo chmod 600 /etc/dynamic-alpinux/config.env
4. Créer les répertoires de données et de logs
sudo mkdir -p <répertoire données>
sudo mkdir -p <répertoire logs>
sudo chown <user>:<group> <répertoire données> <répertoire logs>
5. Configurer AlpID (Keycloak)
Dans la console d'administration Keycloak (https://alpid.alpinux.org) :
- Clients → Créer un client
- Client ID : le client ID choisi pour cette app
- Client authentication : activé (pour obtenir un
client_secret) - Valid redirect URIs :
https://dynamic.alpinux.org/auth/callback - Web origins :
https://dynamic.alpinux.org - Notez le Client secret dans l'onglet Credentials
6. Installer le service systemd
Les fichiers de configuration systemd et Apache sont conservés hors dépôt (infra/ local).
sudo cp infra/dynamic/dynamic.alpinux.org.service \
/etc/systemd/system/dynamic-alpinux.service
sudo systemctl daemon-reload
sudo systemctl enable --now dynamic-alpinux
sudo systemctl status dynamic-alpinux
7. Configurer Apache
sudo a2enmod proxy proxy_http headers ssl
sudo cp infra/dynamic/dynamic.alpinux.org.vhost.conf \
/etc/apache2/sites-available/dynamic.alpinux.org.conf
sudo a2ensite dynamic.alpinux.org
sudo apachectl configtest
sudo systemctl reload apache2
8. Obtenir le certificat SSL
sudo certbot --apache -d dynamic.alpinux.org
Mise à jour
ssh <user>@alpinux.org
cd $APP_DIR
git pull
cd dynamic
venv/bin/pip install -r requirements.txt # si requirements.txt a changé
sudo systemctl restart dynamic-alpinux
Gestion du service
| Action | Commande |
|---|---|
| Démarrer | sudo systemctl start dynamic-alpinux |
| Arrêter | sudo systemctl stop dynamic-alpinux |
| Redémarrer | sudo systemctl restart dynamic-alpinux |
| État | sudo systemctl status dynamic-alpinux |
| Logs en direct | sudo journalctl -u dynamic-alpinux -f |
Structure de l'application
dynamic/
├── app.py ← point d'entrée Flask
├── auth_utils.py ← décorateur @login_required
├── db.py ← SQLite (scores)
├── quiz.py ← chargement du JSON
├── requirements.txt
├── .env.example
├── data/
│ └── quizzes.json ← toutes les questions (source de vérité)
├── routes/
│ ├── public.py ← accueil, liste, jeu, résultat
│ ├── auth.py ← /auth/login, /auth/callback, /auth/logout
│ └── protected.py ← /profil/
├── static/
│ ├── style.css
│ └── quiz.js
└── templates/
├── base.html
├── index.html
├── quiz/
│ ├── intro.html
│ ├── play.html
│ └── result.html
└── profil/
└── index.html
Accès public vs membres
| URL | Accès |
|---|---|
/ |
Public |
/quiz/ |
Public (aperçu de tous les quiz) |
/quiz/<id>/ |
Public (page intro) |
/quiz/<id>/jouer |
Public si members_only: false, sinon AlpID requis |
/profil/ |
AlpID requis |
/auth/login |
Redirect → AlpID |
/auth/callback |
Retour OIDC (interne) |
Les quiz avancés (niveau 4) et experts (niveau 5) ont "members_only": true dans data/quizzes.json.
Ajouter un quiz
Éditez dynamic/data/quizzes.json et ajoutez un objet au tableau :
{
"id": "mon-quiz",
"title": "Titre du quiz",
"description": "Description courte.",
"level": "Intermédiaire",
"level_id": 3,
"members_only": false,
"duration_min": 5,
"icon": "🐧",
"questions": [
{
"id": 1,
"text": "Question ?",
"choices": ["Réponse A", "Réponse B", "Réponse C", "Réponse D"],
"answer": 0
}
]
}
level_id: 1=Découverte, 2=Débutant, 3=Intermédiaire, 4=Avancé, 5=Expertanswer: index 0-based de la bonne réponse danschoicesmembers_only:truepour restreindre aux membres AlpID
Après modification, redémarrez le service pour recharger le JSON :
sudo systemctl restart dynamic-alpinux