DevOps & Cloud

Nginx Reverse Proxy Configuration for Laravel and Node.js

SC

Sarah Chen

DevOps Lead · May 7, 2026 · 3 min read

Nginx Reverse Proxy Configuration for Laravel and Node.js

Nginx Reverse Proxy Configuration That Holds Under Load

Nginx sits between the internet and your app servers, terminating TLS, serving static assets, and load balancing upstream PHP-FPM or Node processes. Misconfigured buffers and missing security headers cause more outages than application bugs.

Production Server Block

upstream laravel_backend {
    server 127.0.0.1:9000;
    keepalive 32;
}

server {
    listen 443 ssl http2;
    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;

    root /var/www/app/public;
    index index.php;

    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass laravel_backend;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_read_timeout 60s;
    }

    location ~* \.(js|css|png|jpg|svg|woff2)$ {
        expires 30d;
        access_log off;
    }
}

Tuning and Gotchas

  • Set client_max_body_size for file uploads—default 1MB breaks invoices
  • Enable gzip for JSON and SVG, not already-compressed images
  • Use proxy_set_header X-Forwarded-Proto $scheme behind ALB
  • Rate limit login routes with limit_req_zone

Reload with nginx -t && systemctl reload nginx—never restart blindly in production without syntax check.

SSL and HTTP/2 Tuning

Use Mozilla SSL Configuration Generator profiles—Intermediate for most sites, Modern if you drop old Android clients. Enable OCSP stapling to shave TLS handshake latency. Renew Let's Encrypt certs via certbot timer; monitor expiry 30 days ahead.

Separate access and error logs per vhost for easier debugging. Log format including request_time and upstream_response_time identifies whether slowness is nginx, PHP-FPM, or database.

For WebSocket upgrades behind nginx, proxy_http_version 1.1, Upgrade and Connection headers are mandatory. Missing config manifests as connects that work locally but fail in staging behind proxy.

Enable brotli_types including application/json for API responses over 1KB—mobile clients on slow networks benefit measurably. Monitor 499 client closed connection rates; spikes often indicate upstream slowness causing users to abandon before response completes.

High Availability Patterns

Run two nginx instances behind keepalived or cloud load balancer for HA—single nginx VM is SPOF entire site depends on. Health check nginx itself with external monitor hitting static health.html bypassing upstream.

Separate configs per site in sites-enabled with include snippets for SSL params—DRY ssl_protocols definition prevents updating five vhosts individually when TLS guidance changes next year.

Rate-limit login endpoints even on non-WordPress stacks—bots scan universally. A modest limit_req zone cuts brute-force noise and log spam without affecting legitimate users who mistype passwords occasionally.

Logging and Privacy

Mask or omit sensitive query parameters from access logs—tokens in URLs end up in log aggregators and SIEM forever. Use custom log_format including request_id forwarded from application for end-to-end tracing across nginx and PHP-FPM logs during incident response.

Test config with nginx -t in CI before deploy—syntax errors during reload take down entire site if init script does not validate first. Keep previous config file timestamped backup on server for one-command rollback when deploy goes wrong at peak traffic hour.

Map custom error pages for 502/503—default nginx error HTML screams misconfiguration to users; branded maintenance page preserves trust during brief upstream outages while team fixes PHP-FPM pool exhaustion.

Document who approves TLS cipher changes and where configs live in git. Compliance scans flag legacy protocols before enterprise audits; having an owner and runbook saves frantic searches the week before assessors arrive.

Keep a staging vhost mirroring production TLS settings—test cert renewals there before certbot touches live traffic and accidentally breaks chain completeness.

Always run nginx -t before reload.

WebSocket Proxying

For Laravel Echo or Socket.io, add upgrade headers on the proxy location. Log rotation matters—unbounded access logs filled a client's disk in eleven days during a traffic spike.

Map custom 502/503 error pages to branded maintenance screens—default nginx error HTML erodes user trust during brief upstream outages.

Frequently Asked Questions

Nginx vs Apache for Laravel?

Nginx + PHP-FPM handles concurrent connections more efficiently. Apache mod_php is simpler but heavier per connection.

How do I proxy to Node on port 3000?

Use proxy_pass http://127.0.0.1:3000 with WebSocket upgrade headers for Socket.io.

Should I terminate SSL at nginx or ALB?

ALB termination simplifies cert management on AWS. Nginx termination gives more control on VPS setups.

Leave a comment

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Quick Inquiry

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Wait — don't leave yet!

Get a free project consultation. Leave your email and we'll reach out within 24 hours.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Stay ahead in AI & tech

Weekly insights on AI, software, and growth — no spam.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Book a Consultation

Pick a preferred time — we'll confirm by email.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Inquire about

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Request a directory listing

Submit your company details. Our team will review your application and publish your listing after approval.

Contact person

Company details

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Listings are reviewed manually before going live on the directory.