# 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} -- 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= -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/ 5432:5432 & # Dump PGPASSWORD= 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 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