976 lines
26 KiB
Plaintext
976 lines
26 KiB
Plaintext
# Guide de Migration Moodle vers Infrastructure RBER
|
|
|
|
> Guide pratique basé sur la migration réussie de l'UNSTIM (elearningum.rber.bj)
|
|
|
|
---
|
|
|
|
## Table des matières
|
|
|
|
1. [Prérequis](#1-prérequis)
|
|
2. [Phase 1 : Audit de l'environnement source](#2-phase-1--audit-de-lenvironnement-source)
|
|
3. [Phase 2 : Préparation infrastructure RBER](#3-phase-2--préparation-infrastructure-rber)
|
|
4. [Phase 3 : Sauvegarde des données](#4-phase-3--sauvegarde-des-données)
|
|
5. [Phase 4 : Transfert et restauration](#5-phase-4--transfert-et-restauration)
|
|
6. [Phase 5 : Configuration post-migration](#6-phase-5--configuration-post-migration)
|
|
7. [Phase 6 : Configuration rberConnect (SSO)](#7-phase-6--configuration-rberconnect-sso)
|
|
8. [Phase 7 : Validation et mise en production](#8-phase-7--validation-et-mise-en-production)
|
|
9. [Troubleshooting](#9-troubleshooting)
|
|
10. [Checklist de migration](#10-checklist-de-migration)
|
|
|
|
---
|
|
|
|
## 1. Prérequis
|
|
|
|
### Infrastructure RBER requise
|
|
|
|
| Composant | Version | Statut |
|
|
|-----------|---------|--------|
|
|
| Cluster RKE2 | v1.32+ | ✅ Disponible |
|
|
| CloudNativePG | v1.24+ | ✅ Disponible |
|
|
| Longhorn Storage | v1.7+ | ✅ Disponible |
|
|
| HAProxy Ingress | v1.11+ | ✅ Disponible |
|
|
| Harbor Registry | v2.11+ | ✅ Disponible |
|
|
| Keycloak (rberConnect) | v26+ | ✅ Disponible |
|
|
|
|
### Accès requis
|
|
|
|
- SSH vers le serveur Moodle source
|
|
- Accès admin Moodle source
|
|
- Accès base de données source (MySQL/MariaDB ou PostgreSQL)
|
|
- kubectl configuré sur le cluster RBER
|
|
- Accès Harbor (harbor.rber.bj)
|
|
|
|
### Outils sur le poste de travail
|
|
|
|
```bash
|
|
# Vérifier les outils
|
|
kubectl version --client
|
|
helm version
|
|
pg_dump --version # Si source PostgreSQL
|
|
mysqldump --version # Si source MySQL
|
|
rsync --version
|
|
```
|
|
|
|
### Informations à collecter avant de commencer
|
|
|
|
| Information | Exemple UNSTIM | Votre valeur |
|
|
|-------------|----------------|--------------|
|
|
| URL source | elearning.unstim.bj | |
|
|
| URL cible RBER | elearningum.rber.bj | |
|
|
| Version Moodle | 4.x / 5.x | |
|
|
| Type BDD source | MySQL / PostgreSQL | |
|
|
| Taille BDD | ~2 GB | |
|
|
| Taille moodledata | ~50 GB | |
|
|
| Namespace K8s | moodle-unstim | |
|
|
|
|
---
|
|
|
|
## 2. Phase 1 : Audit de l'environnement source
|
|
|
|
> **Note :** Les Moodle sources sont des pods Kubernetes. Toutes les commandes utilisent `kubectl exec`.
|
|
|
|
### 2.1 Identifier le pod source
|
|
|
|
```bash
|
|
# Variables - ADAPTER selon l'université et le namespace source
|
|
SOURCE_NS="moodle-source" # Namespace où se trouve le Moodle actuel
|
|
SOURCE_DEPLOY="moodle" # Nom du deployment
|
|
|
|
# Vérifier le pod
|
|
kubectl get pods -n ${SOURCE_NS}
|
|
|
|
# Version Moodle
|
|
kubectl exec -n ${SOURCE_NS} deploy/${SOURCE_DEPLOY} -- php /bitnami/moodle/admin/cli/version.php
|
|
|
|
# Version PHP et extensions
|
|
kubectl exec -n ${SOURCE_NS} deploy/${SOURCE_DEPLOY} -- php -v
|
|
kubectl exec -n ${SOURCE_NS} deploy/${SOURCE_DEPLOY} -- php -m | grep -E "curl|gd|intl|mbstring|pgsql|mysqli|xml|zip|soap|ldap"
|
|
```
|
|
|
|
### 2.2 Audit base de données
|
|
|
|
```bash
|
|
# Identifier le cluster PostgreSQL source
|
|
kubectl get cluster -n ${SOURCE_NS}
|
|
|
|
# Ou se connecter via le pod Moodle
|
|
kubectl exec -n ${SOURCE_NS} deploy/${SOURCE_DEPLOY} -- php -r "
|
|
require('/bitnami/moodle/config.php');
|
|
global \$DB;
|
|
echo 'Host: ' . \$CFG->dbhost . PHP_EOL;
|
|
echo 'Database: ' . \$CFG->dbname . PHP_EOL;
|
|
"
|
|
|
|
# Taille de la base (si accès direct au pod PostgreSQL)
|
|
kubectl exec -n ${SOURCE_NS} <pg-pod-name> -- psql -U postgres -d moodle -c "
|
|
SELECT pg_size_pretty(pg_database_size('moodle')) AS size;
|
|
"
|
|
```
|
|
|
|
### 2.3 Statistiques Moodle
|
|
|
|
```bash
|
|
kubectl exec -n ${SOURCE_NS} deploy/${SOURCE_DEPLOY} -- php -r "
|
|
require('/bitnami/moodle/config.php');
|
|
global \$DB;
|
|
echo 'Utilisateurs actifs: ' . \$DB->count_records('user', ['deleted' => 0]) . PHP_EOL;
|
|
echo 'Cours: ' . (\$DB->count_records('course') - 1) . PHP_EOL;
|
|
echo 'Fichiers: ' . \$DB->count_records_select('files', \"filename != '.'\") . PHP_EOL;
|
|
echo 'Devoirs: ' . \$DB->count_records('assign') . PHP_EOL;
|
|
"
|
|
```
|
|
|
|
### 2.4 Audit moodledata
|
|
|
|
```bash
|
|
# Taille totale
|
|
kubectl exec -n ${SOURCE_NS} deploy/${SOURCE_DEPLOY} -- du -sh /bitnami/moodledata/
|
|
|
|
# Répartition
|
|
kubectl exec -n ${SOURCE_NS} deploy/${SOURCE_DEPLOY} -- du -h --max-depth=1 /bitnami/moodledata/ | sort -hr
|
|
|
|
# Nombre de fichiers
|
|
kubectl exec -n ${SOURCE_NS} deploy/${SOURCE_DEPLOY} -- find /bitnami/moodledata -type f | wc -l
|
|
```
|
|
|
|
### 2.5 Plugins installés
|
|
|
|
```bash
|
|
# Liste des plugins
|
|
kubectl exec -n ${SOURCE_NS} deploy/${SOURCE_DEPLOY} -- php /bitnami/moodle/admin/cli/plugin_list.php
|
|
|
|
# Plugins custom (local)
|
|
kubectl exec -n ${SOURCE_NS} deploy/${SOURCE_DEPLOY} -- ls -la /bitnami/moodle/local/
|
|
|
|
# Thèmes custom
|
|
kubectl exec -n ${SOURCE_NS} deploy/${SOURCE_DEPLOY} -- ls -la /bitnami/moodle/theme/ | grep -v boost | grep -v classic
|
|
```
|
|
|
|
### 2.6 Configuration actuelle
|
|
|
|
```bash
|
|
# Afficher config.php
|
|
kubectl exec -n ${SOURCE_NS} deploy/${SOURCE_DEPLOY} -- cat /bitnami/moodle/config.php
|
|
|
|
# Paramètres critiques
|
|
kubectl exec -n ${SOURCE_NS} deploy/${SOURCE_DEPLOY} -- grep -E "wwwroot|dataroot|dbtype|dbhost|dbname|prefix" /bitnami/moodle/config.php
|
|
```
|
|
|
|
---
|
|
|
|
## 3. Phase 2 : Préparation infrastructure RBER
|
|
|
|
### 3.1 Créer le namespace
|
|
|
|
```bash
|
|
# Variables - ADAPTER selon l'université
|
|
UNIVERSITY="unstim" # uac, una, up, unstim
|
|
NAMESPACE="moodle-${UNIVERSITY}"
|
|
|
|
# Créer le namespace
|
|
kubectl create namespace ${NAMESPACE}
|
|
|
|
# Labelliser
|
|
kubectl label namespace ${NAMESPACE} \
|
|
university=${UNIVERSITY} \
|
|
app=moodle \
|
|
environment=production
|
|
```
|
|
|
|
### 3.2 Créer le PVC pour moodledata
|
|
|
|
```yaml
|
|
# moodle-${UNIVERSITY}-pvc.yaml
|
|
apiVersion: v1
|
|
kind: PersistentVolumeClaim
|
|
metadata:
|
|
name: moodle-${UNIVERSITY}-data
|
|
namespace: moodle-${UNIVERSITY}
|
|
spec:
|
|
accessModes:
|
|
- ReadWriteMany
|
|
storageClassName: longhorn
|
|
resources:
|
|
requests:
|
|
storage: 100Gi # Ajuster selon audit (+50% marge)
|
|
```
|
|
|
|
```bash
|
|
kubectl apply -f moodle-${UNIVERSITY}-pvc.yaml
|
|
kubectl get pvc -n ${NAMESPACE}
|
|
```
|
|
|
|
### 3.3 Base de données
|
|
|
|
**Option A : Base dédiée (recommandé pour isolation)**
|
|
|
|
Créer un cluster CloudNativePG dédié selon le guide infrastructure.
|
|
|
|
**Option B : Base partagée (utilisé pour UNSTIM)**
|
|
|
|
Utiliser le cluster PostgreSQL partagé existant :
|
|
- Host : `edu-pg-main-rw.shared.svc.cluster.local`
|
|
- Créer une base de données dédiée par université
|
|
|
|
```bash
|
|
# Créer la base dans le cluster partagé
|
|
kubectl exec -it -n shared edu-pg-main-1 -- psql -U postgres -c "
|
|
CREATE DATABASE moodle_${UNIVERSITY};
|
|
CREATE USER moodle_${UNIVERSITY} WITH PASSWORD 'MOT_DE_PASSE_FORT';
|
|
GRANT ALL PRIVILEGES ON DATABASE moodle_${UNIVERSITY} TO moodle_${UNIVERSITY};
|
|
"
|
|
```
|
|
|
|
### 3.4 Déployer Moodle (Helm Bitnami)
|
|
|
|
```bash
|
|
# Ajouter le repo
|
|
helm repo add bitnami https://charts.bitnami.com/bitnami
|
|
helm repo update
|
|
|
|
# Créer le fichier values
|
|
cat > moodle-${UNIVERSITY}-values.yaml << 'EOF'
|
|
image:
|
|
registry: docker.io
|
|
repository: bitnami/moodle
|
|
tag: 4.5.1-debian-12-r0 # Adapter à la version source
|
|
|
|
moodleSkipInstall: true # IMPORTANT : on migre, on n'installe pas
|
|
|
|
postgresql:
|
|
enabled: false # On utilise CloudNativePG externe
|
|
|
|
externalDatabase:
|
|
host: edu-pg-main-rw.shared.svc.cluster.local
|
|
port: 5432
|
|
user: moodle
|
|
database: moodle
|
|
type: pgsql
|
|
|
|
persistence:
|
|
enabled: true
|
|
existingClaim: moodle-UNIVERSITY-data # Remplacer UNIVERSITY
|
|
|
|
resources:
|
|
requests:
|
|
memory: "2Gi"
|
|
cpu: "1000m"
|
|
limits:
|
|
memory: "4Gi"
|
|
cpu: "2000m"
|
|
|
|
replicaCount: 1 # Commencer à 1, augmenter après validation
|
|
|
|
ingress:
|
|
enabled: true
|
|
ingressClassName: haproxy
|
|
hostname: elearningXX.rber.bj # Remplacer XX
|
|
annotations:
|
|
haproxy.org/ssl-redirect: "false"
|
|
|
|
livenessProbe:
|
|
enabled: true
|
|
initialDelaySeconds: 600
|
|
periodSeconds: 30
|
|
|
|
readinessProbe:
|
|
enabled: true
|
|
initialDelaySeconds: 120
|
|
periodSeconds: 10
|
|
EOF
|
|
|
|
# Installer
|
|
helm install moodle-${UNIVERSITY} bitnami/moodle \
|
|
--namespace ${NAMESPACE} \
|
|
--values moodle-${UNIVERSITY}-values.yaml \
|
|
--set externalDatabase.password="MOT_DE_PASSE_DB" \
|
|
--wait --timeout 20m
|
|
```
|
|
|
|
---
|
|
|
|
## 4. Phase 3 : Sauvegarde des données
|
|
|
|
### 4.1 Activer le mode maintenance
|
|
|
|
```bash
|
|
kubectl exec -n ${SOURCE_NS} deploy/${SOURCE_DEPLOY} -- php /bitnami/moodle/admin/cli/maintenance.php --enable
|
|
|
|
# Vérifier
|
|
curl -I https://elearning-source.rber.bj
|
|
```
|
|
|
|
### 4.2 Dump de la base de données
|
|
|
|
**Option A : Dump depuis le pod PostgreSQL**
|
|
|
|
```bash
|
|
# Identifier le pod PostgreSQL
|
|
PG_POD=$(kubectl get pods -n ${SOURCE_NS} -l cnpg.io/cluster=<cluster-name> -o jsonpath='{.items[0].metadata.name}')
|
|
|
|
# Dump
|
|
kubectl exec -n ${SOURCE_NS} ${PG_POD} -- pg_dump -U postgres -Fc moodle > moodle_dump_$(date +%Y%m%d_%H%M%S).dump
|
|
|
|
# Vérifier
|
|
ls -lh moodle_dump_*.dump
|
|
```
|
|
|
|
**Option B : Dump via port-forward**
|
|
|
|
```bash
|
|
# Port-forward
|
|
kubectl port-forward -n ${SOURCE_NS} svc/<pg-service> 5432:5432 &
|
|
|
|
# Dump
|
|
PGPASSWORD=<password> pg_dump -h localhost -U moodle -Fc moodle > moodle_dump_$(date +%Y%m%d_%H%M%S).dump
|
|
|
|
# Arrêter le port-forward
|
|
kill %1
|
|
```
|
|
|
|
### 4.3 Archiver moodledata
|
|
|
|
```bash
|
|
# Créer l'archive depuis le pod source
|
|
kubectl exec -n ${SOURCE_NS} deploy/${SOURCE_DEPLOY} -- tar -czf /tmp/moodledata_backup.tar.gz \
|
|
--exclude='cache/*' \
|
|
--exclude='sessions/*' \
|
|
--exclude='temp/*' \
|
|
--exclude='trashdir/*' \
|
|
--exclude='localcache/*' \
|
|
-C /bitnami moodledata
|
|
|
|
# Copier l'archive vers le poste local
|
|
kubectl cp ${SOURCE_NS}/${SOURCE_DEPLOY}:/tmp/moodledata_backup.tar.gz ./moodledata_backup_$(date +%Y%m%d_%H%M%S).tar.gz
|
|
|
|
# Vérifier
|
|
ls -lh moodledata_backup_*.tar.gz
|
|
|
|
# Checksum
|
|
sha256sum moodledata_backup_*.tar.gz > moodledata.sha256
|
|
|
|
# Nettoyer le fichier temporaire dans le pod
|
|
kubectl exec -n ${SOURCE_NS} deploy/${SOURCE_DEPLOY} -- rm /tmp/moodledata_backup.tar.gz
|
|
```
|
|
|
|
**Alternative : Extraction directe (gros volumes)**
|
|
|
|
```bash
|
|
# Streamer directement sans fichier intermédiaire
|
|
kubectl exec -n ${SOURCE_NS} deploy/${SOURCE_DEPLOY} -- tar -czf - \
|
|
--exclude='cache/*' \
|
|
--exclude='sessions/*' \
|
|
--exclude='temp/*' \
|
|
--exclude='trashdir/*' \
|
|
--exclude='localcache/*' \
|
|
-C /bitnami moodledata > moodledata_backup_$(date +%Y%m%d_%H%M%S).tar.gz
|
|
```
|
|
|
|
### 4.4 Sauvegarder plugins custom (si nécessaire)
|
|
|
|
```bash
|
|
kubectl exec -n ${SOURCE_NS} deploy/${SOURCE_DEPLOY} -- tar -czf /tmp/plugins.tar.gz \
|
|
-C /bitnami/moodle \
|
|
local/ \
|
|
theme/
|
|
|
|
kubectl cp ${SOURCE_NS}/${SOURCE_DEPLOY}:/tmp/plugins.tar.gz ./moodle_plugins_$(date +%Y%m%d).tar.gz
|
|
```
|
|
|
|
---
|
|
|
|
## 5. Phase 4 : Transfert et restauration
|
|
|
|
### 5.1 Variables cibles
|
|
|
|
```bash
|
|
# ADAPTER selon l'université
|
|
UNIVERSITY="unstim"
|
|
TARGET_NS="moodle-${UNIVERSITY}"
|
|
TARGET_DEPLOY="moodle-${UNIVERSITY}"
|
|
```
|
|
|
|
### 5.2 Transfert via MinIO (recommandé)
|
|
|
|
```bash
|
|
# Configurer MinIO
|
|
mc alias set rber http://minio.rber.bj:9000 ACCESS_KEY SECRET_KEY
|
|
|
|
# Créer le bucket
|
|
mc mb rber/migrations/${UNIVERSITY}
|
|
|
|
# Upload
|
|
mc cp moodle_dump_*.dump rber/migrations/${UNIVERSITY}/
|
|
mc cp moodledata_backup_*.tar.gz rber/migrations/${UNIVERSITY}/
|
|
mc cp moodledata.sha256 rber/migrations/${UNIVERSITY}/
|
|
|
|
# Vérifier
|
|
mc ls rber/migrations/${UNIVERSITY}/
|
|
```
|
|
|
|
### 5.3 Restaurer la base de données
|
|
|
|
**PostgreSQL → PostgreSQL :**
|
|
|
|
```bash
|
|
# Port-forward vers le cluster PG cible
|
|
kubectl port-forward -n shared svc/edu-pg-main-rw 5432:5432 &
|
|
|
|
# Restaurer
|
|
pg_restore -h localhost -U moodle -d moodle --no-owner --no-acl moodle_dump_*.dump
|
|
|
|
# Arrêter le port-forward
|
|
kill %1
|
|
```
|
|
|
|
**Ou directement dans le pod PostgreSQL :**
|
|
|
|
```bash
|
|
# Copier le dump dans le pod PG
|
|
kubectl cp moodle_dump_*.dump shared/edu-pg-main-1:/tmp/
|
|
|
|
# Restaurer
|
|
kubectl exec -n shared edu-pg-main-1 -- pg_restore -U postgres -d moodle --no-owner /tmp/moodle_dump.dump
|
|
|
|
# Nettoyer
|
|
kubectl exec -n shared edu-pg-main-1 -- rm /tmp/moodle_dump.dump
|
|
```
|
|
|
|
### 5.4 Restaurer moodledata
|
|
|
|
**Méthode recommandée avec suivi de progression :**
|
|
|
|
```bash
|
|
# Avec pv pour voir la progression
|
|
pv moodledata_backup_*.tar.gz | kubectl exec -i -n ${TARGET_NS} deploy/${TARGET_DEPLOY} -- tar -xzf - -C /bitnami/moodledata --strip-components=1 --no-same-owner
|
|
```
|
|
|
|
**Sans pv :**
|
|
|
|
```bash
|
|
cat moodledata_backup_*.tar.gz | kubectl exec -i -n ${TARGET_NS} deploy/${TARGET_DEPLOY} -- tar -xzf - -C /bitnami/moodledata --strip-components=1 --no-same-owner
|
|
```
|
|
|
|
**Suivre la progression (autre terminal) :**
|
|
|
|
```bash
|
|
watch -n 5 "kubectl exec -n ${TARGET_NS} deploy/${TARGET_DEPLOY} -- du -sh /bitnami/moodledata"
|
|
```
|
|
|
|
### 5.5 Corriger les permissions
|
|
|
|
```bash
|
|
kubectl exec -n ${TARGET_NS} deploy/${TARGET_DEPLOY} -- chown -R 1001:1001 /bitnami/moodledata
|
|
kubectl exec -n ${TARGET_NS} deploy/${TARGET_DEPLOY} -- chmod -R 755 /bitnami/moodledata
|
|
```
|
|
|
|
---
|
|
|
|
## 6. Phase 5 : Configuration post-migration
|
|
|
|
### 6.1 Configurer config.php
|
|
|
|
**⚠️ Point critique** - Un config.php mal configuré casse l'affichage (CSS non chargé).
|
|
|
|
```bash
|
|
# ADAPTER les valeurs selon l'université
|
|
UNIVERSITY="unstim"
|
|
TARGET_NS="moodle-${UNIVERSITY}"
|
|
TARGET_DEPLOY="moodle-${UNIVERSITY}"
|
|
TARGET_URL="elearningum.rber.bj" # Adapter selon université
|
|
DB_HOST="edu-pg-main-rw.shared.svc.cluster.local"
|
|
DB_NAME="moodle"
|
|
DB_USER="moodle"
|
|
DB_PASS="MOT_DE_PASSE"
|
|
|
|
kubectl exec -i -n ${TARGET_NS} deploy/${TARGET_DEPLOY} -- bash -c 'cat > /bitnami/moodle/config.php' << EOF
|
|
<?php // Moodle configuration file
|
|
unset(\$CFG);
|
|
global \$CFG;
|
|
\$CFG = new stdClass();
|
|
|
|
// === DATABASE ===
|
|
\$CFG->dbtype = 'pgsql';
|
|
\$CFG->dblibrary = 'native';
|
|
\$CFG->dbhost = '${DB_HOST}';
|
|
\$CFG->dbname = '${DB_NAME}';
|
|
\$CFG->dbuser = '${DB_USER}';
|
|
\$CFG->dbpass = '${DB_PASS}';
|
|
\$CFG->prefix = 'mdl_';
|
|
\$CFG->dboptions = array(
|
|
'dbpersist' => 0,
|
|
'dbport' => 5432,
|
|
'dbsocket' => '',
|
|
);
|
|
|
|
// === URL ===
|
|
if (empty(\$_SERVER['HTTP_HOST'])) {
|
|
\$_SERVER['HTTP_HOST'] = '127.0.0.1:8080';
|
|
}
|
|
|
|
// Détection automatique HTTP/HTTPS
|
|
if (isset(\$_SERVER['HTTPS']) && \$_SERVER['HTTPS'] == 'on') {
|
|
\$CFG->wwwroot = 'https://${TARGET_URL}';
|
|
} else {
|
|
\$CFG->wwwroot = 'http://${TARGET_URL}';
|
|
}
|
|
|
|
// === PATHS ===
|
|
\$CFG->dataroot = '/bitnami/moodledata';
|
|
\$CFG->admin = 'admin';
|
|
\$CFG->directorypermissions = 02775;
|
|
|
|
// === PERFORMANCE ===
|
|
\$CFG->cachejs = true;
|
|
\$CFG->langstringcache = true;
|
|
|
|
// === PROXY SETTINGS (derrière HAProxy) ===
|
|
\$CFG->reverseproxy = true;
|
|
\$CFG->sslproxy = true;
|
|
|
|
require_once(__DIR__ . '/lib/setup.php');
|
|
EOF
|
|
```
|
|
|
|
### 6.2 Purger les caches
|
|
|
|
```bash
|
|
kubectl exec -n ${TARGET_NS} deploy/${TARGET_DEPLOY} -- php /bitnami/moodle/admin/cli/purge_caches.php
|
|
```
|
|
|
|
### 6.3 Mettre à jour les URLs dans la base
|
|
|
|
```bash
|
|
# Remplacer l'ancienne URL par la nouvelle
|
|
kubectl exec -n ${TARGET_NS} deploy/${TARGET_DEPLOY} -- php /bitnami/moodle/admin/cli/replace.php \
|
|
--search="http://ANCIEN-DOMAINE" \
|
|
--replace="https://${TARGET_URL}" \
|
|
--non-interactive
|
|
```
|
|
|
|
### 6.4 Exécuter les mises à jour de base
|
|
|
|
```bash
|
|
kubectl exec -n ${TARGET_NS} deploy/${TARGET_DEPLOY} -- php /bitnami/moodle/admin/cli/upgrade.php --non-interactive
|
|
```
|
|
|
|
---
|
|
|
|
## 7. Phase 6 : Configuration rberConnect (SSO)
|
|
|
|
rberConnect utilise Keycloak pour l'authentification centralisée. Cette configuration permet aux utilisateurs de se connecter avec leurs identifiants universitaires unifiés.
|
|
|
|
### 7.1 Prérequis Keycloak
|
|
|
|
Vérifier que le client Moodle existe dans Keycloak :
|
|
- **Realm** : rber
|
|
- **Client ID** : moodle-UNIVERSITY (ex: moodle-unstim)
|
|
- **Client Protocol** : openid-connect
|
|
- **Access Type** : confidential
|
|
- **Valid Redirect URIs** : https://elearningXX.rber.bj/*
|
|
|
|
### 7.2 Récupérer les informations Keycloak
|
|
|
|
```bash
|
|
# URLs Keycloak RBER
|
|
KEYCLOAK_URL="https://auth.rber.bj"
|
|
REALM="rber"
|
|
|
|
# Endpoints (à vérifier)
|
|
# Authorization: ${KEYCLOAK_URL}/realms/${REALM}/protocol/openid-connect/auth
|
|
# Token: ${KEYCLOAK_URL}/realms/${REALM}/protocol/openid-connect/token
|
|
# Userinfo: ${KEYCLOAK_URL}/realms/${REALM}/protocol/openid-connect/userinfo
|
|
```
|
|
|
|
### 7.3 Activer OAuth2 dans Moodle
|
|
|
|
**Étape 1 : Accéder à l'administration**
|
|
|
|
1. Aller sur `https://elearningXX.rber.bj/admin`
|
|
2. Se connecter en tant qu'administrateur
|
|
3. Naviguer vers : **Administration du site** → **Plugins** → **Authentification** → **Gestion de l'authentification**
|
|
|
|
**Étape 2 : Activer OAuth 2**
|
|
|
|
1. Dans la liste des plugins d'authentification, activer **OAuth 2**
|
|
2. Cliquer sur **Réglages** à côté de OAuth 2
|
|
|
|
**Étape 3 : Créer un service OAuth 2**
|
|
|
|
1. Aller dans : **Administration du site** → **Serveur** → **Services OAuth 2**
|
|
2. Cliquer sur **Créer un nouveau service personnalisé**
|
|
|
|
### 7.4 Configuration du service OAuth 2
|
|
|
|
Remplir les champs suivants :
|
|
|
|
| Champ | Valeur |
|
|
|-------|--------|
|
|
| **Nom** | rberConnect |
|
|
| **Client ID** | moodle-UNIVERSITY |
|
|
| **Client secret** | (récupérer dans Keycloak) |
|
|
| **Authenticate token requests via HTTP headers** | ✅ Oui |
|
|
| **Service Base URL** | https://auth.rber.bj/realms/rber |
|
|
| **Scopes** | openid profile email |
|
|
|
|
**Endpoints à configurer :**
|
|
|
|
| Endpoint | URL |
|
|
|----------|-----|
|
|
| **Authorization endpoint** | https://auth.rber.bj/realms/rber/protocol/openid-connect/auth |
|
|
| **Token endpoint** | https://auth.rber.bj/realms/rber/protocol/openid-connect/token |
|
|
| **Userinfo endpoint** | https://auth.rber.bj/realms/rber/protocol/openid-connect/userinfo |
|
|
| **JWKS URL** | https://auth.rber.bj/realms/rber/protocol/openid-connect/certs |
|
|
|
|
### 7.5 Mapper les attributs utilisateur
|
|
|
|
Dans la configuration du service OAuth 2, configurer le **User field mappings** :
|
|
|
|
| Champ Moodle | Claim OAuth 2 |
|
|
|--------------|---------------|
|
|
| username | preferred_username |
|
|
| email | email |
|
|
| firstname | given_name |
|
|
| lastname | family_name |
|
|
|
|
### 7.6 Configuration via CLI (alternative)
|
|
|
|
```bash
|
|
kubectl exec -it -n ${NAMESPACE} deploy/moodle-${UNIVERSITY} -- bash
|
|
|
|
# Dans le pod
|
|
php /bitnami/moodle/admin/cli/cfg.php --name=auth --set=oauth2
|
|
php /bitnami/moodle/admin/cli/cfg.php --name=authpreventaccountcreation --set=0
|
|
php /bitnami/moodle/admin/cli/cfg.php --name=allowaccountssameemail --set=1
|
|
|
|
exit
|
|
```
|
|
|
|
### 7.7 Créer le service OAuth 2 via SQL (avancé)
|
|
|
|
```sql
|
|
-- Exécuter dans la base Moodle
|
|
INSERT INTO mdl_oauth2_issuer (
|
|
name,
|
|
clientid,
|
|
clientsecret,
|
|
baseurl,
|
|
loginscopes,
|
|
loginscopesoffline,
|
|
enabled,
|
|
showonloginpage
|
|
) VALUES (
|
|
'rberConnect',
|
|
'moodle-UNIVERSITY',
|
|
'CLIENT_SECRET_ICI',
|
|
'https://auth.rber.bj/realms/rber',
|
|
'openid profile email',
|
|
'openid profile email offline_access',
|
|
1,
|
|
1
|
|
);
|
|
```
|
|
|
|
### 7.8 Tester l'authentification
|
|
|
|
1. Ouvrir une fenêtre de navigation privée
|
|
2. Aller sur `https://elearningXX.rber.bj/login/`
|
|
3. Cliquer sur le bouton **rberConnect** (ou équivalent)
|
|
4. Être redirigé vers Keycloak
|
|
5. Se connecter avec les identifiants universitaires
|
|
6. Être redirigé vers Moodle, connecté
|
|
|
|
### 7.9 Configuration Keycloak côté serveur
|
|
|
|
Si le client n'existe pas encore dans Keycloak :
|
|
|
|
```bash
|
|
# Se connecter à Keycloak Admin
|
|
# https://auth.rber.bj/admin/
|
|
|
|
# Créer le client :
|
|
# 1. Realm : rber
|
|
# 2. Clients → Create client
|
|
# 3. Client ID : moodle-UNIVERSITY
|
|
# 4. Client Protocol : openid-connect
|
|
# 5. Root URL : https://elearningXX.rber.bj
|
|
# 6. Valid redirect URIs : https://elearningXX.rber.bj/*
|
|
# 7. Web origins : https://elearningXX.rber.bj
|
|
# 8. Access Type : confidential
|
|
# 9. Sauvegarder et récupérer le secret dans l'onglet Credentials
|
|
```
|
|
|
|
---
|
|
|
|
## 8. Phase 7 : Validation et mise en production
|
|
|
|
### 8.1 Tests fonctionnels
|
|
|
|
| Test | Commande / Action | Résultat attendu |
|
|
|------|-------------------|------------------|
|
|
| Page d'accueil | `curl -I https://elearningXX.rber.bj` | HTTP 200, CSS chargé |
|
|
| Login admin | Se connecter via navigateur | Accès au tableau de bord |
|
|
| Login SSO | Cliquer sur rberConnect | Redirection Keycloak → Moodle |
|
|
| Upload fichier | Ajouter un fichier dans un cours | Fichier accessible |
|
|
| Téléchargement | Télécharger un fichier existant | Téléchargement OK |
|
|
| Cours existants | Vérifier la liste des cours | Tous les cours présents |
|
|
| Utilisateurs | Administration → Utilisateurs | Comptes migrés |
|
|
|
|
### 8.2 Vérification des données
|
|
|
|
```bash
|
|
# Compter les utilisateurs
|
|
kubectl exec -n ${TARGET_NS} deploy/${TARGET_DEPLOY} -- php -r "
|
|
require('/bitnami/moodle/config.php');
|
|
global \$DB;
|
|
echo 'Utilisateurs actifs: ' . \$DB->count_records('user', ['deleted' => 0]) . PHP_EOL;
|
|
echo 'Cours: ' . \$DB->count_records('course') . PHP_EOL;
|
|
"
|
|
```
|
|
|
|
### 8.3 Test de performance
|
|
|
|
```bash
|
|
# Test basique avec curl
|
|
time curl -s -o /dev/null -w "%{http_code}" https://elearningXX.rber.bj
|
|
|
|
# Test de charge (si ab disponible)
|
|
ab -n 100 -c 10 https://elearningXX.rber.bj/
|
|
```
|
|
|
|
### 8.4 Configuration DNS
|
|
|
|
Coordonner avec l'administrateur réseau :
|
|
|
|
```dns
|
|
; Zone RBER
|
|
elearningXX.rber.bj. IN A 10.29.112.100 ; IP HAProxy VIP
|
|
|
|
; Optionnel : ancien domaine en redirection
|
|
elearning.UNIVERSITY.bj. IN CNAME elearningXX.rber.bj.
|
|
```
|
|
|
|
### 8.5 Désactiver la maintenance sur le pod source
|
|
|
|
```bash
|
|
# Désactiver la maintenance
|
|
kubectl exec -n ${SOURCE_NS} deploy/${SOURCE_DEPLOY} -- php /bitnami/moodle/admin/cli/maintenance.php --disable
|
|
|
|
# Ou si l'ancien pod n'est plus nécessaire, le scaler à 0
|
|
kubectl scale -n ${SOURCE_NS} deploy/${SOURCE_DEPLOY} --replicas=0
|
|
```
|
|
|
|
### 8.6 Communication aux utilisateurs
|
|
|
|
```
|
|
Objet : ✅ Migration réussie - Nouvelle plateforme e-learning
|
|
|
|
Chers utilisateurs,
|
|
|
|
La plateforme e-learning de [UNIVERSITÉ] est maintenant accessible sur :
|
|
🔗 https://elearningXX.rber.bj
|
|
|
|
Nouveautés :
|
|
- Connexion simplifiée via rberConnect (identifiants universitaires)
|
|
- Performances améliorées
|
|
- Disponibilité renforcée
|
|
|
|
Vos cours et données ont été migrés. Vos identifiants restent les mêmes.
|
|
|
|
Support : support@rber.bj
|
|
```
|
|
|
|
---
|
|
|
|
## 9. Troubleshooting
|
|
|
|
> **Note :** Dans toutes les commandes ci-dessous, utiliser les variables définies :
|
|
> ```bash
|
|
> UNIVERSITY="unstim" # Adapter
|
|
> TARGET_NS="moodle-${UNIVERSITY}"
|
|
> TARGET_DEPLOY="moodle-${UNIVERSITY}"
|
|
> ```
|
|
|
|
### 9.1 CSS ne charge pas (page sans style)
|
|
|
|
**Cause :** `wwwroot` incorrect dans config.php
|
|
|
|
```bash
|
|
# Vérifier
|
|
kubectl exec -n ${TARGET_NS} deploy/${TARGET_DEPLOY} -- grep wwwroot /bitnami/moodle/config.php
|
|
|
|
# Le protocole (http/https) doit correspondre à l'URL utilisée
|
|
# Corriger si nécessaire
|
|
kubectl exec -n ${TARGET_NS} deploy/${TARGET_DEPLOY} -- sed -i "s|http://|https://|g" /bitnami/moodle/config.php
|
|
|
|
# Purger le cache
|
|
kubectl exec -n ${TARGET_NS} deploy/${TARGET_DEPLOY} -- php /bitnami/moodle/admin/cli/purge_caches.php
|
|
|
|
# Vider le cache du navigateur : Ctrl+Shift+R
|
|
```
|
|
|
|
### 9.2 Erreur de connexion base de données
|
|
|
|
```bash
|
|
# Vérifier la connectivité
|
|
kubectl exec -n ${TARGET_NS} deploy/${TARGET_DEPLOY} -- php -r "
|
|
\$conn = pg_connect('host=edu-pg-main-rw.shared.svc.cluster.local port=5432 dbname=moodle user=moodle password=XXX');
|
|
if (\$conn) { echo 'DB OK'.PHP_EOL; } else { echo 'DB FAIL'.PHP_EOL; }
|
|
"
|
|
|
|
# Vérifier les credentials dans config.php
|
|
kubectl exec -n ${TARGET_NS} deploy/${TARGET_DEPLOY} -- grep -E "dbhost|dbname|dbuser|dbpass" /bitnami/moodle/config.php
|
|
```
|
|
|
|
### 9.3 Erreur 502 Bad Gateway
|
|
|
|
```bash
|
|
# Vérifier le pod
|
|
kubectl get pods -n ${TARGET_NS}
|
|
kubectl logs -n ${TARGET_NS} deploy/${TARGET_DEPLOY} --tail=50
|
|
|
|
# Vérifier l'ingress
|
|
kubectl get ingress -n ${TARGET_NS}
|
|
kubectl describe ingress -n ${TARGET_NS}
|
|
|
|
# Vérifier le service
|
|
kubectl get svc -n ${TARGET_NS}
|
|
```
|
|
|
|
### 9.4 Fichiers non accessibles
|
|
|
|
```bash
|
|
# Vérifier les permissions
|
|
kubectl exec -n ${TARGET_NS} deploy/${TARGET_DEPLOY} -- ls -la /bitnami/moodledata/
|
|
|
|
# Corriger
|
|
kubectl exec -n ${TARGET_NS} deploy/${TARGET_DEPLOY} -- chown -R 1001:1001 /bitnami/moodledata
|
|
kubectl exec -n ${TARGET_NS} deploy/${TARGET_DEPLOY} -- chmod -R 755 /bitnami/moodledata
|
|
```
|
|
|
|
### 9.5 rberConnect ne fonctionne pas
|
|
|
|
```bash
|
|
# Vérifier que OAuth2 est activé
|
|
kubectl exec -n ${TARGET_NS} deploy/${TARGET_DEPLOY} -- php /bitnami/moodle/admin/cli/cfg.php --name=auth
|
|
|
|
# Tester la connectivité vers Keycloak
|
|
kubectl exec -n ${TARGET_NS} deploy/${TARGET_DEPLOY} -- curl -I https://auth.rber.bj/realms/rber/.well-known/openid-configuration
|
|
|
|
# Vérifier les logs
|
|
kubectl logs -n ${TARGET_NS} deploy/${TARGET_DEPLOY} | grep -i oauth
|
|
```
|
|
|
|
### 9.6 Pod en CrashLoopBackOff
|
|
|
|
```bash
|
|
# Voir les logs du pod précédent
|
|
kubectl logs -n ${TARGET_NS} -l app.kubernetes.io/name=moodle --previous
|
|
|
|
# Vérifier les events
|
|
kubectl get events -n ${TARGET_NS} --sort-by='.lastTimestamp' | tail -20
|
|
|
|
# Vérifier les ressources
|
|
kubectl describe pod -n ${TARGET_NS} -l app.kubernetes.io/name=moodle
|
|
```
|
|
|
|
### 9.7 Commandes de diagnostic générales
|
|
|
|
```bash
|
|
# État général
|
|
kubectl get all -n ${TARGET_NS}
|
|
|
|
# Logs en temps réel
|
|
kubectl logs -n ${TARGET_NS} deploy/${TARGET_DEPLOY} -f
|
|
|
|
# Entrer dans le pod
|
|
kubectl exec -it -n ${TARGET_NS} deploy/${TARGET_DEPLOY} -- bash
|
|
|
|
# Vérifier le config.php complet
|
|
kubectl exec -n ${TARGET_NS} deploy/${TARGET_DEPLOY} -- cat /bitnami/moodle/config.php
|
|
```
|
|
|
|
---
|
|
|
|
## 10. Checklist de migration
|
|
|
|
### Avant la migration
|
|
|
|
- [ ] Audit de l'environnement source complété
|
|
- [ ] Taille de stockage estimée (+50% marge)
|
|
- [ ] Namespace créé
|
|
- [ ] PVC créé
|
|
- [ ] Base de données préparée
|
|
- [ ] Fenêtre de maintenance planifiée et communiquée
|
|
|
|
### Sauvegarde
|
|
|
|
- [ ] Mode maintenance activé sur source
|
|
- [ ] Dump base de données effectué
|
|
- [ ] Checksum du dump vérifié
|
|
- [ ] Archive moodledata créée
|
|
- [ ] Checksum moodledata vérifié
|
|
- [ ] Plugins custom sauvegardés
|
|
- [ ] config.php sauvegardé
|
|
|
|
### Transfert et restauration
|
|
|
|
- [ ] Fichiers transférés vers RBER
|
|
- [ ] Checksums vérifiés après transfert
|
|
- [ ] Base de données restaurée (conversion MySQL→PG si nécessaire)
|
|
- [ ] Moodledata restauré
|
|
- [ ] Permissions corrigées (1001:1001)
|
|
|
|
### Configuration
|
|
|
|
- [ ] config.php configuré correctement
|
|
- [ ] wwwroot correspond au protocole utilisé (HTTP/HTTPS)
|
|
- [ ] Caches purgés
|
|
- [ ] URLs mises à jour dans la base
|
|
- [ ] Upgrade Moodle exécuté
|
|
|
|
### rberConnect (SSO)
|
|
|
|
- [ ] Client Keycloak créé/vérifié
|
|
- [ ] Service OAuth 2 créé dans Moodle
|
|
- [ ] Endpoints configurés
|
|
- [ ] Mapping attributs configuré
|
|
- [ ] Test de connexion SSO réussi
|
|
|
|
### Validation
|
|
|
|
- [ ] Page d'accueil charge avec CSS
|
|
- [ ] Login administrateur fonctionne
|
|
- [ ] Login utilisateur standard fonctionne
|
|
- [ ] Login SSO (rberConnect) fonctionne
|
|
- [ ] Cours existants visibles
|
|
- [ ] Upload de fichiers fonctionne
|
|
- [ ] Téléchargement de fichiers fonctionne
|
|
- [ ] Nombre d'utilisateurs correspond
|
|
- [ ] Nombre de cours correspond
|
|
|
|
### Mise en production
|
|
|
|
- [ ] DNS configuré
|
|
- [ ] Certificat SSL valide (si applicable)
|
|
- [ ] Ancien serveur maintenance désactivée ou éteint
|
|
- [ ] Communication utilisateurs envoyée
|
|
- [ ] Monitoring configuré
|
|
- [ ] Backup automatique configuré
|
|
|
|
---
|
|
|
|
## Annexe : Correspondance des universités
|
|
|
|
| Université | Code | Namespace | URL RBER | Client Keycloak |
|
|
|------------|------|-----------|----------|-----------------|
|
|
| UNSTIM | unstim | moodle-unstim | elearningum.rber.bj | moodle-unstim |
|
|
| UAC | uac | moodle-uac | elearningac.rber.bj | moodle-uac |
|
|
| UNA | una | moodle-una | elearningna.rber.bj | moodle-una |
|
|
| UP | up | moodle-up | elearningup.rber.bj | moodle-up |
|
|
|
|
---
|
|
|
|
**Version** : 2.0
|
|
**Basé sur** : Migration UNSTIM - Décembre 2025
|
|
**Contact** : devops@rber.bj |