Slik fikser du "Nginx 502 Bad Gateway" når du bruker proxy til Node.js

En NGINX 502 Bad Gateway foran et Node.js-program betyr vanligvis én ting: NGINX godtok klientforespørselen, men kunne ikke få et brukbart svar fra oppstrømsprogrammet det skulle kontakte. Den raskeste løsningen er derfor ikke å starte alt på nytt eller øke hver timeout. Først må du bevise om Node.js-tjenesten kan nås fra samme nettverksplassering som NGINX, og deretter bruke NGINX-feilloggen til å velge neste trekk.

Denne veiledningen bruker fire diagnostiske trinn. Kommandoene forutsetter en Linux-vert og en Node.js-app som forventes på port 3000. Erstatt port, vertsnavn, stier og tjenestenavn med verdiene i distribusjonen din.

Hva bør du sjekke før du endrer NGINX?

Still først tre spørsmål:

  • Lytter Node.js-prosessen faktisk på adressen og porten NGINX prøver å nå?
  • Hvilken nøyaktig oppstrømsfeil registrerer NGINX-feilloggen for den mislykkede forespørselen?
  • Kjører NGINX og Node.js på samme vert, i separate containere eller på separate maskiner?

Disse svarene er viktige fordi den samme nettlesersynlige 502-feilen kan komme fra svært forskjellige forhold. En stoppet nodeprosess, feil proxy_passport, en container som brukes 127.0.0.1feil, en oppstrøms timeout og et ugyldig oppstrømssvar har ikke samme løsning.

NGINX dokumenterer proxy_passsom direktivet som spesifiserer protokollen og adressen til proxy-serveren. Oppstrømsmodulen eksponerer også variabler som $upstream_addr, $upstream_status, $upstream_connect_timeog $upstream_response_time, som er nyttige når du trenger mer detaljert produksjonslogging. Se den offisielle dokumentasjonen for NGINX-proxymodulen og NGINX-oppstrømsmodulen .

Trinn 1: Kan NGINXs oppstrømslinje nås direkte?

Start med å omgå den omvendte proxyen. Hvis NGINX er på samme vert som Node.js og konfigurasjonen din peker til 127.0.0.1:3000, test den nøyaktige destinasjonen:

curl -i http://127.0.0.1:3000/health
ss -ltnp | grep ':3000'

Et sunt resultat kan returnere HTTP 200 fra applikasjonen din og vise en lytter på port 3000. Hvis tilkoblingen avvises, må du ikke redigere NGINX-tidsavbrudd ennå. Det finnes ingen lyttetjeneste på adressen NGINX prøver å bruke, eller tjenesten lytter et annet sted.

Terminal sjekker et Node.js helse-endepunkt på 127.0.0.1 port 3000 og viser den lyttende Node-prosessen
Den første sjekken omgår NGINX: terminalen kaller Node.js helse-endepunkt direkte og bekrefter hvilken adresse som lytter på port 3000.

Hva om Node.js-prosessen kjører, men porten mangler?

En kjørende prosess er ikke nok. Applikasjonen må ha fullført serveroppstarten og bundet en lyttesocket. Node.js dokumenterer server.listen()som operasjonen som starter en TCP- eller IPC-server som lytter etter tilkoblinger. Den bemerker også at EADDRINUSEdette skjer når en annen server allerede eier den forespurte porten. Se gjennom den offisielle dokumentasjonen for Node.js nettserver og Node.js HTTP-dokumentasjon .

En minimal Node.js HTTP-testtjeneste kan se slik ut:

import http from 'node:http';

const server = http.createServer((req, res) => {
  if (req.url === '/health') {
    res.writeHead(200, { 'content-type': 'application/json' });
    return res.end(JSON.stringify({ status: 'ok' }));
  }

  res.writeHead(200, { 'content-type': 'text/plain' });
  res.end('Node.js is running');
});

server.listen(3000, '127.0.0.1', () => {
  console.log('Listening on http://127.0.0.1:3000');
});

Binding til 127.0.0.1er passende når NGINX og Node.js deler samme vert og ingen annen maskin trenger direkte tilgang til Node-porten. Hvis de er i separate containere, har den adressen en annen betydning, som dekkes nedenfor.

Trinn 2: Hva sier egentlig NGINX-feilloggen?

Når du vet om oppstrømsadressen svarer direkte, sjekk loggoppføringen som ble generert samtidig med 502. En vanlig plassering på Linux-pakker er /var/log/nginx/error.log, men den faktiske banen styres av error_logdirektivet og kan variere avhengig av installasjonen.

sudo tail -n 100 /var/log/nginx/error.log

NGINXs kjernedokumentasjon sier at dette error_logkontrollerer destinasjonen og alvorlighetsgraden for diagnostisk logg. Kommandolinjedokumentasjonen gir også mulighet nginx -Ttil å teste og dumpe den aktive konfigurasjonen, noe som kan hjelpe deg med å finne en uventet loggbane eller serverblokk. Se NGINXs kjerneloggdokumentasjon og NGINX-kommandolinjeparametere .

NGINX-feillogg i en terminal som viser feil om avvist tilkobling under tilkobling til oppstrøms 127.0.0.1 port 3000
En tilkoblingsnektelse peker mot oppstrømsadressen eller tjenestetilgjengeligheten, ikke mot et behov for en lengre proxy-tidsavbrudd.

Bruk meldingen til å avgrense problemet:

Det du ser Mest nyttig neste sjekk
Connection refusedmens du kobler til oppstrøms Bekreft nodelytteren, porten, adressen, containernettverket og prosesstilstanden.
Oppstrømstilkoblingen utløper Sjekk tilgjengelighet for ruting/brannmur og om destinasjonen i det hele tatt er tilgjengelig.
Oppstrøms lesing utløper etter tilkobling Mål applikasjonens responstid og kontroller tregt Node.js-arbeid eller nedstrømsavhengigheter før du øker proxy_read_timeout.
Bare WebSocket-forespørsler mislykkes Sjekk WebSocket Upgrade og Connection-overskriftene og NGINX-versjonens virkemåte.

Trinn 3: Peker proxy_pass til adressen Node.js faktisk bruker?

Sammenlign live-lytteren fra trinn 1 med den aktive NGINX-konfigurasjonen. Et konvensjonelt oppsett med samme vert ser slik ut:

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

NGINX støtter offisielt en IP-adresse, vertsnavn, oppstrømsgruppe eller UNIX-domenesocket i proxy_pass. Den kritiske regelen er enkel: destinasjonen må kunne nås fra NGINX-arbeiderens nettverkskontekst.

Kodeditor som sammenligner et NGINX proxy_pass-mål på 127.0.0.1 port 3000 med et Node.js-program som lytter på samme adresse og port
Sammenlign begge sider av forbindelsen: NGINX-oppstrømsmålet må samsvare med en adresse og port som Node.js-serveren faktisk lytter på.

Er NGINX og Node.js i separate Docker Compose-containere?

Hvis de er det, 127.0.0.1refererer «inne i NGINX-containeren» til selve NGINX-containeren, ikke Node.js-containeren. Docker Compose-dokumentasjonen oppgir at tjenester på standard Compose-nettverket kan oppdages etter tjenestenavn. Den anbefaler også å bruke containerporten for tjeneste-til-tjeneste-kommunikasjon i stedet for en vertspublisert port.

Hvis for eksempel Compose-tjenesten er navngitt appog Node lytter på containerport 3000, kan NGINX bruke:

location / {
    proxy_pass http://app:3000;
}

Begge tjenestene må dele et nettverk. Node-tjenesten må også lytte på et grensesnitt som er tilgjengelig fra det containernettverket. Applikasjoner binder seg vanligvis til 0.0.0.0innsiden av containeren for dette formålet. Du trenger ikke nødvendigvis å publisere port 3000 til verten bare for NGINX-til-app-trafikk. Bekreft topologien mot den offisielle nettverksdokumentasjonen for Docker Compose .

Bør du bruke localhost eller 127.0.0.1?

Hvis begge prosessene kjører på samme vert, kan det hende at begge fungerer, men de er ikke alltid utskiftbare i alle miljøer fordi localhostde kan løses til IPv4, IPv6 eller begge deler. Å bruke den nøyaktige adressen som vises av lytteren fjerner én variabel. Node.js dokumenterer at hvis argumentet hostutelates, kan den lytte på den uspesifiserte IPv6-adressen ::når den er tilgjengelig, eller den uspesifiserte IPv4-adressen 0.0.0.0ellers.

Hvis du ser en avvikelse, for eksempel at NGINX kontakter 127.0.0.1:3000mens applikasjonen bare er tilgjengelig gjennom et annet containervertsnavn, en annen port eller en UNIX-socket, bør du fikse adressen i stedet for å kompensere med nye forsøk.

Er en lengre timeout faktisk den riktige løsningen?

Endre bare tidsavbrudd når loggene viser en tidsavbrudd og du forstår hvorfor oppstrømsfunksjonen trenger lengre tid. NGINX dokumenterer en standard proxy_connect_timeoutpå 60 sekunder og bemerker at den vanligvis ikke kan overskride 75 sekunder. Den dokumenterer også en standard proxy_read_timeoutpå 60 sekunder, målt mellom påfølgende lesninger fra oppstrømsfunksjonen i stedet for over hele responsen.

location /reports/ {
    proxy_pass http://127.0.0.1:3000;
    proxy_connect_timeout 5s;
    proxy_read_timeout 120s;
}

Eksemplet ovenfor er ikke en universell anbefaling. En lav timeout for tilkobling kan være fornuftig for en lokal oppstrøms tilkobling som skal koble til nesten umiddelbart, mens en lengre timeout for lesing kan være berettiget for en legitimt lang forespørsel. Men hvis applikasjonen er treg på grunn av en blokkert hendelsesløkke, en databasestopp, en overbelastet avhengighet eller en forespørsel som henger, vil det å øke timeouten bare skjule symptomet.

Gjennomgå den nøyaktige semantikken i de offisielle NGINX proxy timeout-direktivene .

Hva om bare WebSocket-tilkoblinger får en 502-feil eller frakobling?

WebSocket-proxying har ytterligere krav fordi Upgradeog Connectionheaderne er hop-by-hop-headere og ikke videresendes automatisk i den vanlige reverse-proxy-banen. NGINXs offisielle WebSocket-dokumentasjon viser eksplisitt hvordan disse headerne settes.

location /socket/ {
    proxy_pass http://127.0.0.1:3000;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

NGINX bemerker også at en inaktiv proxy-WebSocket-tilkobling lukkes hvis oppstrømstilkoblingen ikke sender data innenfor lesetidsavbruddsintervallet. En ping på applikasjonsnivå kan holde tilkoblingen aktiv der det er aktuelt. For gjeldende oppførsel og versjonsspesifikke notater, bruk den offisielle NGINX WebSocket-proxydokumentasjonen .

Trinn 4: Hvordan validerer du løsningen uten å skape et nytt driftsavbrudd?

Test konfigurasjonen før du laster NGINX på nytt:

sudo nginx -t
sudo nginx -s reload

NGINX-dokumenter -tsom en syntaks- og referansefilkontroll, og -s reloadsom signalet som laster inn konfigurasjonen på nytt ved å starte nye arbeidere og stenge ned gamle på en elegant måte.

Bekreft deretter begge lagene på nytt:

curl -i http://127.0.0.1:3000/health
curl -I https://example.com/
Terminal som viser en vellykket nginx-konfigurasjonstest, nginx-påfylling og et HTTP 200-svar fra det offentlige nettstedet
Etter at du har korrigert oppstrømsbanen, test NGINX-konfigurasjonen, last den inn på nytt og bekreft at det offentlige endepunktet returnerer et normalt svar.

Ikke stopp ved «hjemmesiden lastes inn». Test ruten som opprinnelig mislyktes på nytt, inkludert HTTP-metoden og eventuell forespørselstekst. Hvis 502-feilen bare oppstod ved opplastinger, API-kall, store rapporter eller WebSockets, test det samme trafikkmønsteret.

Hva om direkte Node.js-forespørsler fungerer, men NGINX fortsatt returnerer 502?

Det resultatet reduserer problemet betraktelig. Sjekk disse elementene i rekkefølge:

  1. Bekreft den aktive serverblokken. Kjør sudo nginx -Tog sørg for at de forventede server_nameog locationhåndterer forespørselen.
  2. Bekreft det nøyaktige oppstrømsmålet. Adressen i proxy_passmå samsvare med det som er tilgjengelig fra NGINX, ikke bare det som fungerer fra den bærbare datamaskinen eller en annen container.
  3. Sjekk protokollavvik. Hvis oppstrømstjenesten forventer HTTPS, men NGINX bruker http://, eller omvendt, korriger skjemaet og konfigurer deretter oppstrøms TLS med vilje.
  4. Se etter tilbakestillinger av programtilkoblinger. Kontroller Node.js-prosessloggene med samme tidsstempel som NGINX-feilen. Et krasj eller en avbrutt tilkobling krever en løsning på programsiden.
  5. Sjekk spesialisert trafikk. WebSockets, strømmesvar, store forespørsler og uvanlig trege behandlere kan trenge andre proxy-innstillinger enn et enkelt JSON API.

Hvis NGINX og Node.js er atskilt av en brannmur, Kubernetes-tjeneste, lastbalanserer, service mesh eller en annen proxy, er det ikke sikkert at hoppet som mislykkes er den lokale NGINX-til-node-forbindelsen. Test hvert hopp uavhengig i stedet for å anta at den synlige NGINX-serveren er kilden til feilen.

Bør du starte Node.js eller NGINX på nytt først?

En omstart er passende når du har bevis på at en prosess har stoppet, er usunn eller kjører en foreldet konfigurasjon. Det er ikke den beste første diagnostiske handlingen fordi den kan slette ledetråder og midlertidig få et periodisk problem til å forsvinne.

Hvis Node-porten mangler, må du kontrollere prosessbehandleren eller containerloggene dine, rette oppstartsproblemet for programmet, og deretter starte tjenesten. Hvis du bare endret NGINX-konfigurasjonen, må du bruke den nginx -tfør du laster inn på nytt. Hvis du endret Node.js-kode eller miljøvariabler, må du starte Node-tjenesten på nytt ved hjelp av veilederen som distribusjonen din faktisk bruker, for eksempel systemd, en containerorkestrator eller en annen prosessbehandler.

For produksjonsutgivelser av Node.js, må du også bekrefte at du er på en støttet utgivelseslinje. Fra september 2026 viser den offisielle utgivelsessiden for Node.js Node.js 24 og 22 som LTS-linjer, og anbefaler at produksjonsapplikasjoner bruker aktive LTS- eller vedlikeholds-LTS-utgivelser. Sjekk gjeldende status på den offisielle utgivelsessiden for Node.js i stedet for å stole på en gammel veiledning.

En kompakt NGINX 502-beslutningstabell

Test Resultat Sannsynlig retning
curloppstrøms direkte Tilkobling avvist Noden lytter ikke der, feil adresse/port eller feil containernavnerom.
curloppstrøms direkte HTTP 200 Fokuser på NGINX-konfigurasjon, nettverkskontekst, protokoll, overskrifter eller rutespesifikk oppførsel.
NGINX-feillogg Oppstrøms tidsavbrudd Mål tilkoblingsmuligheten og applikasjonens responstid før du endrer tidsavbruddsverdier.
Docker Compose-distribusjon proxy_pass http://127.0.0.1:3000fra NGINX-containeren Bruk navnet på apptjenesten og det delte containernettverket når tjenestene er separate.
Bare WebSocket-ruten mislykkes Vanlige HTTP-ruter fungerer Sjekk oppgradering/videresending av tilkobling og oppførsel ved tidsavbrudd for lesing.
nginx -t Mislykkes Rett syntaks- eller refererte filfeil før innlasting på nytt.

Endelig egenkontroll

Du har sannsynligvis fikset rotårsaken, i stedet for bare å undertrykke symptomet, når alle de følgende er sanne:

  • Node.js-oppstrømsserveren svarer direkte fra den samme nettverkskonteksten som NGINX bruker.
  • Node-lytteren blir proxy_passenige om protokoll, adresse og port.
  • NGINX-feilloggen registrerer ikke lenger oppstrøms tilkoblingsfeil for den berørte ruten.
  • nginx -tlykkes før hver konfigurasjonsinnlasting.
  • Den opprinnelige mislykkede forespørselen – ikke bare hjemmesiden – lykkes nå via NGINX.
  • Tidsavbrudd ble bare endret når logger og målt applikasjonsatferd rettferdiggjorde endringen.
  • Containerdistribusjoner bruker tjeneste-til-tjeneste-nettverk i stedet for å anta at 127.0.0.1de krysser containergrenser.

Det mest pålitelige feilsøkingsmønsteret er derfor: test noden direkte, les NGINX-feilen, match oppstrømsadressen med den faktiske nettverkstopologien, valider og last deretter inn på nytt . En 502 er et gateway-symptom. Det nyttige spørsmålet er alltid hvilket hopp som mislyktes og hva loggen sier om den feilen.

Legg igjen en kommentar

How to Fix "Tailwind CSS Styles Not Updating" in a Vite React App

How to Fix "Tailwind CSS Styles Not Updating" in a Vite React App

Fix Tailwind CSS styles not updating in Vite React by checking Tailwind v4 setup, CSS imports, source detection, dynamic classes, HMR, and stale caches.

Slik fikser du ModuleNotFoundError: Ingen modul kalt 'pip' i Python 3

Slik fikser du ModuleNotFoundError: Ingen modul kalt 'pip' i Python 3

Fiks Python 3s ModuleNotFoundError for pip på Windows, macOS og Linux med ensurepip, OS-pakker, virtuelle miljøer og tolkekontroller.

Slik fikser du «Ingen tillatelse (offentlig nøkkel)» i GitHub SSH

Slik fikser du «Ingen tillatelse (offentlig nøkkel)» i GitHub SSH

Fiks GitHub SSH-tillatelse nektet (offentlig nøkkel) ved å sjekke verten, aktiv SSH-nøkkel, GitHub-konto, SSO-autorisasjon, ekstern URL og port 22-tilgang.

How to Fix “Git Push Rejected: Non-Fast-Forward” Without Losing Changes

How to Fix “Git Push Rejected: Non-Fast-Forward” Without Losing Changes

Fix a Git non-fast-forward push safely. Protect local work, fetch remote commits, choose merge or rebase, resolve conflicts, and push without losing changes.

Slik fikser du "Nginx 502 Bad Gateway" når du bruker proxy til Node.js

Slik fikser du "Nginx 502 Bad Gateway" når du bruker proxy til Node.js

Rett Nginx 502 Bad Gateway-feil med en Node.js-oppstrøm ved å sjekke appporten, NGINX-logger, proxy_pass-adresse, containernettverk, tidsavbrudd og omlasting.

Slik fikser du «Typen 'null' kan ikke tilordnes til type» i TypeScript

Slik fikser du «Typen 'null' kan ikke tilordnes til type» i TypeScript

Rett TypeScripts feilmelding «Typen 'null' kan ikke tilordnes til type» med unionstyper, innsnevring, standardverdier og sikre påstander under strictNullChecks.

Slik fikser du feilen «Prisma Client has not been generated yet»

Slik fikser du feilen «Prisma Client has not been generated yet»

Fiks feilen med at Prisma Client ikke er generert ved å sjekke generatoren, skjemaet, utdatastien, importene, versjonene, monorepo-oppsettet og byggetrinnene ved distribusjon.

Slik fikser du «ERR_MODULE_NOT_FOUND» i Node.js ESM-importer

Slik fikser du «ERR_MODULE_NOT_FOUND» i Node.js ESM-importer

Fiks Node.js ERR_MODULE_NOT_FOUND i ESM ved å sjekke importstier, filtyper, pakkeinstallasjon, eksport, ESM-modus og rene installasjoner.

Slik løser du SSL-sertifikatproblemet: Unable to Get Local Issuer Certificate i Git

Slik løser du SSL-sertifikatproblemet: Unable to Get Local Issuer Certificate i Git

Løs Git-feilmeldingen 'unable to get local issuer certificate' ved å identifisere tillitsbakgrunnen, installere riktig CA-kjede og beholde SSL-verifisering aktivert.

Slik løser du MongoDB nettverksavbrudd i Mongoose-tilkoblingen

Slik løser du MongoDB nettverksavbrudd i Mongoose-tilkoblingen

Løs MongoDB nettverksavbrudd i Mongoose ved å identifisere avbruddstypen, teste Atlas- eller TCP-tilgjengelighet, korrigere URI-en, og justere tidsavbrudd kun når det er berettiget.