Starte Node.js Backend i Docker: En feilsøkingsveiledning
Oppstår en feil når du prøver å kjøre din Node.js-backend inne i a Docker container kan være frustrerende, spesielt når det er på grunn av en enkel "Mangler startskript"-melding. Denne feilen oppstår ofte når NPM finner ikke riktig startkommando i oppsettet ditt. Hvis du har blitt rammet av dette, er du ikke alene!
I mange tilfeller koker problemet ned til feil baner eller feiljusterte konfigurasjoner mellom innstillingene for package.json og Docker. Det er lett å overse en liten detalj når du arbeider med flertrinnsbygg, containerisering og konfigurasjonsfiler. Etter å ha møtt dette problemet selv, kan jeg si at å fikse det ofte innebærer å sjekke hver fils plassering og skript.
For eksempel distribuerte jeg en gang en backend og innså senere at dist-mappen min ikke var riktig kartlagt, noe som førte til at startkommandoen mislyktes. Enkle justeringer kan løse disse problemene, men å finne den rette krever tålmodighet. Å sjekke om alle avhengigheter og skript er riktig kartlagt kan spare timer med feilsøking.
I denne veiledningen vil vi dykke ned i noen praktiske trinn for å fikse denne feilen, spesielt hvis du kjører backend sammen med en database som DynamoDB i Docker. La oss feilsøke feilen "manglende startskript" sammen for å få backend til å fungere problemfritt!
Kommando | Beskrivelse |
---|---|
CMD ["node", "dist/server.js"] | Definerer primærkommandoen som kjører i Docker-beholderen ved oppstart. Her ber den Docker om å starte applikasjonen ved å kjøre server.js inne i dist-mappen, og adressere mangler startskript problemet ved å sikre at Docker vet hvilket skript som skal kjøres. |
WORKDIR /app | Setter arbeidskatalogen inne i beholderen til /app. Dette er avgjørende for å sikre at alle filbaner i påfølgende kommandoer refererer til denne katalogen, og effektiviserer bygge- og kjøretidsprosessene i Docker. |
COPY --from=builder /app/dist ./dist | Kopierer de bygde filene fra dist-mappen i byggerstadiet til kjøretidsmiljøets dist-katalog. Denne kommandoen er viktig for å sikre at kompilerte TypeScript-filer er tilgjengelige i beholderen. |
RUN npm install --omit=dev | Installerer bare produksjonsavhengighetene ved å utelate dev-avhengighetene. Denne kommandoen er optimalisert for produksjonsbygg, reduserer beholderens endelige størrelse og forbedrer sikkerheten ved å ekskludere utviklingsverktøy. |
healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000"] | Definerer en helsesjekk for å bekrefte om DynamoDB-tjenesten i Docker kjører. Den bruker curl for å forsøke å koble til det spesifiserte lokale endepunktet, og sikrer at tjenesten er tilgjengelig før backend starter. |
depends_on: | Angir avhengigheter i docker-compose.yml. Her sikrer den at backend-tjenesten venter på at DynamoDB skal initialiseres, og forhindrer at feil prøver å koble til en uklar tjeneste. |
EXPOSE 3001 | Åpner port 3001 i Docker-beholderen, noe som gjør backend-tjenesten tilgjengelig på denne porten. Denne kommandoen er nødvendig for å sette opp nettverk og gi eksterne tjenester eller andre beholdere tilgang til backend. |
test('dist folder exists', ...) | En Jest-enhetstest som sjekker om dist-mappen ble riktig generert. Denne testen hjelper deg med å bekrefte at byggetrinnet var vellykket, og fanger opp potensielle problemer med manglende filer i dist-katalogen. |
expect(packageJson.scripts.start) | En Jest-testlinje som bekrefter at startskriptet finnes i package.json. Dette bidrar til å forhindre at kjøretidsfeil mangler startkommandoer ved å sikre konfigurasjonsnøyaktighet før distribusjon. |
Docker-konfigurasjon for Node.js og databasetilkobling
I eksemplet ovenfor utnytter Docker-oppsettet en flertrinnsbygging, som er nyttig for å lage effektive produksjonsklare containere. Det første trinnet, definert som "bygger", installerer avhengigheter og kompilerer TypeScript filer til JavaScript i dist mappe. Dette trinnet sikrer at den kompilerte koden er klar for produksjon uten å inkludere unødvendige dev-avhengigheter. Når den er bygget, kopierer det andre trinnet (runtime) bare de kompilerte filene og produksjonsavhengighetene, og minimerer beholderstørrelsen. Dette oppsettet er spesielt nyttig hvis du ofte distribuerer til skymiljøer der hver bit av optimalisering teller! 🚀
De WORKDIR kommandoen i begge trinn setter beholderens arbeidskatalog til /app. Dette forenkler filstier og organiserer alle operasjoner rundt denne katalogen. Etter det, KOPIERE instruksjoner flytter spesifikke filer fra vertsmaskinen til beholderen. I det første trinnet kopieres pakke*.json-filer og tsconfig.json for å tillate avhengighetsinstallasjon og TypeScript-kompilering, og KJØR npm installasjon og KJØR npm kjøre bygg kommandoer sikrer at alt er satt opp riktig. Dette oppsettet hjelper til med å unngå problemer som manglende startskript ved å sørge for at alle filene er riktig kopiert og konfigurert.
De docker-compose.yml fil kobler backend med DynamoDB, som er avgjørende for lokal testing og utvikling. De avhenger_på alternativet ber Docker om å starte DynamoDB før backend-tjenesten, og sikrer at databasen er klar for alle tilkoblingsforsøk fra backend. I virkelige scenarier kan det å ikke ha et slikt avhengighetsoppsett føre til tilkoblingsproblemer når backend starter før databasen, noe som resulterer i frustrerende feil. De helsesjekk kommando tester om DynamoDB er tilgjengelig ved å pinge endepunktet, og prøver på nytt til en tilkobling er opprettet. Dette nivået av feilhåndtering sparer tid ved å sikre at tjenestene starter i riktig rekkefølge 🕒.
Til slutt, i package.json, har vi definert start skript som node dist/server.js. Denne kommandoen sikrer at NPM vet nøyaktig hvilken fil som skal kjøres i beholderen, og hjelper til med å unngå feilen "manglende startskript". Det er også en byggekommando for å kompilere TypeScript-kode og en ren kommando for å fjerne dist-mappen, som sikrer at hver distribusjon starter på nytt. Å bruke npm-skript som disse gjør oppsettet mer pålitelig, spesielt når Docker er involvert, siden det tilbyr forutsigbare stier og handlinger. Denne omfattende konfigurasjonen av Docker-, Docker Compose- og NPM-skript fungerer sammen for å skape en strømlinjeformet arbeidsflyt for utvikling til produksjon.
Løsning 1: Justering av Dockerfile og Package.json for korrekt filkopiering
Denne løsningen bruker Docker og Node.js for å sikre at filene blir korrekt kopiert til dist mappen og at NPM kan finne start manus.
# Dockerfile
FROM node:18 AS builder
WORKDIR /app
# Copy necessary config files and install dependencies
COPY package*.json tsconfig.json ./
RUN npm install
# Copy all source files and build the project
COPY . .
RUN npm run build
# Production stage
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/package*.json ./
RUN npm install --omit=dev
COPY --from=builder /app/dist ./dist
EXPOSE 3001
# Adjust command to start the server
CMD ["node", "dist/server.js"]
Løsning 2: Endre docker-compose.yml for Environment Control
Denne løsningen endrer docker-compose.yml konfigurasjon for å spesifisere de riktige kommandoene og sikre at skript kjører riktig i Docker.
# docker-compose.yml
version: "3.9"
services:
backend:
build:
context: .
dockerfile: Dockerfile
ports:
- "3001:3001"
environment:
PORT: 3001
depends_on:
- dynamodb
command: ["npm", "run", "start"]
dynamodb:
image: amazon/dynamodb-local
ports:
- "8001:8000"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000"]
interval: 10s
timeout: 5s
retries: 5
Løsning 3: Verifisering og oppdatering av Package.json-skriptene
Denne løsningen innebærer å sikre at start skriptet er riktig definert i package.json fil for å forhindre manglende skriptfeil.
{
"name": "backend",
"version": "1.0.0",
"main": "dist/server.js",
"scripts": {
"build": "tsc",
"start": "node dist/server.js",
"dev": "nodemon --exec ts-node src/server.ts",
"clean": "rimraf dist"
}
}
Enhetstester: Sikre integritet for skript- og dockerkonfigurasjon
Disse Jest-testene validerer at viktige filer er korrekt kopiert og at NPM-skript fungerer i containermiljøet.
// test/deployment.test.js
const fs = require('fs');
describe('Deployment Tests', () => {
test('dist folder exists', () => {
expect(fs.existsSync('./dist')).toBe(true);
});
test('start script exists in package.json', () => {
const packageJson = require('../package.json');
expect(packageJson.scripts.start).toBe("node dist/server.js");
});
test('Dockerfile has correct CMD', () => {
const dockerfile = fs.readFileSync('./Dockerfile', 'utf8');
expect(dockerfile).toMatch(/CMD \["node", "dist\/server.js"\]/);
});
});
Sikre riktig filkopiering og struktur i Docker for Node.js-prosjekter
Når du arbeider med Node.js-applikasjoner i Docker, er en viktig faktor å sikre at alle nødvendige filer er korrekt kopiert og strukturert i beholderen. I flertrinnsbygg, som eksempelet ovenfor, har hvert trinn et spesifikt formål. Den innledende fasen, "bygger", håndterer kompilering av TypeScript til JavaScript og forbereder dist mappe. I det andre trinnet er bare produksjonsfiler inkludert, noe som reduserer beholderstørrelsen og optimaliserer distribusjonen. Denne tilnærmingen reduserer ikke bare unødvendig oppblåsthet, men forbedrer også sikkerheten ved å utelate utviklingsverktøy.
Et viktig aspekt ved Docker for Node.js er å organisere package.json og start skriptet nøyaktig. Ved å spesifisere stier tydelig i Dockerfilen og sikre at startkommandoen er riktig konfigurert i package.json, minimerer du feil som «Mangler startskript». Det er også viktig å bekrefte at Docker vet hvor hver fil skal være, spesielt i komplekse oppsett som involverer flere tjenester eller mapper. Bruk for eksempel COPY-kommandoen til å bare legge til dist mappe og nødvendige konfigurasjoner til den endelige beholderen sikrer at kun viktige filer er tilgjengelige i produksjonen 📂.
For å sjekke helsen til tjenestene dine, docker-compose.yml filen bruker en helsesjekk for å bekrefte at databasen er klar. Ved å definere avhengigheter sikrer vi at backend-tjenesten ikke starter før databasen er responsiv, og forhindrer tidsrelaterte tilkoblingsproblemer. Dette oppsettet er spesielt gunstig i virkelige applikasjoner der databasetilkobling er avgjørende. Uten denne strukturen kan tjenester prøve å koble seg til før andre tjenester er oppe, noe som fører til kjøretidsfeil og potensiell nedetid for brukere 🔄.
Vanlige spørsmål om å fikse "manglende startskript" i Node.js
- Hva forårsaker feilen "manglende startskript" i NPM?
- Denne feilen oppstår ofte når package.json filen har ikke en start skript definert. NPM finner ikke riktig inngangspunkt for å starte applikasjonen.
- Gjør det package.json filen må være i dist mappe?
- Nei, den package.json ligger vanligvis i rotkatalogen, og bare nødvendige filer kopieres til dist mappe.
- Hvorfor bruker vi flertrinnsbygg i Docker?
- Flertrinnsbygg lar oss lage lette, produksjonsklare beholdere. Ved å skille bygge- og kjøretidsmiljøer ekskluderes unødvendige filer, noe som forbedrer sikkerheten og effektiviteten.
- Hvordan fungerer healthcheck i Docker Compose hjelp?
- De healthcheck kommando sjekker om en tjeneste er oppe og kjører, noe som er viktig i tilfeller der avhengige tjenester må være klare først, som databaser.
- Kan jeg bruke andre databaser i stedet for DynamoDB i dette oppsettet?
- Ja, du kan erstatte DynamoDB med andre databaser. Juster Docker Compose-konfigurasjonen slik at den passer din foretrukne databasetjeneste.
- Hvorfor bruker vi RUN npm install --omit=dev kommando?
- Denne kommandoen installerer bare produksjonsavhengigheter, noe som hjelper til med å holde beholderen lett ved å ekskludere utviklingsverktøy.
- Hvordan kan jeg bekrefte dist mappen er riktig kopiert?
- Du kan legge til en test i koden din for å sjekke om dist eksisterer, eller bruk Docker CLI til å inspisere innholdet til beholderen etter byggingen.
- Må jeg spesifisere porten i både Dockerfile og Docker Compose?
- Ja, å spesifisere porten i begge sikrer at containerporten samsvarer med vertsporten, noe som gjør tjenesten tilgjengelig fra utenfor Docker.
- Hvorfor er innstillingen WORKDIR viktig i Docker?
- Innstilling WORKDIR oppretter en standard katalogbane for alle kommandoer, forenkler filstier og organiserer containerfiler systematisk.
- Hvordan kan jeg se Docker-logger for å feilsøke denne feilen?
- Bruk docker logs [container_name] for å få tilgang til logger, som kan gi innsikt i eventuelle oppstartsfeil eller manglende filer.
Retter oppstartsfeil for Node.js i Docker
Å adressere feilen "manglende startskript" krever oppmerksomhet på detaljer, spesielt ved konfigurering av Dockers filstruktur og NPM-skript. Kontrollerer Dockerfilen din for å sikre at kompilerte filer blir kopiert til dist mappen og at startskriptet i package.json er riktig definert kan spare deg for timer med feilsøking.
Å opprettholde et klart oppsett og organiserte skript vil hjelpe Docker-beholdere til å fungere uten problemer, og bruk av helsesjekker i Docker Compose sikrer at tjenestene lastes inn i riktig rekkefølge. Med disse justeringene bør backend-en din starte pålitelig, og gi deg en jevnere utviklingsarbeidsflyt. 🛠️
Kilder og referanser
- Detaljert informasjon om Docker flertrinnsbygginger og beste praksis for Node.js-applikasjoner i Docker: Docker-dokumentasjon
- Omfattende veiledning for å sette opp helsesjekker og avhengigheter i Docker Compose for å sikre at tjenestene starter i riktig rekkefølge: Docker Compose Health Check
- Feilsøking av "manglende startskript"-feil og andre vanlige NPM-problemer, inkludert konfigurering av package.json riktig for produksjonsbygg: NPM-dokumentasjon
- Introduksjon til konfigurering og testing av DynamoDB Local i Docker-miljøer, inkludert bruk med Node.js-backends: AWS DynamoDB Local Guide