Voici un tutoriel approfondi sur l'utilisation de Docker Compose pour développer une application Express avec MongoDB :
Pourquoi Docker Compose : Express + MongoDB ?
L'adoption de Docker Compose est essentielle pour les développeurs modernes en raison des nombreux avantages qu'il offre. En particulier, lors du développement d'applications utilisant plusieurs services interconnectés comme Express.js et MongoDB, Docker Compose permet une configuration et une gestion simplifiées de ces environnements.
Un cas concret est le développement d'une application web complète où les données sont stockées dans une base de données NoSQL comme MongoDB. En utilisant Docker Compose, vous pouvez rapidement déployer et configurer ces deux services en un seul fichier de configuration, facilitant ainsi le partage et la collaboration entre les développeurs.
Prerequis
- Connaissance des bases de Node.js et Express.js
- Familiarité avec MongoDB
- Installation de Docker (version 20.10.7 ou ultérieure)
- Installation de Docker Compose (version 1.29.2 ou ultérieure)
Concepts fondamentaux
1. Dockerfile
Le Dockerfile est un fichier texte contenant des instructions qui décrivent comment construire une image Docker. Voici un exemple simple pour une application Express.js :
## Utilisation d'une image officielle de Node.js
FROM node:14
## Définition du répertoire de travail dans l'image
WORKDIR /app
## Copie du package.json et du package-lock.json
COPY package*.json ./
## Installation des dépendances du projet
RUN npm install
## Copie du code source du projet
COPY . .
## Exposition du port 3000 sur lequel Express.js écoute les requêtes
EXPOSE 3000
## Commande pour lancer l'application
CMD ["node", "app.js"]
2. docker-compose.yml
Le fichier docker-compose.yml est utilisé pour définir et exécuter des conteneurs Docker. Voici un exemple pour notre application Express.js avec MongoDB :
version: '3'
services:
app:
build: .
ports:
- "3000:3000"
volumes:
- .:/app
depends_on:
- mongo
environment:
MONGO_URI: mongodb://mongo:27017/mydatabase
mongo:
image: mongo:4.4
ports:
- "27017:27017"
volumes:
- mongo-data:/data/db
volumes:
mongo-data:
3. MongoDB avec Docker Compose
MongoDB peut facilement être configuré en utilisant Docker Compose en spécifiant une image officielle de MongoDB dans le docker-compose.yml. Voici un exemple :
services:
db:
image: mongo
ports:
- "27017:27017"
volumes:
- mongodb-data:/data/db
volumes:
mongodb-data:
4. Connexion Express.js à MongoDB
Pour connecter Express.js à MongoDB, vous pouvez utiliser le package mongoose. Voici un exemple de code pour configurer la connexion :
const mongoose = require('mongoose');
// Configuration de la connexion MongoDB
mongoose.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
// Gestion des erreurs de connexion
mongoose.connection.on('error', (err) => {
console.error('MongoDB connection error:', err);
});
Mise en pratique : projet fil rouge
Étape 1 : Création du projet
Créez un nouveau répertoire pour votre projet et initialisez-le avec npm init.
mkdir express-mongo-app
cd express-mongo-app
npm init -y
Étape 2 : Installation des dépendances
Installez les packages nécessaires :
npm install express mongoose body-parser dotenv
Étape 3 : Configuration de l'application Express.js
Créez un fichier app.js avec le code suivant :
const express = require('express');
const bodyParser = require('body-parser');
require('dotenv').config();
// Initialisation de l'application Express.js
const app = express();
app.use(bodyParser.json());
// Route pour tester la connexion
app.get('/', (req, res) => {
res.send('Hello World!');
});
// Démarrage du serveur
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
Étape 4 : Configuration de MongoDB
Créez un fichier .env pour stocker les variables d'environnement :
MONGO_URI=mongodb://localhost:27017/mydatabase
PORT=3000
Étape 5 : Ajout du modèle Mongoose
Créez un fichier models/Todo.js avec le code suivant :
const mongoose = require('mongoose');
// Schéma pour les tâches
const todoSchema = new mongoose.Schema({
title: {
type: String,
required: true,
},
completed: {
type: Boolean,
default: false,
},
});
// Création du modèle
const Todo = mongoose.model('Todo', todoSchema);
module.exports = Todo;
Étape 6 : Ajout des routes pour les tâches
Ajoutez les routes CRUD dans app.js :
const express = require('express');
const bodyParser = require('body-parser');
const Todo = require('./models/Todo');
// Initialisation de l'application Express.js
const app = express();
app.use(bodyParser.json());
// Route pour ajouter une tâche
app.post('/todos', async (req, res) => {
const todo = new Todo(req.body);
await todo.save();
res.status(201).send(todo);
});
// Route pour récupérer toutes les tâches
app.get('/todos', async (req, res) => {
const todos = await Todo.find({});
res.send(todos);
});
// Route pour mettre à jour une tâche
app.patch('/todos/:id', async (req, res) => {
const todo = await Todo.findByIdAndUpdate(req.params.id, req.body, { new: true });
if (!todo) return res.status(404).send();
res.send(todo);
});
// Route pour supprimer une tâche
app.delete('/todos/:id', async (req, res) => {
const todo = await Todo.findByIdAndDelete(req.params.id);
if (!todo) return res.status(404).send();
res.send(todo);
});
// Démarrage du serveur
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
Étape 7 : Configuration de Docker Compose
Créez un fichier docker-compose.yml avec le code suivant :
version: '3'
services:
app:
build: .
ports:
- "3000:3000"
volumes:
- .:/app
depends_on:
- mongo
environment:
MONGO_URI: mongodb://mongo:27017/mydatabase
mongo:
image: mongo
ports:
- "27017:27017"
Étape 8 : Lancement de l'application
Exécutez les commandes suivantes pour démarrer votre application :
docker-compose up --build
Erreurs frequentes et debugging
Erreur 1 : Le service MongoDB ne démarre pas
Code incorrect :
docker-compose up
Code correct :
docker-compose up -d mongo
Erreur 2 : L'application Express.js ne peut pas se connecter à MongoDB
Code incorrect :
mongoose.connect('mongodb://localhost:27017/mydatabase', {
useNewUrlParser: true,
useUnifiedTopology: true,
});
Code correct :
mongoose.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
Erreur 3 : Les volumes ne sont pas montés correctement
Code incorrect :
volumes:
- .:/app
Code correct :
volumes:
- .:/app
- mongo-data:/data/db
volumes:
mongo-data:
Pour aller plus loin
1. Authentification MongoDB
L'authentification est essentielle pour sécuriser votre base de données MongoDB. Vous pouvez l'activer en modifiant le fichier docker-compose.yml et en ajoutant les options d'authentification.
2. Utilisation de Docker Swarm
Pour des environnements de production plus complexes, vous pouvez utiliser Docker Swarm pour gérer une armée de conteneurs Docker.
3. Optimisation des performances avec MongoDB Atlas
Si vous avez besoin d'un service MongoDB en production, considérez l'utilisation de MongoDB Atlas pour une meilleure performance et la gestion évoluée de votre base de données.
Défi pratique
Créez un simple API RESTful pour gérer des utilisateurs en utilisant Express.js et MongoDB. Assurez-vous de configurer la connexion à MongoDB via Docker Compose, d'ajouter les modèles et routes CRUD correspondants, et de tester votre application avec Postman ou curl.