Introduction
Sauvegarder et restaurer une API REST n'est pas une simple commande, mais un ensemble de pratiques opérationnelles qui vous mènent d'un problème observé à un résultat vérifié. Une sauvegarde n'est utile que si vous pouvez la restaurer, et une restauration n'est fiable que si vous pouvez prouver qu'elle a fonctionné. Cet article fournit un guide pratique, étape par étape, pour les développeurs, les consultants DevOps et les équipes techniques de startups qui doivent mettre en œuvre des procédures fiables de sauvegarde et de restauration pour une API REST construite avec Node.js, Express et MongoDB. Nous utiliserons des exemples concrets, des commandes, des sorties attendues, des signaux d'échec et des décisions de récupération pour rendre le processus opérationnel.
L'objectif principal est la sécurité opérationnelle : observer avant de changer, limiter le rayon d'impact, utiliser des espaces réservés au lieu de secrets, vérifier chaque résultat et documenter les chemins de récupération. Nous couvrirons cinq pratiques essentielles :
- Inventaire des versions et de l'environnement : sachez exactement ce que vous exécutez avant de toucher à quoi que ce soit.
- Chemin de configuration sûr : apportez des modifications de manière contrôlée et réversible.
- Vérification et diagnostics : confirmez que les sauvegardes et les restaurations fonctionnent réellement.
- Modes de défaillance et récupération : prévoyez l'inévitable et sachez comment revenir en arrière.
- Liste de contrôle opérationnelle : transformez ces pratiques en une procédure reproductible.
Tout au long de l'article, nous utiliserons une API de commerce électronique fictive appelée acme-api pour illustrer des scénarios réels.
Inventaire des versions et de l'environnement
Avant toute opération de sauvegarde ou de restauration, vous devez connaître l'état exact de votre environnement. Cela inclut le code de l'application API, ses dépendances, l'environnement d'exécution, la base de données et les services auxiliaires. Une incompatibilité de version peut transformer une restauration de routine en une panne de plusieurs heures. L'inventaire capture l'état actuel et les horodatages, protège les informations d'identification et définit le plus petit changement justifié.
Identification des composants et des versions
Pour notre acme-api, les composants sont :
- Code de l'application : le code du serveur Express.js, versionné dans Git.
- Environnement d'exécution Node.js : la version installée sur le serveur de production.
- Dépendances du package : le fichier de verrouillage
node_modules. - Base de données : MongoDB, y compris ses données et son schéma.
- Configuration de l'environnement : clés secrètes, URL de base de données et autres paramètres.
Utilisez des commandes en lecture seule pour capturer l'état actuel sans rien altérer. Par exemple, sur le serveur de production, exécutez :
node --version
# Sortie attendue : v18.16.0
npm --version
# Sortie attendue : 9.5.1
git rev-parse HEAD
# Sortie attendue : 3f2b9a4c1e... (hash de commit)
mongod --version | head -1
# Sortie attendue : db version v6.0.5
Pour l'application elle-même, vérifiez les versions des packages déployés :
npm list --depth=0
# La sortie attendue montre : [email protected], [email protected], etc.
Documentez ces versions dans un fichier texte ou une base de données de gestion de configuration. Incluez la date et l'heure de l'inventaire. Par exemple :
2025-03-01 10:23:45 UTC, acme-api v1.4.2, Node v18.16.0, MongoDB v6.0.5, commit 3f2b9a4c1e, express 4.18.2, mongoose 7.1.0
Prérequis et rayon d'impact
Définissez les prérequis pour toute opération de sauvegarde ou de restauration. Pour notre API, une sauvegarde complète nécessite :
- Un accès en lecture aux fichiers de l'application (généralement via SSH ou un outil de déploiement).
- Un accès en lecture à l'instance MongoDB (un utilisateur avec le rôle
backup). - Un espace disque suffisant pour la sauvegarde.
- La possibilité d'exécuter des commandes sans provoquer d'indisponibilité (ou une fenêtre de maintenance si une indisponibilité est nécessaire).
Le rayon d'impact est l'ensemble des ressources qu'un changement pourrait affecter. Pour une sauvegarde de base de données, le rayon d'impact est généralement limité au serveur de base de données, mais si vous arrêtez l'API pour effectuer une sauvegarde cohérente, le rayon d'impact inclut la disponibilité de l'API. Efforcez-vous toujours de minimiser le rayon d'impact en utilisant des méthodes de sauvegarde non perturbatrices, telles que mongodump avec --oplog pour des sauvegardes à un instant donné sans arrêter le serveur.
Capture de l'état de configuration
Les variables d'environnement et les fichiers de configuration sont critiques. Utilisez une méthode sécurisée pour les exporter, mais ne produisez jamais de secrets en clair dans les journaux ou les articles. Par exemple, pour capturer les variables d'environnement sans révéler les valeurs :
env | cut -d= -f1 | sort > env_keys.txt
# Sortie attendue : un fichier listant uniquement les noms de variables, par exemple DATABASE_URL, JWT_SECRET, etc.
Pour MongoDB, capturez les rôles et autorisations des utilisateurs :
mongosh admin --eval 'db.getUsers()'
# Sortie attendue : tableau de documents utilisateur (sensibles ; à manipuler avec précaution)
Stockez ces inventaires dans un emplacement sécurisé, comme un gestionnaire de mots de passe ou un système de sauvegarde chiffré.
Étape de vérification
Après l'inventaire, vérifiez que vous pouvez accéder à tous les composants avec des commandes en lecture seule. Par exemple, vérifiez que l'API répond :
curl -s http://localhost:3000/health
# Sortie attendue : {"status":"ok","version":"1.4.2"}
Vérifiez la connectivité MongoDB :
mongosh --eval 'db.runCommand({ ping: 1 })'
# Sortie attendue : { ok: 1 }
Si une vérification échoue, arrêtez-vous et résolvez le problème avant de continuer. Chemin de récupération : si vous ne pouvez pas accéder à un composant, vérifiez les informations d'identification, le réseau et l'état du service, puis relancez la vérification.
Chemin de configuration sûr
Apporter des modifications de configuration en toute sécurité signifie que vous pouvez les annuler en cas de problème. Cette section explique comment appliquer des modifications à l'API ou à son environnement avec un risque minimal.
Contrôle de version et fichiers de configuration
Toutes les modifications de configuration doivent être dans le contrôle de version. Pour acme-api, nous stockons la configuration dans un répertoire config avec des fichiers par environnement, par exemple config/production.json. Lorsque vous modifiez un paramètre, suivez ces étapes :
- Branche : créez une branche Git pour la modification.
git checkout -b update-db-timeout
- Modifier : modifiez le fichier avec la nouvelle valeur.
{
"database": {
"url": "mongodb://db.internal:27017/acme",
"options": {
"serverSelectionTimeoutMS": 5000
}
}
}
- Tester : exécutez la suite de tests localement ou dans un environnement de préproduction.
npm test
# Sortie attendue : tous les tests réussissent
- Déployer : fusionnez et déployez à l'aide de votre pipeline CI/CD.
- Vérifier : après le déploiement, exécutez le bilan de santé et les vérifications des journaux pour confirmer que le nouveau paramètre est en vigueur.
Variables d'environnement
Pour les secrets et les valeurs spécifiques au déploiement, utilisez des variables d'environnement. Pour faire tourner un mot de passe de base de données en toute sécurité :
- Générez un nouveau mot de passe à l'aide d'une méthode sécurisée :
openssl rand -base64 24
# Sortie : une chaîne aléatoire
- Mettez à jour le secret dans votre gestionnaire de secrets (par exemple, AWS Secrets Manager, HashiCorp Vault) et dans MongoDB.
- Modifiez la variable d'environnement sur le serveur API, par exemple en mettant à jour le fichier d'unité systemd ou la configuration du conteneur.
- Redémarrez le processus API :
sudo systemctl restart acme-api
- Vérifiez que l'API fonctionne et peut se connecter à la base de données :
curl -s http://localhost:3000/health
# Sortie attendue : {"status":"ok"}
- Si la vérification échoue, revenez à la valeur précédente de la variable d'environnement et redémarrez à nouveau.
Modifications du schéma de base de données
Modifier le schéma de la base de données lors d'une mise à niveau peut être risqué. Utilisez un outil de migration comme migrate-mongo ou mongo-migrate. Par exemple, pour ajouter un index :
- Créez un script de migration :
// migrations/20250301120000-add-order-index.js
module.exports = {
async up(db) {
await db.collection('orders').createIndex({ customerId: 1, createdAt: -1 });
},
async down(db) {
await db.collection('orders').dropIndex('customerId_1_createdAt_-1');
}
};
- Exécutez la migration :
migrate-mongo up
# Sortie attendue : Applied 1 migration
- Vérifiez que l'index existe :
mongosh acme --eval 'db.orders.getIndexes()'
# Vérifiez le nouvel index
- Si nécessaire, annulez avec
migrate-mongo down.
Liste de contrôle de configuration sûre
| Élément | Action | Vérification |
|---|---|---|
| Modification de configuration | Créer une branche, modifier le fichier, tester | Les tests passent en préproduction |
| Rotation des secrets | Mettre à jour le gestionnaire de secrets et la variable d'environnement, redémarrer | Le bilan de santé de l'API est OK |
| Migration de schéma | Exécuter la migration ascendante | L'index existe, les requêtes fonctionnent |
| Mise à jour des dépendances | Mettre à jour package.json, exécuter les tests, déployer | Tous les tests passent, aucune régression |
Vérification et diagnostics
La vérification ne consiste pas seulement à vérifier qu'une commande a réussi ; elle confirme que la sauvegarde ou la restauration répond à vos objectifs de récupération. Cette section détaille comment tester les sauvegardes et les restaurations sans risquer les données de production.
Vérification des sauvegardes
Après avoir effectué une sauvegarde, vous devez vérifier son intégrité et sa capacité de restauration. Pour MongoDB, une sauvegarde effectuée avec mongodump peut être vérifiée en listant les fichiers et éventuellement en la restaurant sur une instance temporaire.
- Créez une sauvegarde :
mongodump --uri="mongodb://backupUser:[email protected]:27017/acme" --archive=/backups/acme-20250301-1000.archive
# Sortie attendue : done
- Vérifiez que l'archive existe et n'est pas vide :
ls -lh /backups/acme-20250301-1000.archive
# Sortie attendue : -rw-r--r-- 1 backup backup 2.3G Mar 1 10:00 acme-20250301-1000.archive
- Pour tester la restauration sans affecter la production, lancez une instance MongoDB temporaire dans un conteneur ou un serveur séparé, restaurez l'archive et exécutez des requêtes pour garantir l'intégrité des données.
# Démarrer MongoDB temporaire (avec Docker)
docker run --name temp-mongo -d -p 27018:27017 mongo:6.0.5
# Restaurer l'archive
mongorestore --uri="mongodb://localhost:27018" --archive=/backups/acme-20250301-1000.archive
# Sortie attendue : finished restoring acme.orders (1000 documents)
# Requête pour vérifier
mongosh --port 27018 --eval 'db.orders.countDocuments()'
# Sortie attendue : 1000
# Nettoyer
docker stop temp-mongo && docker rm temp-mongo
Ce processus garantit que votre sauvegarde n'est pas corrompue et peut être restaurée.
Vérification de la restauration de l'API
Si vous devez restaurer l'API elle-même (code et configuration), suivez une validation similaire :
- Restaurez les fichiers de l'application depuis Git ou une archive de sauvegarde vers un répertoire de préproduction.
- Installez les dépendances :
npm ci
# Sortie attendue : added 123 packages
- Exécutez l'application avec la configuration restaurée dans un environnement de préproduction.
- Exécutez des tests d'intégration contre l'API de préproduction, y compris les points de terminaison critiques.
- Comparez les sorties de réponse avec les schémas attendus.
Test de récupération à un instant donné
Pour la reprise après sinistre, vous devrez peut-être restaurer à un instant précis. MongoDB prend en charge la récupération à un instant donné à l'aide de l'oplog. Testez cela en :
- Activant les sauvegardes d'oplog dans votre stratégie de sauvegarde (
mongodump --oplog). - Dans un environnement de test, restaurez la sauvegarde complète puis appliquez les entrées d'oplog jusqu'à un horodatage spécifique en utilisant
mongorestore --oplogReplay --oplogLimit. - Vérifiez que les données correspondent à l'état à cet horodatage en vérifiant un enregistrement ou un nombre connu.
Commandes de diagnostic et sorties attendues
Lorsque la vérification échoue, vous devez diagnostiquer. Les commandes courantes incluent :
- Consulter les journaux de l'API :
tail -f /var/log/acme-api.log - Vérifier l'état du processus :
systemctl status acme-api - Vérifier la connectivité de la base de données :
mongosh --eval 'db.runCommand({ ping: 1 })' - Vérifier l'espace disque :
df -h
Si l'API ne peut pas se connecter à la base de données, les journaux peuvent afficher MongooseServerSelectionError: connect ECONNREFUSED. Vérifiez si MongoDB est en cours d'exécution (systemctl status mongod), et sinon, démarrez-le.
Modes de défaillance et récupération
Anticiper les modes de défaillance est essentiel. Cette section décrit les défaillances courantes et les étapes de récupération.
Échec de la sauvegarde
Une sauvegarde peut échouer en raison d'un espace disque insuffisant, d'erreurs de permission ou d'une interruption du réseau.
- Symptôme :
mongodumpse termine avec l'erreurE: not enough free space. - Récupération : libérez de l'espace ou spécifiez une destination de sauvegarde différente avec plus d'espace. Ensuite, réexécutez.
- Prévention : surveillez l'utilisation du disque et définissez des alertes.
Échec de la restauration
La restauration peut échouer si la sauvegarde est corrompue, s'il y a une incompatibilité de version ou un manque de mémoire.
- Symptôme : erreur
mongorestoreFailed: restore error: error applying oplog. - Récupération : vérifiez l'intégrité de la sauvegarde avec des sommes de contrôle si disponibles. Essayez de restaurer sans oplog. En cas d'incompatibilité de version, assurez-vous que la version cible de MongoDB est compatible.
- Solution de repli : si la restauration échoue complètement, utilisez une sauvegarde précédente connue comme bonne.
Indisponibilité de l'API pendant la récupération
Si l'API est en panne, la restauration peut nécessiter de repartir de zéro.
- Symptôme : l'API renvoie 503 Service Unavailable.
- Récupération : déployez la dernière version connue comme bonne depuis Git, restaurez la base de données, puis effectuez un bilan de santé.
- Plan de repli : gardez les artefacts de la version précédente prêts pour un repli rapide.
Corruption des données
La corruption des données peut survenir en raison d'erreurs de disque ou de bogues.
- Symptôme : les requêtes renvoient des résultats inattendus ou des erreurs comme
Unrecognized pipeline stage name: '$sort'. - Récupération : restaurez à partir de la sauvegarde vérifiée la plus récente, puis appliquez les sauvegardes incrémentielles ou l'oplog pour minimiser la perte de données.
- Prévention : activez la réplication MongoDB pour la redondance et effectuez des sauvegardes fréquentes.
Réalisation d'un exercice d'incendie
Testez régulièrement votre processus de sauvegarde et de restauration. Planifiez un exercice d'incendie trimestriel où vous simulez une défaillance totale et récupérez dans un environnement de préproduction. Documentez le temps nécessaire et les problèmes rencontrés.
Liste de contrôle opérationnelle
Utilisez cette liste de contrôle avant et après toute opération de sauvegarde ou de restauration pour garantir la cohérence et la sécurité.
Liste de contrôle pré-opérationnelle
- [ ] Confirmer que l'inventaire de l'environnement est à jour (versions, configurations).
- [ ] Vérifier qu'il y a suffisamment d'espace disque pour la sauvegarde.
- [ ] S'assurer de disposer des informations d'identification nécessaires (stockées en toute sécurité, pas en clair).
- [ ] Informer les parties prenantes si une indisponibilité est prévue.
- [ ] Effectuer un bilan de santé en lecture seule sur l'API et la base de données.
Liste de contrôle de sauvegarde
- [ ] Exécuter la commande de sauvegarde avec les bons paramètres.
- [ ] Enregistrer l'emplacement, la taille et l'horodatage du fichier de sauvegarde.
- [ ] Vérifier l'intégrité du fichier de sauvegarde (par exemple, sortie de succès de
mongodump). - [ ] Copier la sauvegarde vers un emplacement séparé (hors site ou stockage cloud).
- [ ] Consigner la sauvegarde dans un journal des opérations.
Liste de contrôle de restauration
- [ ] Identifier la sauvegarde à restaurer et la raison.
- [ ] Si possible, restaurer d'abord dans un environnement de préproduction.
- [ ] Effectuer la restauration à l'aide des commandes appropriées.
- [ ] Vérifier la cohérence des données (nombre de documents, requêtes d'échantillonnage).
- [ ] Exécuter des tests d'intégration de l'API contre la base de données restaurée.
- [ ] Basculer le trafic vers l'API restaurée le cas échéant.
- [ ] Surveiller les erreurs après la restauration.
Revue post-opérationnelle
Après toute opération, passez en revue :
- Qu'est-ce qui a bien fonctionné ?
- Qu'est-ce qui pourrait être amélioré ?
- Y a-t-il eu des problèmes inattendus ?
- Documentez les leçons apprises et mettez à jour les procédures.
Conclusion
La sauvegarde et la restauration d'une API REST ne sont efficaces que si chaque étape est versionnée, observable et réversible lorsque c'est possible. Copier des commandes sans comprendre les prérequis et les sorties attendues n'est pas une procédure opérationnelle ; c'est un pari. En suivant les pratiques décrites dans cet article—de l'inventaire méticuleux de l'environnement à la vérification approfondie et aux tests de récupération—vous pouvez construire un système de sauvegarde et de restauration robuste qui minimise les temps d'arrêt et les pertes de données.
Comme prochaine étape, choisissez une vérification à faible risque de cet article, comme exécuter un bilan de santé en lecture seule sur votre API ou vérifier une sauvegarde de base de données récente. Enregistrez l'état actuel, exécutez la commande documentée, comparez le résultat avec le signal attendu et examinez les dépendances comme Express, Node.js et MongoDB. Au fil du temps, étendez vos vérifications pour couvrir des exercices de restauration complets. Un flux de travail technique fiable rend les défaillances visibles, protège les valeurs sensibles, limite les modifications à la ressource prévue et définit la vérification de la récupération avant qu'un incident ne vous oblige à décider.