Implementatie van NestJS-containers
Vereenvoudig de implementatie van Node.js/Nest.js: stapsgewijze handleiding met Docker en Google Cloud
Een gecorrigeerde handleiding voor meerfasige Node.js- en NestJS-containers, onveranderlijke artefacten en de keuze tussen Docker Hub en Cloud Build voor oplevering aan Cloud Run.
8 min. leestijdDoor Abdullah Raheel
Een Node.js- of NestJS-service implementeren
Dit is het implementatiepad dat ik in 2023 gebruikte voor een NestJS-microservice: bouw een Docker-image, publiceer deze via GitHub Actions en implementeer deze op Cloud Run. Ik heb de onderdelen uit de oorspronkelijke handleiding gecorrigeerd die ik nu niet meer zou opleveren.
Docker verpakt de runtime, afhankelijkheden en toepassing in één image. Het verkleint de verschillen tussen lokale, CI- en Cloud Run-omgevingen, maar configuratie en infrastructuur kunnen nog steeds verschillen.
Deze handleiding behandelt drie fasen: de image bouwen en testen, deze via GitHub Actions en Docker Hub publiceren en deze met handmatige revisies of continue implementatie op Google Cloud implementeren.
Vereisten
- Installeer Docker voordat je de build start.
- Installeer op Windows WSL (Windows Subsystem for Linux), zodat Docker de vereiste Linux-omgeving kan gebruiken.
- Schakel de vereiste virtualisatiefuncties in voordat je verdergaat als de WSL-installatie mislukt met fout 0x80370114.
Fase 1: de Docker-image maken
De oorspronkelijke handleiding uit 2023 gebruikte één Node 18 Alpine-fase, installeerde productieafhankelijkheden en voerde daarna de Nest-build in dezelfde image uit. Die volgorde levert geen betrouwbare NestJS-build op: TypeScript en andere buildtools staan vaak in devDependencies. De gecorrigeerde image scheidt compilatie van de runtime, zodat voor de build de volledige toolchain beschikbaar is zonder deze naar productie te sturen.
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"]De buildfase gebruikt npm ci, waarvoor een vastgelegde lockfile nodig is, en compileert met de door het project vastgezette versies van Nest en TypeScript. De runtimefase ontvangt productieafhankelijkheden en gecompileerde uitvoer en schakelt daarna met de node-gebruiker van de image over van root naar lagere rechten.
Dockerfile
.dockerignore
node_modules
npm-debug.log
distDe genegeerde bestanden houden de Docker-buildcontext kleiner en voorkomen dat hostafhankelijkheden of een bestaande dist-directory naar de image worden gekopieerd.
De container lokaal uitvoeren en controleren
Bouw de image en controleer of Docker deze heeft gemaakt.
docker build --tag nest-microservice .
docker imagesStart een losgekoppelde container en wijs de interne poort 8080 toe aan lokale poort 5000. Controleer docker ps, roep het HTTP-statuseindpunt aan en bekijk docker logs voordat je de image publiceert.
docker run -d --publish 5000:8080 --name nest-container nest-microservice
docker ps
docker ps --all
docker stop nest-containerPush Dockerfile en .dockerignore naar de GitHub-repository nadat de lokale image en container werken.
Fase 2: de image publiceren met GitHub Actions
Voor continue integratie zijn een GitHub-repository met de Node.js- of NestJS-broncode en een Docker Hub-account nodig. Maak een persoonlijk toegangstoken voor Docker Hub en sla daarna de accountnaam en het token op als repositorygeheimen met de namen DOCKERHUB_USERNAME en DOCKERHUB_TOKEN.
De onderstaande workflow uit 2023 draaide bij elke push naar main, checkte de broncode uit, meldde zich aan bij Docker Hub, schakelde Buildx in, bouwde de Dockerfile in de hoofdmap en pushte abdullahraheel/nest-microservice:latest. De workflow is behouden als de oorspronkelijke implementatie, inclusief de historische actieversies.
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- Sla de workflow op en leg deze vast in een commit.
- Push de wijziging naar main, zodat de workflow start.
- Controleer de Actions-uitvoering en stel bij een mislukte job vast welke stap precies faalde.
- Controleer of de gepubliceerde repository en tag in Docker Hub verschijnen.
Fase 3: de image implementeren op Google Cloud Run
Maak een Google Cloud-project, open Cloud Run en maak een service. Geef voor een handmatige implementatie de Docker Hub-image op als gebruikersnaam/repository:tag, kies de regio en service-instellingen en maak de revisie. De voorbeeldimage is abdullahraheel/nest-microservice:latest; gebruik exact de repository en tag die je eigen workflow heeft geproduceerd.
Cloud Build koppelen voor continue implementatie
- Kies Create Service en selecteer de optie om continue implementatie met Cloud Build in te stellen.
- Selecteer de repositoryprovider en repository.
- Kies de implementatiebranch, in dit voorbeeld main.
- Selecteer Dockerfile als buildtype en geef het pad op.
- Sla de configuratie op en maak de service.
Zodra de verbinding actief is, activeren in main gemergede wijzigingen Cloud Build om de repository te bouwen en de service automatisch opnieuw te implementeren. Dit is een alternatief voor het implementeren van de Docker Hub-image uit fase 2, geen tweede afnemer van hetzelfde artefact.
Samenvatting en bronnen
- Bouw het NestJS- of Node.js-project als Docker-image en test de container lokaal.
- Kies één opleveringspad: publiceer een geversioneerde image via GitHub Actions of laat Cloud Build de gekoppelde repository bouwen.
- Implementeer handmatig een exacte imagerevisie of gebruik het gekoppelde Cloud Build-pad voor automatische servicerevisies.
- Gebruik een externe scheduler of singletonbesturing voor gepland werk; een Cloud Run-webinstance is niet vanzelf één duurzame cronworker.

