aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Tools & DevOps

Nginx Reverse Proxy: je app-server erachter plaatsen

Een nginx reverse proxy opzetten is de meest praktische manier om een stevige poort vóór je applicatieserver te plaatsen in plaats van die rechtstreeks aan het internet bloot te stellen. Of het nu een Node.js-API is, een PHP-FPM-proces dat Laravel bedient of een game-paneel-UI die op poort 8080 luistert: Nginx ontvangt de binnenkomende verzoeken, beëindigt TLS, serveert statische bestanden en stuurt de rest door naar de app erachter. In dit artikel bouwen we stap voor stap een werkende configuratie vanaf nul op, behandelen we de bekende valkuilen en voegen we de fijnafstelling toe die productie nodig heeft.

Wat doet een reverse proxy precies?

Een klassieke proxy staat aan de clientzijde en beheert uitgaand verkeer. Een reverse proxy is het omgekeerde: hij staat aan de serverzijde en verwerkt inkomend verkeer. De client ziet alleen Nginx; hij weet nooit op welke poort, in welke taal of in hoeveel kopieën de backend-app draait. Die abstractie levert je veel op:

  • TLS-terminatie: certificaatbeheer wordt op één punt gecentraliseerd, in Nginx. De app spreekt gewoon HTTP.
  • Eén poort, één domein: je accepteert alles op 80 en 443 en routeert verschillende paden (/api, /admin) naar verschillende backends.
  • Beveiliging: de app-poort blijft dicht naar buiten toe; hij is alleen vanaf localhost bereikbaar.
  • Prestaties: statische bestanden, gzip/brotli-compressie en caching worden rechtstreeks door Nginx afgehandeld.

Installatie en basisconfiguratie

Op Debian/Ubuntu is de installatie een eenregelaar:

sudo apt update
sudo apt install nginx
sudo systemctl enable --now nginx

De netste aanpak is om configuratiebestanden onder /etc/nginx/sites-available/ te bewaren en ze te activeren met een symbolische koppeling naar sites-enabled/. Stel dat je app op 127.0.0.1:3000 draait. Het onderstaande serverblok stuurt alle binnenkomende verzoeken ernaar door:

server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        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;
    }
}

Activeer het bestand, test de configuratie en herlaad:

sudo ln -s /etc/nginx/sites-available/app \
           /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Waarom zijn de proxy-headers zo belangrijk?

De bovenstaande proxy_set_header-regels zijn geen versiering. Op het moment dat Nginx ertussen komt, kan de backend-app de echte client niet meer zien; hij heeft alleen 127.0.0.1 tegenover zich. Geef je niet de juiste headers door, dan verschijnt ieders IP als localhost in je logs, houdt je app HTTPS voor HTTP en belandt in een oneindige redirect-lus, of breken de sessiecookies.

  • X-Forwarded-For draagt het echte client-IP.
  • X-Forwarded-Proto vertelt de app dat het verzoek eigenlijk HTTPS was; veilige cookies en correcte URL-generatie zijn ervan afhankelijk.
  • Het behouden van de Host-header laat de app de juiste host zien in opstellingen met meerdere domeinen.

Vergeet in frameworks zoals Laravel niet de trusted proxy-instelling te configureren zodat deze headers worden gehonoreerd; anders worden de X-Forwarded-*-headers genegeerd.

HTTPS en TLS-terminatie

De grootste kracht van een reverse proxy is dat het certificaat op één plek wordt gecentraliseerd. Certbot is de praktischste tool om een gratis Let's Encrypt-certificaat te krijgen:

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d app.example.com

Certbot voegt automatisch het 443-blok, de certificaatpaden en de omleiding van 80 naar 443 toe. Wil je het handmatig schrijven, dan ziet het skelet er zo uit:

server {
    listen 443 ssl;
    server_name app.example.com;

    ssl_certificate     /etc/letsencrypt/live/app.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host              $host;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Omdat je TLS bij Nginx beëindigt, mag de verbinding naar de backend gewoon HTTP zijn; over localhost is dat volkomen veilig en het verlost de app van elke certificaatzorg.

WebSocket, time-outs en caching

Realtime-apps (chat, live dashboards, een gameconsole) gebruiken WebSocket. Om Nginx de verbinding te laten upgraden, zijn twee headers vereist:

location /ws {
    proxy_pass http://127.0.0.1:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade    $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 3600s;
}

Bij langlopende verzoeken kan de standaard proxy_read_timeout van 60 seconden je misleiden; het genereren van een zwaar rapport wordt halverwege afgebroken. Voor statische inhoud beantwoordt het gebruik van Nginx' eigen cache of de expires-directive het verzoek zonder ooit de backend te bereiken, wat de app ontlast.

Loadbalancing en meerdere backends

Wanneer één app-instantie niet genoeg is, definieer je meerdere processen als één pool met een upstream-blok:

upstream app_pool {
    server 127.0.0.1:3000;
    server 127.0.0.1:3001;
}

server {
    listen 80;
    location / {
        proxy_pass http://app_pool;
    }
}

Standaard verdeelt Nginx verzoeken om de beurt (round-robin); met least_conn kiest hij degene met de minste verbindingen, en met ip_hash stuurt hij dezelfde client altijd naar dezelfde backend. Dit is ook de basis voor implementaties zonder downtime (blauw-groen).

Veelgestelde vragen

Zijn een reverse proxy en een loadbalancer hetzelfde?

Niet helemaal. Elke loadbalancer gedraagt zich als een reverse proxy, maar niet elke reverse proxy hoeft de belasting te verdelen. Nginx kan beide: met één backend is het gewoon een proxy, en met meerdere backends en een upstream wordt het een loadbalancer.

Hoe los ik een 502 Bad Gateway-fout op?

Een 502 betekent bijna altijd dat de backend niet draait of dat het adres/de poort in proxy_pass verkeerd is. Bevestig met ss -ltnp dat de app echt luistert en bekijk /var/log/nginx/error.log.

Moet ik TLS bij de backend beëindigen?

In de meeste opstellingen niet. TLS bij Nginx beëindigen en via localhost gewoon HTTP spreken is zowel eenvoudiger als veilig. Alleen in strikte compliance-scenario's, waar intern verkeer over het netwerk ook versleuteld moet zijn, overweeg je end-to-end-TLS.

Wil je je infrastructuur achter Nginx plaatsen? We kunnen samen een stevige reverse proxy-opstelling ontwerpen, inclusief TLS, caching en implementaties zonder downtime. Neem contact met me op en laten we over je project praten.

Bu kategorideki tüm yazılar →

Devamı için