🎯 Objectif : Savoir déployer MongoDB en production avec schema validation, pymongo, Atlas et des stratégies de backup fiables. ⏱️ Durée estimée : 55 minutes | Niveau : Avancé
De la base de dev au déploiement production
Tu sais faire du CRUD, construire des pipelines d’agrégation et poser des index. En production, ça ne suffit pas. Tu as besoin de contraintes sur tes données (schema validation), d’un driver applicatif (pymongo), d’une plateforme managée (Atlas) et de sauvegardes automatisées (mongodump). C’est la différence entre un POC qui tourne sur ta machine et un service qui encaisse du trafic réel.
Ce chapitre couvre les quatre piliers d’un déploiement MongoDB solide : la validation, la modélisation, l’intégration Python et les opérations (backup/restore).
🔥 Cas réel : Une équipe a déployé un MongoDB sans schema validation pour “aller vite”. En 6 mois, la collection users contenait des documents avec email en string, en array, en null, et même des champs emial (typo). Le pipeline de données en aval cassait régulièrement. L’ajout de schema validation + un script de nettoyage a pris 3 jours. Le refaire dès le départ aurait pris 30 minutes.
Schema validation : la flexibilité sous contrôle
MongoDB est schemaless par défaut, mais “schemaless” ne veut pas dire “n’importe quoi”. La schema validation via JSON Schema te permet de définir des règles que les documents doivent respecter à l’insertion et à la mise à jour — sans perdre la flexibilité de MongoDB.
L’idée est de poser un filet de sécurité : les champs critiques sont typés et obligatoires, le reste peut varier librement. C’est le meilleur des deux mondes.
// Collection avec validation stricte sur les champs critiques
db.createCollection("users", {
validator: {
$jsonSchema: {
bsonType: "object",
required: ["name", "email", "role"],
properties: {
name: { bsonType: "string", minLength: 2, maxLength: 100 },
email: {
bsonType: "string",
pattern: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
},
role: { bsonType: "string", enum: ["admin", "editor", "viewer"] },
age: { bsonType: "int", minimum: 0, maximum: 150 }
}
}
},
validationLevel: "strict", // strict ou moderate
validationAction: "error" // error ou warn
})
MongoDB rejette tout document qui enfreint les règles : champ manquant, mauvais type, valeur hors enum, regex non matchée. Le message d’erreur précise quel champ pose problème.
💡 Tip DevOps : Utilise validationLevel: "moderate" quand tu ajoutes une validation sur une collection existante. Ce mode ne valide que les nouveaux documents et les mises à jour, sans bloquer les anciens documents non-conformes. Ça te laisse le temps de nettoyer progressivement. Tu peux modifier la validation d’une collection existante avec db.runCommand({ collMod: "users", validator: { ... } }).
Modélisation : embedded vs references
Le choix entre embedded (imbriqué) et references (normalisé) est la décision de modélisation la plus impactante en MongoDB. Elle conditionne les performances, la complexité et la maintenabilité de ton application.
Embedded : les données liées sont dans le même document. Une seule lecture, atomicité garantie, performances de lecture excellentes. Mais duplication possible et limite de 16 MB par document.
References : les données liées sont dans des collections séparées, reliées par un ID. Pas de duplication, données indépendantes et requêtables, mais nécessite un $lookup (jointure) ou plusieurs requêtes.
// Embedded — un utilisateur avec ses adresses intégrées
{
name: "Alice",
email: "alice@example.com",
addresses: [
{ type: "home", street: "Rue du Lac 10", city: "Lausanne" },
{ type: "work", street: "Av. de la Gare 5", city: "Genève" }
]
}
// References — données séparées, reliées par ID
// Collection users : { _id: 1, name: "Alice", email: "alice@example.com" }
// Collection addresses : { user_id: 1, type: "home", street: "Rue du Lac 10" }
🧠 À retenir : La règle de décision est simple. 1-to-1 et 1-to-few (< 100 éléments) → embedded. 1-to-many (100+) → references. Many-to-many → toujours references. Si les données sont toujours lues ensemble → embedded. Si elles sont requêtées indépendamment ou partagées entre documents → references.
Intégration Python avec pymongo
pymongo est le driver officiel MongoDB pour Python. C’est ce que tu utilises dans tes applications FastAPI, Django, scripts d’automatisation — tout ce qui est côté applicatif.
L’API pymongo suit exactement la même logique que le shell mongosh : les mêmes noms de méthodes, les mêmes opérateurs, les mêmes structures. Si tu sais écrire une requête dans le shell, tu sais l’écrire en pymongo.
from pymongo import MongoClient
from pymongo.errors import DuplicateKeyError, ConnectionFailure
# Connexion (locale ou Atlas)
client = MongoClient("mongodb://admin:secret123@localhost:27017/")
db = client["myapp"]
# CRUD — même syntaxe que mongosh, en Python
db.users.insert_one({"name": "Alice", "email": "alice@example.com", "role": "admin"})
user = db.users.find_one({"name": "Alice"})
db.users.update_one({"name": "Alice"}, {"$set": {"role": "superadmin"}})
db.users.delete_one({"name": "Alice"})
# Gestion des erreurs — toujours wrapper les opérations critiques
try:
db.users.insert_one({"_id": "unique-id", "name": "Test"})
db.users.insert_one({"_id": "unique-id", "name": "Doublon"})
except DuplicateKeyError:
print("Document avec cet ID existe déjà")
⚠️ Attention : find() en pymongo retourne un curseur, pas une liste. Le curseur est lazy — il ne charge les documents que quand tu itères dessus. C’est performant pour les gros résultats, mais si tu veux tout en mémoire, utilise list(db.collection.find(...)). Attention à la RAM sur les grosses collections.
Aggregation et script de monitoring complet
L’agrégation en pymongo utilise exactement la même syntaxe de pipeline que mongosh. Voici un script réaliste de monitoring qui illustre l’ensemble des opérations :
from pymongo import MongoClient
from datetime import datetime
import random
client = MongoClient("mongodb://admin:secret123@localhost:27017/")
db = client["monitoring"]
# Simuler des métriques pour 5 serveurs
servers = ["web-01", "web-02", "db-01", "cache-01", "worker-01"]
for server in servers:
db.metrics.insert_one({
"hostname": server,
"timestamp": datetime.utcnow(),
"cpu_percent": round(random.uniform(5, 95), 1),
"ram_percent": round(random.uniform(20, 90), 1),
})
# Aggregation : moyennes par serveur, triées par CPU
pipeline = [
{"$group": {
"_id": "$hostname",
"avg_cpu": {"$avg": "$cpu_percent"},
"avg_ram": {"$avg": "$ram_percent"}
}},
{"$sort": {"avg_cpu": -1}}
]
for doc in db.metrics.aggregate(pipeline):
print(f"{doc['_id']}: CPU {doc['avg_cpu']:.1f}% | RAM {doc['avg_ram']:.1f}%")
# TTL index — auto-suppression après 30 jours
db.metrics.create_index("timestamp", expireAfterSeconds=30*24*3600)
💡 Tip DevOps : Pour la connexion Atlas depuis Python, utilise le format SRV : MongoClient("mongodb+srv://user:pass@cluster0.abc123.mongodb.net/"). Le driver résout automatiquement les nœuds du replica set. Ajoute retryWrites=true&w=majority dans l’URI pour la résilience en production.
Backup et restauration : le filet de sécurité
Pas de production sans backup. MongoDB fournit deux paires d’outils : mongodump/mongorestore (format binaire BSON, rapide, complet) et mongoexport/mongoimport (format JSON/CSV, lisible, pratique pour les échanges).
En production, tu utilises mongodump pour les sauvegardes automatisées et mongoexport pour les exports ponctuels ou les migrations.
# Sauvegarder toute la base "myapp" (binaire BSON)
docker exec -it mongodb mongodump \
--authenticationDatabase admin \
-u admin -p secret123 \
-d myapp --out /tmp/backup
# Restaurer (avec --drop pour écraser les données existantes)
docker exec -it mongodb mongorestore \
--authenticationDatabase admin \
-u admin -p secret123 \
--drop /tmp/backup
# Export lisible en JSON (pour debug ou échange)
docker exec -it mongodb mongoexport \
--authenticationDatabase admin \
-u admin -p secret123 \
-d myapp -c zips --out /tmp/zips.json
Script de backup automatisé pour la production
Voici un script battle-tested qui gère le dump, la compression, la rétention et optionnellement l’envoi vers S3 :
#!/bin/bash
# backup-mongodb.sh — cron quotidien
DATE=$(date +%Y-%m-%d_%H-%M)
BACKUP_DIR="/backups/mongodb/$DATE"
RETENTION_DAYS=30
mongodump --uri="mongodb://admin:secret123@localhost:27017" \
--authenticationDatabase admin --out "$BACKUP_DIR"
tar -czf "$BACKUP_DIR.tar.gz" "$BACKUP_DIR" && rm -rf "$BACKUP_DIR"
find /backups/mongodb/ -name "*.tar.gz" -mtime +$RETENTION_DAYS -delete
# Optionnel : aws s3 cp "$BACKUP_DIR.tar.gz" s3://my-backups/mongodb/
echo "✅ Backup terminé : $BACKUP_DIR.tar.gz"
# Cron : backup quotidien à 3h du matin
0 3 * * * /opt/scripts/backup-mongodb.sh >> /var/log/mongodb-backup.log 2>&1
🔥 Cas réel : Un client a perdu 48h de données après un drop accidentel en production. Le backup cron tournait mais écrivait sur le même disque que MongoDB — quand le disque a saturé, plus de backup ET plus de base. Leçon : stocke toujours tes backups sur un volume séparé ou en remote (S3, GCS, autre serveur). Teste régulièrement la restauration — un backup non testé est un backup qui n’existe pas.
Bonnes pratiques et pièges en production
Les fondamentaux :
- Schema validation dès le jour 1 — même minimale (
required+ types des champs critiques). Ajouter la validation après 6 mois de données anarchiques est douloureux - Embedded par défaut, references quand c’est justifié — l’embedded est plus performant en lecture et plus simple. Ne normalise que quand les données sont partagées ou volumineuses
- Gestion d’erreurs systématique en pymongo — catch
DuplicateKeyError,ConnectionFailure,OperationFailure. Uninsert_one()non wrappé qui échoue silencieusement peut corrompre ta logique métier - Backup automatisé + testé — le script ne suffit pas, vérifie périodiquement que le restore fonctionne
Les pièges classiques :
- ⚠️ Pas de validation → données incohérentes qui cassent les pipelines en aval
- ⚠️ Tout en embedded sur des relations many-to-many → duplication massive et documents de 16 MB
- ⚠️ Connexion pymongo sans timeout → ton app bloque indéfiniment si MongoDB est down. Configure
serverSelectionTimeoutMSetconnectTimeoutMS - ⚠️ Backups sur le même disque → quand le disque sature, tu perds tout en même temps
🧠 À retenir : MongoDB Atlas gère automatiquement la réplication, les backups et le monitoring. Pour un projet en production sans équipe DBA dédiée, c’est souvent le choix le plus pragmatique. Le tier gratuit (M0, 512 MB) suffit pour les petits projets et le prototypage. Pour la production sérieuse, les plans payants ajoutent les backups continus, le scaling automatique et le support.
Résumé
La schema validation pose un filet de sécurité sur tes données sans sacrifier la flexibilité de MongoDB. La modélisation embedded vs references est un choix de design qui impacte directement les performances — embedded par défaut, references quand c’est justifié. pymongo t’intègre MongoDB dans tes applications Python avec la même API que le shell. Et les backups automatisés avec mongodump + cron + stockage distant sont non-négociables en production.
Avec les quatre chapitres de cette série, tu as couvert l’essentiel : du CRUD aux pipelines d’agrégation, des index à la production. La suite, c’est de la pratique — monte un vrai projet, encaisse du vrai trafic, et mesure.
➡️ La suite : On a fait le tour de MongoDB ! Direction les autres modules du cursus.
À toi de jouer
Exercice 1 — Schema Validation stricte
Crée une collection deployments avec validation JSON Schema : app_name (string, requis), version (string, pattern semver ^\d+\.\d+\.\d+$), replicas (integer, min 1, max 50), environment (enum : dev/staging/prod). Teste avec des documents valides et invalides.
Exercice 2 — Script pymongo complet Écris un script Python qui se connecte à MongoDB, insère 100 documents de métriques aléatoires, exécute une aggregation par serveur (avg CPU, max RAM), et exporte le résultat en JSON. Gère les erreurs de connexion avec timeout et retry.
Exercice 3 — Backup et restauration
Configure un backup automatique : script bash avec mongodump compressé + timestamp, stockage dans /backups/mongodb/, rétention de 7 jours. Teste la restauration avec mongorestore --drop sur une base de test et vérifie l’intégrité via un count_documents().
Contenu réservé aux abonnés
Ce chapitre fait partie de la formation complète. Abonne-toi pour débloquer tous les contenus.
Débloquer pour 29 CHF/moisLe chapitre 1 de chaque formation est gratuit.
Série pas encore débloquée
Termine la série prérequise d'abord pour accéder à ce contenu.
Aller à la série prérequiseSur cette page
Articles liés
Agrégation et indexation
Maîtrise l'aggregation pipeline MongoDB ($match, $group, $sort, $lookup) et optimise tes requêtes avec les index (simple, composé, texte).
MongoDB : les bases du NoSQL
Comprends la différence NoSQL vs SQL, les concepts fondamentaux de MongoDB (documents, collections, bases), et installe MongoDB avec Docker.
CRUD et requêtes MongoDB
Maîtrise les opérations CRUD avec mongosh, les filtres, projections, opérateurs de comparaison, les types BSON et construis une API de monitoring.