Déploiement de conteneurs NestJS
Simplifier le déploiement de Node.js et NestJS : guide pas à pas avec Docker et Google Cloud
Un guide corrigé sur les conteneurs Node.js et NestJS en plusieurs étapes, les artefacts immuables et le choix entre Docker Hub et Cloud Build pour livrer sur Cloud Run.
8 min de lecturePar Abdullah Raheel
Déployer un service Node.js ou NestJS
Voici la chaîne de déploiement que j’ai utilisée en 2023 pour un microservice NestJS : construire une image Docker, la publier depuis GitHub Actions, puis la déployer sur Cloud Run. J’ai corrigé les parties du guide d’origine que je ne livrerais plus aujourd’hui.
Docker regroupe l’environnement d’exécution, les dépendances et l’application dans une seule image. Il réduit les différences entre les environnements local, CI et Cloud Run, mais la configuration et l’infrastructure peuvent toujours varier.
Ce guide couvre trois étapes : construire et tester l’image, la publier au moyen de GitHub Actions et Docker Hub, puis la déployer sur Google Cloud à l’aide de révisions manuelles ou d’un déploiement continu.
Prérequis
- Installez Docker avant de commencer la construction.
- Sous Windows, installez WSL (Sous-système Windows pour Linux) afin que Docker puisse utiliser l’environnement Linux requis.
- Si l’installation de WSL échoue avec l’erreur 0x80370114, activez les fonctionnalités de virtualisation requises avant de continuer.
Étape 1 : créer l’image Docker
Le guide d’origine de 2023 utilisait une seule étape Node 18 Alpine, installait les dépendances de production, puis exécutait la compilation Nest dans cette même image. Cet ordre ne permet pas de construire une application NestJS de manière fiable : TypeScript et les autres outils de construction se trouvent souvent dans devDependencies. L’image corrigée sépare la compilation de l’environnement d’exécution afin que la construction dispose de tous ses outils sans les livrer en production.
FROM node:18-alpine AS build
WORKDIR /usr/src/app
# Copy manifests first so dependency layers can be reused.
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:18-alpine AS runtime
ENV NODE_ENV=production
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm ci --omit=dev && npm cache clean --force
COPY --from=build /usr/src/app/dist ./dist
EXPOSE 8080
USER node
CMD ["node", "dist/main.js"]L’étape de construction utilise npm ci, qui exige un fichier de verrouillage ajouté au dépôt, et compile avec les versions de Nest et TypeScript épinglées par le projet. L’étape d’exécution reçoit les dépendances de production et la sortie compilée, puis abandonne les privilèges root au profit de l’utilisateur node de l’image.
Dockerfile
.dockerignore
node_modules
npm-debug.log
distLes fichiers ignorés réduisent le contexte de construction Docker et empêchent la copie dans l’image des dépendances de l’hôte ou d’un répertoire dist existant.
Exécuter et inspecter le conteneur en local
Construisez l’image et vérifiez que Docker l’a créée.
docker build --tag nest-microservice .
docker imagesDémarrez un conteneur détaché et mappez son port interne 8080 sur le port local 5000. Vérifiez docker ps, appelez le point de terminaison HTTP de contrôle d’intégrité et consultez docker logs avant de publier l’image.
docker run -d --publish 5000:8080 --name nest-container nest-microservice
docker ps
docker ps --all
docker stop nest-containerLorsque l’image locale et le conteneur fonctionnent, envoyez Dockerfile et .dockerignore vers le dépôt GitHub.
Étape 2 : publier l’image avec GitHub Actions
L’intégration continue exige un dépôt GitHub contenant les sources Node.js ou NestJS et un compte Docker Hub. Créez un jeton d’accès personnel Docker Hub, puis stockez le nom du compte et le jeton dans des secrets de dépôt nommés DOCKERHUB_USERNAME et DOCKERHUB_TOKEN.
Le flux de travail de 2023 ci-dessous s’exécutait à chaque push vers main, récupérait les sources, se connectait à Docker Hub, activait Buildx, construisait le Dockerfile à la racine et publiait abdullahraheel/nest-microservice:latest. Il est conservé comme implémentation d’origine, avec les versions historiques de ses actions.
name: ci
on:
push:
branches:
- "main"
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
file: ./Dockerfile
push: true
tags: ${{ secrets.DOCKERHUB_USERNAME }}/nest-microservice:latest- Enregistrez et validez le flux de travail.
- Envoyez la modification vers main pour lancer le flux de travail.
- Inspectez l’exécution d’Actions et diagnostiquez l’étape exacte si une tâche échoue.
- Vérifiez que le dépôt et le tag publiés apparaissent dans Docker Hub.
Étape 3 : déployer l’image sur Google Cloud Run
Créez un projet Google Cloud, ouvrez Cloud Run et créez un service. Pour un déploiement manuel, indiquez l’image Docker Hub sous la forme username/repository:tag, choisissez la région et les paramètres du service, puis créez la révision. L’image d’exemple est abdullahraheel/nest-microservice:latest. Utilisez le dépôt et le tag exacts produits par votre propre flux de travail.
Connecter Cloud Build pour le déploiement continu
- Choisissez Create Service, puis l’option permettant de configurer le déploiement continu avec Cloud Build.
- Sélectionnez le fournisseur du dépôt et le dépôt.
- Choisissez la branche de déploiement, main dans cet exemple.
- Sélectionnez Dockerfile comme type de construction et indiquez son chemin.
- Enregistrez la configuration et créez le service.
Lorsque la connexion est active, les modifications fusionnées dans main déclenchent la construction du dépôt par Cloud Build et le redéploiement automatique du service. Il s’agit d’une solution différente du déploiement de l’image Docker Hub produite à l’étape 2, et non d’un autre consommateur du même artefact.
Résumé et références
- Construisez le projet NestJS ou Node.js sous forme d’image Docker et testez son conteneur en local.
- Choisissez une chaîne de livraison : publiez une image versionnée au moyen de GitHub Actions ou laissez Cloud Build construire le dépôt connecté.
- Déployez manuellement une révision d’image exacte ou utilisez la chaîne Cloud Build connectée pour créer automatiquement les révisions du service.
- Utilisez un planificateur externe ou un contrôle d’instance unique pour les tâches planifiées. Une instance web Cloud Run n’est pas, par nature, un processus cron unique et durable.

