Gå til innhold

Utrulling av NestJS-containere

Forenkle utrullingen av Node.js/Nest.js: trinnvis veiledning med Docker og Google Cloud

En korrigert veiledning om flertrinnscontainere for Node.js og NestJS, uforanderlige byggeartefakter og valget mellom Docker Hub og Cloud Build ved utrulling til Cloud Run.

8 min lesetidAv

Distribuere en Node.js- eller NestJS-tjeneste

Dette er utrullingsløpet jeg brukte i 2023 for en NestJS-mikrotjeneste: bygg et Docker-image, publiser det fra GitHub Actions og rull det ut til Cloud Run. Jeg har rettet delene av den opprinnelige veiledningen som jeg ikke ville levert i dag.

Docker pakker kjøretiden, avhengighetene og applikasjonen i ett Docker-image. Det reduserer forskjellene mellom lokale, CI- og Cloud Run-miljøer, men konfigurasjon og infrastruktur kan fortsatt variere.

Denne gjennomgangen dekker tre faser: bygge og teste imaget, publisere det gjennom GitHub Actions og Docker Hub og rulle det ut til Google Cloud med enten manuelle revisjoner eller kontinuerlig utrulling.

Forutsetninger

  • Installer Docker før du begynner å bygge imaget.
  • På Windows, installer WSL (Windows Subsystem for Linux) slik at Docker kan bruke det nødvendige Linux-miljøet.
  • Hvis WSL-installasjonen mislykkes med feil 0x80370114, aktiver de nødvendige virtualiseringsfunksjonene før du fortsetter.

Fase 1: Opprett Docker-imaget

Den opprinnelige veiledningen fra 2023 brukte ett Node 18 Alpine-trinn, installerte produksjonsavhengighetene og kjørte deretter Nest-byggingen i det samme imaget. Denne rekkefølgen gir ikke en pålitelig NestJS-bygging, fordi TypeScript og andre byggeverktøy ofte ligger i devDependencies. Det korrigerte imaget skiller kompileringen fra kjøretiden. Dermed har byggingen tilgang til hele verktøykjeden uten at verktøykjeden følger med til produksjon.

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"]

Byggetrinnet bruker npm ci, som krever en låsefil som er lagt inn i kodelageret, og kompilerer med prosjektets fastlåste Nest- og TypeScript-versjoner. Kjøretidstrinnet mottar produksjonsavhengighetene og det kompilerte resultatet, og gir deretter fra seg root-rettigheter ved å bruke node-brukeren i imaget.

Dockerfile
.dockerignore
node_modules
npm-debug.log
dist

De ignorerte filene gjør Docker-byggekonteksten mindre og hindrer at avhengigheter fra vertsmaskinen eller en eksisterende dist-mappe kopieres inn i imaget.

Kjør og undersøk containeren lokalt

Bygg Docker-imaget og bekreft at Docker opprettet det.

docker build --tag nest-microservice .
docker images

Start en container i bakgrunnen og koble den interne porten 8080 til lokal port 5000. Kontroller docker ps, kall HTTP-helseendepunktet og undersøk docker logs før imaget publiseres.

docker run -d --publish 5000:8080 --name nest-container nest-microservice
docker ps
docker ps --all
docker stop nest-container

Når det lokale imaget og containeren virker, sender du Dockerfile og .dockerignore til GitHub-kodelageret.

Fase 2: Publiser imaget med GitHub Actions

Kontinuerlig integrasjon krever et GitHub-kodelager med kildekoden for Node.js eller NestJS og en konto på Docker Hub. Opprett et personlig tilgangstoken i Docker Hub. Lagre deretter kontonavnet og tokenet som hemmeligheter i kodelageret med navnene DOCKERHUB_USERNAME og DOCKERHUB_TOKEN.

Arbeidsflyten fra 2023 nedenfor kjørte ved hver push til main, hentet ut kildekoden, logget på Docker Hub, aktiverte Buildx, bygde Dockerfile fra roten og pushet abdullahraheel/nest-microservice:latest. Den er beholdt som den opprinnelige implementasjonen, med de historiske versjonene av Actions-handlingene.

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
  1. Lagre og commit arbeidsflyten.
  2. Push endringen til main, slik at arbeidsflyten starter.
  3. Undersøk kjøringen i Actions og finn det nøyaktige trinnet dersom en jobb feiler.
  4. Kontroller at det publiserte kodelageret og taggen vises i Docker Hub.

Fase 3: Rull ut imaget til Google Cloud Run

Opprett et Google Cloud-prosjekt, åpne Cloud Run og opprett en tjeneste. For manuell utrulling oppgir du Docker Hub-imaget som username/repository:tag, velger region og tjenesteinnstillinger og oppretter revisjonen. Eksempelimaget er abdullahraheel/nest-microservice:latest. Bruk det nøyaktige kodelageret og den nøyaktige taggen som din egen arbeidsflyt produserte.

Koble til Cloud Build for kontinuerlig utrulling

  1. Velg Create Service og alternativet for å sette opp kontinuerlig utrulling med Cloud Build.
  2. Velg leverandøren av kodelageret og selve kodelageret.
  3. Velg utrullingsgrenen. I dette eksemplet brukes main.
  4. Velg Dockerfile som byggetype og angi banen.
  5. Lagre konfigurasjonen og opprett tjenesten.

Når tilkoblingen er aktiv, utløser endringer som slås sammen til main, Cloud Build. Tjenesten bygges fra kodelageret og rulles automatisk ut på nytt. Dette er et alternativ til å rulle ut Docker Hub-imaget fra fase 2, ikke en ekstra forbruker av den samme artefakten.

Sammendrag og referanser

  1. Bygg NestJS- eller Node.js-prosjektet som et Docker-image, og test containeren lokalt.
  2. Velg én leveringsbane: publiser et versjonert image gjennom GitHub Actions, eller la Cloud Build bygge det tilkoblede kodelageret.
  3. Rull ut en bestemt image-revisjon manuelt, eller bruk den tilkoblede Cloud Build-banen til automatiske tjenesterevisjoner.
  4. Bruk en ekstern planlegger eller singleton-kontroll til planlagt arbeid. En Cloud Run-webinstans er ikke i seg selv én varig cron-arbeider.