Chapitre 319 minIntermédiaire
Installer MongoDB : Docker, Atlas, mongosh et Compass
Par Josselyn C., prof de BTS SIO. Mis à jour le .
À la fin de ce chapitre, tu sauras
- lancer MongoDB dans Docker, sur ton système ou avec Atlas ;
- lire et écrire une chaîne de connexion, et la garder secrète ;
- te repérer dans mongosh et dans Compass ;
- charger le jeu de données d'AppliFrais.
3 exercices corrigés1 schéma
Pour travailler avec MongoDB, il te faut un serveur (mongod), qui stocke les données, et un client pour lui parler : le shell mongosh, l'interface graphique Compass, ou ton application Node.js. Le serveur peut tourner dans un conteneur Docker sur ton poste, être installé directement sur ton système, ou être hébergé gratuitement dans le cloud avec MongoDB Atlas. Ce chapitre installe les trois options, explique la chaîne de connexion et charge le jeu de données d'AppliFrais qui sert dans tout le cours.
Les pièces du puzzle
| Composant | Rôle | Où l'obtenir |
|---|---|---|
mongod | Le serveur : il stocke les données et exécute les requêtes | Image Docker mongo:9, installeur de MongoDB Community, ou Atlas |
mongosh | Le shell : tu tapes des commandes JavaScript, il affiche les résultats | Inclus dans l'image Docker et dans Compass ; sinon à installer à part |
| Compass | L'interface graphique : parcourir, filtrer, modifier, voir les index et les plans d'exécution | Téléchargement gratuit sur le site de MongoDB |
| Database Tools | mongodump, mongorestore, mongoimport, mongoexport | Téléchargement à part (version 100.x) ; inclus dans l'image Docker |
| Driver Node.js | La bibliothèque mongodb (et Mongoose par-dessus) | npm install mongodb ou npm install mongoose |
Option 1 : MongoDB dans Docker (recommandé)
Docker lance MongoDB dans un conteneur isolé, sans rien installer sur ton système, avec la même version pour toute l'équipe. Si Docker est nouveau pour toi, le cours Docker explique images, conteneurs et volumes. Crée ce fichier compose.yaml à la racine de ton projet :
services:
mongo:
image: mongo:9
restart: unless-stopped
ports:
- "127.0.0.1:27017:27017" # accessible depuis ton poste uniquement
environment:
MONGO_INITDB_ROOT_USERNAME: ${MONGO_ROOT_USER}
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_ROOT_PASSWORD}
volumes:
- mongo-data:/data/db # les données survivent à la suppression du conteneur
volumes:
mongo-data:
Et, à côté, un fichier .env que Docker Compose lit automatiquement (et que Git ignore, voir plus bas) :
MONGO_ROOT_USER=admin
MONGO_ROOT_PASSWORD=change-moi-par-un-vrai-mot-de-passe
Puis, dans un terminal :
docker compose up -d # télécharge l'image et démarre le conteneur
docker compose ps # le service mongo doit être « running »
docker compose exec mongo mongosh -u admin -p --authenticationDatabase admin
La dernière commande ouvre mongosh à l'intérieur du conteneur ; elle demande le mot de passe. Au premier démarrage, l'image crée le compte administrateur décrit par les deux variables MONGO_INITDB_ROOT_* et active l'authentification.
Trois choix de ce fichier méritent une explication :
127.0.0.1:27017:27017publie le port de MongoDB sur l'adresse locale seulement. Écrire27017:27017l'ouvrirait sur toutes les interfaces de ta machine, donc au réseau de ton école ou de ton alternance. Des milliers de bases MongoDB exposées sur Internet sans mot de passe ont été vidées et rançonnées depuis 2017 : on y revient au chapitre 13.- Le volume nommé
mongo-datagarde les données hors du conteneur.docker compose downarrête et supprime le conteneur, mais garde le volume ;docker compose down -vsupprime aussi le volume, donc toutes tes données. - Les identifiants viennent du
.env, pas du fichier versionné. Attention : ces variables ne servent qu'à la première initialisation. Si le volume existe déjà, changer le mot de passe dans le.envne change rien.
Option 2 : installer MongoDB sur ton système
Si tu ne peux pas utiliser Docker, installe MongoDB Community Server directement :
- Windows : télécharge l'installeur MSI sur le site de MongoDB (Download Center, édition Community). Il installe
mongodcomme service Windows, qui démarre avec le système, et propose d'installer Compass. - macOS : avec Homebrew,
brew tap mongodb/brew, puisbrew install mongodb-communityetbrew services start mongodb-community. - Linux (Debian, Ubuntu) : ajoute le dépôt APT officiel de MongoDB (la procédure, avec sa clé de signature, est dans la documentation d'installation), puis
sudo apt install mongodb-orgetsudo systemctl enable --now mongod.
mongosh et les Database Tools s'installent à part sur Windows ; Homebrew (brew install mongosh) et le paquet mongodb-org les fournissent sur macOS et Linux. Une installation native démarre sans authentification et n'écoute que sur 127.0.0.1 : c'est acceptable sur ton poste, jamais sur un serveur (chapitre 13).
Option 3 : MongoDB Atlas, gratuit dans le cloud
Atlas est le service de MongoDB Inc. qui héberge des bases pour toi, sur AWS, Google Cloud ou Azure. Son offre Free (longtemps appelée M0) est gratuite sans limite de durée et suffit pour un projet de BTS :
| Caractéristique de l'offre Free | Valeur |
|---|---|
| Stockage | 0,5 Go (données et index) |
| Version | MongoDB 8.0, mise à jour par Atlas |
| Architecture | Un groupe de 3 serveurs répliqués (replica set) : les transactions fonctionnent |
| Débit | 100 opérations par seconde, 500 connexions simultanées |
| Nombre | Un cluster gratuit par projet Atlas |
| Inactivité | Mise en pause après 30 jours sans aucune connexion |
| Restrictions | Pas de JavaScript côté serveur ($where), sauvegarde quotidienne si tu l'actives, 4 copies gardées |
Pour créer ta base :
- Crée un compte sur le site d'Atlas, puis un projet (par exemple
appli-frais). - Crée un cluster Free, dans une région européenne (Paris ou Francfort) : tes données restent dans l'Union européenne, un point que le RGPD te demandera de justifier.
- Dans Database Access, crée un utilisateur de base dédié à ton application, avec un mot de passe généré, et le rôle Read and write to any database (on le restreindra au chapitre 13).
- Dans Network Access, ajoute ton adresse IP. N'ajoute
0.0.0.0/0(« tout Internet ») que si ton hébergeur n'a pas d'adresse fixe, et jamais sans mot de passe fort. - Bouton Connect : Atlas affiche ta chaîne de connexion, de la forme
mongodb+srv://appli:<mot-de-passe>@cluster0.xxxxx.mongodb.net/.
La chaîne de connexion
Tous les clients (mongosh, Compass, ton API, mongodump) se connectent avec une chaîne de connexion, une URI au format standard :
mongodb://utilisateur:motdepasse@hote:27017/appli_frais?authSource=admin
└──┬───┘ └──────────┬────────┘ └───┬────┘ └────┬────┘ └──────┬───────┘
schéma identifiants serveur:port base options
| Élément | Exemple | Remarque |
|---|---|---|
| Schéma | mongodb:// ou mongodb+srv:// | +srv (Atlas) trouve la liste des serveurs dans le DNS et active TLS |
| Identifiants | appli:S3cr%40t | Les caractères spéciaux du mot de passe sont encodés : @ devient %40, : devient %3A, / devient %2F |
| Hôte et port | localhost:27017 | Plusieurs hôtes séparés par des virgules pour un replica set |
| Base | /appli_frais | La base utilisée par défaut par le client |
| Options | ?authSource=admin&directConnection=true | authSource : la base où est enregistré le compte ; directConnection=true : se connecter à ce serveur précis, utile pour un serveur seul en replica set local |
La chaîne de connexion contient un mot de passe : c'est un secret. Elle va dans un fichier .env, jamais dans le code ni dans Git :
# .env (dans .gitignore)
MONGODB_URI=mongodb://appli:mot-de-passe-de-l-appli@localhost:27017/appli_frais
Le compte appli, propre à l'application et créé dans la base appli_frais, est mis en place au chapitre 13 ; en attendant, tu peux utiliser le compte admin avec ?authSource=admin.
Et tu fournis à ton équipe un .env.example sans valeur réelle. Le cours Git explique quoi faire si un secret part quand même dans un commit, et le cours de sécurité comment gérer les secrets en production.
Premiers pas dans mongosh
mongosh est un shell JavaScript : tu y tapes des appels de méthodes sur l'objet db, qui représente la base courante. Lance-le avec ta chaîne de connexion :
mongosh "mongodb://admin:mot-de-passe@localhost:27017/appli_frais?authSource=admin"
Les commandes de navigation :
| Commande | Effet |
|---|---|
show dbs | Liste les bases qui contiennent des données, avec leur taille |
use appli_frais | Bascule sur la base appli_frais (créée au premier document inséré) |
db | Affiche le nom de la base courante |
show collections | Liste les collections de la base courante |
db.fiches.findOne() | Affiche un document de la collection fiches |
load('jeu-de-donnees.js') | Exécute un fichier JavaScript dans la session |
help, db.fiches.help() | L'aide générale, l'aide d'une collection |
cls | Efface l'écran |
.exit ou Ctrl+D | Quitte mongosh |
mongosh complète les noms avec la touche Tab, garde l'historique des commandes (flèche du haut) et accepte les commandes sur plusieurs lignes : tant qu'une accolade ou une parenthèse reste ouverte, il attend la suite.
Compass, l'interface graphique
MongoDB Compass est le pendant de phpMyAdmin ou de MySQL Workbench. Colle ta chaîne de connexion dans l'écran d'accueil, puis :
- l'onglet Documents affiche une collection, en liste, en JSON ou en tableau, avec une barre de filtre qui accepte la syntaxe des requêtes (
{ etat: 'CL' }) ; - l'onglet Aggregations construit un pipeline d'agrégation étape par étape, en montrant le résultat de chaque étape (chapitre 8) ;
- l'onglet Schema analyse un échantillon de documents et montre les champs, leurs types et leur fréquence : idéal pour repérer un champ mal orthographié ;
- l'onglet Indexes liste les index ; l'onglet Explain Plan montre si une requête les utilise (chapitre 7) ;
- un
mongoshintégré s'ouvre en bas de la fenêtre.
L'extension MongoDB for VS Code offre l'essentiel de ces fonctions dans ton éditeur, avec des fichiers de requêtes (playgrounds) que tu exécutes et versionnes.
Charger le jeu de données d'AppliFrais
Tous les exemples du cours utilisent la même base appli_frais : 5 utilisateurs (4 visiteurs médicaux et une comptable) et 9 fiches de frais d'août à octobre 2026. Enregistre ce script sous le nom jeu-de-donnees.js :
// Jeu de données d'AppliFrais : mongosh "<chaîne de connexion>" jeu-de-donnees.js
db = db.getSiblingDB('appli_frais');
db.visiteurs.drop();
db.fiches.drop();
db.visiteurs.insertMany([
{ _id: ObjectId('6a0000000000000000000001'), matricule: 'a131', nom: 'Martin', prenom: 'Lucas',
email: 'lucas.martin@gsb.example', role: 'visiteur', region: 'Rhône',
dateEmbauche: ISODate('2021-09-01') },
{ _id: ObjectId('6a0000000000000000000002'), matricule: 'b204', nom: 'Benali', prenom: 'Inès',
email: 'ines.benali@gsb.example', role: 'visiteur', region: 'Isère',
dateEmbauche: ISODate('2023-03-13') },
{ _id: ObjectId('6a0000000000000000000003'), matricule: 'c087', nom: 'Girard', prenom: 'Thomas',
email: 'thomas.girard@gsb.example', role: 'visiteur', region: 'Rhône',
dateEmbauche: ISODate('2019-01-07') },
{ _id: ObjectId('6a0000000000000000000004'), matricule: 'd312', nom: 'Roux', prenom: 'Camille',
email: 'camille.roux@gsb.example', role: 'visiteur', region: 'Savoie',
dateEmbauche: ISODate('2026-09-01') },
{ _id: ObjectId('6a0000000000000000000005'), matricule: 'k002', nom: 'Lambert', prenom: 'Sophie',
email: 'sophie.lambert@gsb.example', role: 'comptable',
dateEmbauche: ISODate('2015-06-01') }
]);
const martin = ObjectId('6a0000000000000000000001');
const benali = ObjectId('6a0000000000000000000002');
const girard = ObjectId('6a0000000000000000000003');
const roux = ObjectId('6a0000000000000000000004');
// Les tarifs des frais forfaitisés, recopiés dans chaque ligne au moment de la saisie
const ETP = 110, KM = 0.62, NUI = 80, REP = 25;
const forfait = (code, quantite, montantUnitaire) => ({ code, quantite, montantUnitaire });
db.fiches.insertMany([
{ visiteur: martin, mois: '2026-08', etat: 'RB', dateModif: ISODate('2026-09-20T10:00:00Z'),
lignesForfait: [forfait('ETP', 2, ETP), forfait('KM', 310, KM), forfait('REP', 4, REP)],
fraisHorsForfait: [], montantValide: 512.2 },
{ visiteur: martin, mois: '2026-09', etat: 'VA', dateModif: ISODate('2026-10-12T09:30:00Z'),
lignesForfait: [forfait('ETP', 3, ETP), forfait('KM', 420, KM), forfait('NUI', 2, NUI), forfait('REP', 5, REP)],
fraisHorsForfait: [{ date: ISODate('2026-09-14'), libelle: 'Repas client à Lyon', montant: 23.5 }],
montantValide: 898.9 },
{ visiteur: martin, mois: '2026-10', etat: 'CR', dateModif: ISODate('2026-10-28T16:42:05Z'),
lignesForfait: [forfait('ETP', 1, ETP), forfait('KM', 150, KM)],
fraisHorsForfait: [], montantValide: null },
{ visiteur: benali, mois: '2026-09', etat: 'CL', dateModif: ISODate('2026-10-01T08:00:00Z'),
lignesForfait: [forfait('ETP', 4, ETP), forfait('KM', 640, KM), forfait('NUI', 3, NUI), forfait('REP', 6, REP)],
fraisHorsForfait: [
{ date: ISODate('2026-09-08'), libelle: 'Parking gare de Grenoble', montant: 18 },
{ date: ISODate('2026-09-22'), libelle: 'Congrès de cardiologie', montant: 150 }
], montantValide: null },
{ visiteur: benali, mois: '2026-10', etat: 'CR', dateModif: ISODate('2026-10-27T18:10:00Z'),
lignesForfait: [forfait('KM', 95, KM), forfait('REP', 2, REP)],
fraisHorsForfait: [], montantValide: null },
{ visiteur: girard, mois: '2026-08', etat: 'VA', dateModif: ISODate('2026-09-15T14:00:00Z'),
lignesForfait: [forfait('ETP', 1, ETP), forfait('KM', 120, KM)],
fraisHorsForfait: [], montantValide: 184.4 },
{ visiteur: girard, mois: '2026-09', etat: 'MP', dateModif: ISODate('2026-10-20T11:00:00Z'),
lignesForfait: [forfait('ETP', 2, ETP), forfait('KM', 250, KM), forfait('NUI', 1, NUI), forfait('REP', 3, REP)],
fraisHorsForfait: [{ date: ISODate('2026-09-03'), libelle: 'Taxi Lyon Part-Dieu', montant: 32.4 }],
montantValide: 562.4 },
{ visiteur: girard, mois: '2026-10', etat: 'CL', dateModif: ISODate('2026-11-01T09:00:00Z'),
lignesForfait: [forfait('ETP', 3, ETP), forfait('KM', 380, KM), forfait('REP', 4, REP)],
fraisHorsForfait: [], montantValide: null },
{ visiteur: roux, mois: '2026-10', etat: 'CR', dateModif: ISODate('2026-10-05T07:45:00Z'),
lignesForfait: [], fraisHorsForfait: [], montantValide: null }
]);
print(`${db.visiteurs.countDocuments()} visiteurs, ${db.fiches.countDocuments()} fiches`);
Exécute-le depuis ton terminal, avec Docker :
docker compose cp jeu-de-donnees.js mongo:/tmp/jeu-de-donnees.js
docker compose exec mongo mongosh -u admin -p --authenticationDatabase admin /tmp/jeu-de-donnees.js
ou avec un mongosh installé sur ton poste, quel que soit le serveur :
mongosh "<ta chaîne de connexion>" jeu-de-donnees.js
5 visiteurs, 9 fiches
Le script commence par supprimer les deux collections (drop) : relance-le chaque fois que tu veux repartir d'une base propre, par exemple après les exercices de modification du chapitre 4. Les _id des visiteurs sont fixés ; ceux des fiches seront différents chez toi.
Exercices
Exercice 1 sur 3 Lire une chaîne de connexion Réussi À revoir
Pour chaque chaîne, donne le serveur, le port, le compte, la base où le compte est enregistré et la base utilisée par défaut. Repère l'erreur de la dernière.
mongodb://appli:Fr4is@localhost:27017/appli_frais?authSource=adminmongodb+srv://appli:Fr4is@cluster0.ab12c.mongodb.net/appli_fraismongodb://appli:P@ss:2026@localhost:27017/appli_frais
Voir la réponseMasquer la réponse de l'exercice 1
- Serveur
localhost, port27017, compteappli, enregistré dans la baseadmin(authSource), base par défautappli_frais. - Un cluster Atlas :
+srvfait chercher la liste des serveurs et leur port dans le DNS decluster0.ab12c.mongodb.netet active TLS. Compteappli, base par défautappli_frais. SansauthSource, une chaîne+srvd'Atlas authentifie dansadmin, là où Atlas crée ses utilisateurs. - Le mot de passe
P@ss:2026contient@et:, qui ont un sens dans l'URI : le client coupe la chaîne au mauvais endroit et la connexion échoue. Il faut l'encoder :mongodb://appli:P%40ss%3A2026@localhost:27017/appli_frais. SansauthSource, le compte est cherché dans la baseappli_frais.
Tu avais trouvé ?
Exercice 2 sur 3 Diagnostiquer un démarrage Réussi À revoir
Un étudiant lance docker compose up -d avec ce fichier, puis l'API de son voisin, sur un autre poste de la salle, se connecte à sa base sans mot de passe. Trouve les deux erreurs et corrige le fichier.
services:
mongo:
image: mongo:9
ports:
- "27017:27017"
Voir la réponseMasquer la réponse de l'exercice 2
- Le port est publié sur toutes les interfaces (
27017:27017) : n'importe quel poste du réseau atteint la base. Il faut"127.0.0.1:27017:27017". - Aucune authentification : sans les variables
MONGO_INITDB_ROOT_USERNAMEetMONGO_INITDB_ROOT_PASSWORD, l'image démarre MongoDB sans contrôle d'accès.
Il manque aussi un volume : sans lui, les données vivent dans le conteneur et disparaissent avec lui.
services:
mongo:
image: mongo:9
restart: unless-stopped
ports:
- "127.0.0.1:27017:27017"
environment:
MONGO_INITDB_ROOT_USERNAME: ${MONGO_ROOT_USER}
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_ROOT_PASSWORD}
volumes:
- mongo-data:/data/db
volumes:
mongo-data:
Tu avais trouvé ?
Exercice 3 sur 3 Premiers pas Réussi À revoir
Charge le jeu de données, puis, dans mongosh : affiche les bases, place-toi sur appli_frais, affiche ses collections et un document de chaque collection. Combien de documents contient chaque collection ?
Voir la réponseMasquer la réponse de l'exercice 3
show dbs
use appli_frais
show collections // fiches, visiteurs
db.visiteurs.findOne()
db.fiches.findOne()
db.visiteurs.countDocuments() // 5
db.fiches.countDocuments() // 9
show dbs affiche aussi les bases internes admin, config et local, que MongoDB utilise pour les comptes, la configuration et la réplication : n'y touche pas. findOne() sans filtre renvoie le premier document dans l'ordre naturel de stockage, en pratique souvent le premier inséré, sans garantie.
Tu avais trouvé ?