Pourquoi Deployer NestJS avec Docker ?
Le déploiement d'une application NestJS avec Docker offre plusieurs avantages :
Portabilité : Un conteneur Docker est une image qui encapsule toutes les dépendances et les configurations nécessaires pour exécuter l'application, ce qui signifie que vous pouvez déployer votre application sur n'importe quel système qui prend en charge Docker.
Isolation : Les applications sont isolées les unes des autres dans leurs conteneurs respectifs. Cela aide à éviter les conflits entre les différentes applications et améliore la sécurité.
Facilité de déploiement : Avec Docker, le processus de déploiement est simplifié car vous pouvez simplement exécuter une commande pour construire l'image du conteneur et démarrer votre application.
Élasticité : Docker peut être utilisé avec des outils d'orchestration comme Kubernetes pour gérer facilement la mise à l'échelle de vos applications.
Un cas concret serait de développer une API de blog. Vous pouvez utiliser Docker pour déployer cette API sur un serveur distant, permettant ainsi à votre application de fonctionner indépendamment des environnements locaux.
Prerequis
Connaissances nécessaires :
- Base en Node.js et TypeScript
- Compréhension de NestJS
- Connaissance de Docker
Outils à installer (versions) :
- Node.js v14.x ou plus tard
- Docker Desktop (version 2.0.0 ou supérieure)
- npm/yarn (pour gérer les dépendances)
Concepts fondamentaux
1. Dockerfile
Le Dockerfile est un fichier texte qui contient toutes les instructions nécessaires pour construire une image Docker.
## Utilisation de l'image officielle Node.js 14 comme base
FROM node:14
## Création du répertoire de travail dans le conteneur
WORKDIR /usr/src/app
## Copie des fichiers package.json et package-lock.json pour installer les dépendances
COPY package*.json ./
## Installation des dépendances
RUN npm install --only=production
## Copie des fichiers restants dans le répertoire de travail
COPY . .
## Exposition du port 3000
EXPOSE 3000
## Commande pour démarrer l'application
CMD ["node", "dist/main.js"]
2. Docker Compose
docker-compose.yml est un fichier qui permet de définir et d'exécuter des applications multi-conteneurs.
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
volumes:
- .:/usr/src/app
3. Docker Image
Une image Docker est un ensemble de fichiers et instructions qui définit comment construire une application dans un environnement isolé.
## Construire l'image Docker
docker build -t my-nestjs-app .
4. Docker Container
Un conteneur Docker est une instance exécutable d'une image Docker.
## Démarrer le conteneur
docker run -p 3000:3000 my-nestjs-app
Mise en pratique : projet fil rouge
Nous allons construire un gestionnaire de tâches simple avec NestJS et Docker. Voici les étapes :
Initialisation du projet
# Créer un nouveau projet NestJS nest new task-manager cd task-managerStructure du projet
task-manager/ ├── src/ │ ├── app.controller.ts │ ├── app.module.ts │ ├── app.service.ts │ ├── tasks/ │ │ ├── task.controller.ts │ │ ├── task.dto.ts │ │ ├── task.entity.ts │ │ ├── task.module.ts │ │ └── task.service.ts ├── docker-compose.yml ├── Dockerfile ├── package.json └── tsconfig.build.jsonCréation du service pour les tâches
// src/tasks/task.service.ts import { Injectable } from '@nestjs/common'; import { TaskDto } from './task.dto'; @Injectable() export class TaskService { private tasks: TaskDto[] = []; create(task: TaskDto) { this.tasks.push(task); return task; } findAll() { return this.tasks; } }Création du contrôleur pour les tâches
// src/tasks/task.controller.ts import { Controller, Post, Get, Body } from '@nestjs/common'; import { TaskDto } from './task.dto'; import { TaskService } from './task.service'; @Controller('tasks') export class TaskController { constructor(private readonly taskService: TaskService) {} @Post() create(@Body() taskDto: TaskDto) { return this.taskService.create(taskDto); } @Get() findAll() { return this.taskService.findAll(); } }Ajout des fichiers Docker et docker-compose
Dockerfile:FROM node:14 WORKDIR /usr/src/app COPY package*.json ./ RUN npm install --only=production COPY . . EXPOSE 3000 CMD ["node", "dist/main.js"]docker-compose.yml:version: '3.8' services: app: build: . ports: - "3000:3000" volumes: - .:/usr/src/app
Lancement du projet
# Démarrer le conteneur Docker docker-compose up --buildTest de l'application
Vous pouvez maintenant tester votre application en accédant à
http://localhost:3000/tasksdans votre navigateur.
Erreurs frequentes et debugging
1. Problème : L'image Docker ne se construit pas correctement
## Mauvais
docker build -t my-nestjs-app .
bash
## ✅ Correct
docker build --no-cache -t my-nestjs-app .
2. Problème : Le conteneur ne démarre pas
## Mauvais
docker run -p 3000:3000 my-nestjs-app
bash
## ✅ Correct
docker run -p 3000:3000 --rm my-nestjs-app
3. Problème : L'application ne fonctionne pas
// src/app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
bash
## Mauvais
docker-compose up --build
bash
## ✅ Correct
docker-compose up --build --force-recreate
Pour aller plus loin
- Utiliser Docker Secrets pour gérer les secrets et mots de passe : https://docs.docker.com/engine/swarm/secrets/
- Intégrer l'authentification OAuth2 avec Keycloak : https://www.keycloak.org/docs/latest/server_admin/index.html#_oauth2
- Utiliser Docker Compose pour déployer des applications multi-conteneurs : https://docs.docker.com/compose/getting-started/
Défi pratique
Développez un simple service RESTful qui expose une API pour gérer les utilisateurs (GET, POST, PUT, DELETE). Utilisez Docker et Docker Compose pour déployer votre application.