Urgent.News

What's breaking now, across thousands of outlets.

Tech

Why Your Full-Stack App Breaks in Production (and How Nginx Fixes It)

You've built a full-stack application. On your local machine, everything runs like a charm. React or Next.js is running happily on port 3000, your Node or Express backend is cruising on port 5000, and all your API calls resolve in milliseconds. Then you decide to deploy it to a live VPS. Almost immediately, things fall apart: The dreaded CORS error: Your browser suddenly refuses to make…

You've built a full-stack application. Locally, everything functions perfectly. You have React or Next.js running happily on port 3000 for the frontend, and your Node or Express backend happily operating on port 5000 for the backend. API calls resolve swiftly. However, upon deploying to a live VPS, problems arise immediately. You encounter a dreaded CORS error, mixed content warnings, and exposed internal ports.

This is a common issue faced by many developers when transitioning from local development to a production environment. The root cause lies not in your app code but in how traffic enters your server.

The issue stems from the "localhost illusion". When you're developing locally, your setup appears as follows: Browser ├── http://localhost:3000 (Frontend) └── http://localhost:5000/api (Backend API). Both services exist on your machine, making it tempting to apply wildcard CORS headers on the backend or rely on a dev server proxy.

However, these shortcuts create three major headaches in production. Exposing port 5000 directly leads to security vulnerabilities, SSL management becomes complex with multiple ports, and hardcoding backend URLs in the frontend creates unnecessary overhead and visual clutter.

A reverse proxy acts as a solution to these issues. Instead of direct communication between external users and individual services, a reverse proxy like Nginx acts as a gatekeeper. Positioned on standard public web ports (80 for HTTP, 443 for HTTPS), Nginx routes incoming requests internally, bypassing direct access to your individual services.

When a request comes in, Nginx identifies the URL path and forwards it to the appropriate backend. This setup ensures no CORS issues as both your frontend and backend share the same origin (yourdomain.com). It hides your backend, securing it by binding it locally to 127.0.0.1:5000. Additionally, Nginx handles SSL encryption, simplifying the SSL process and keeping your architecture clean.

Setting up Nginx involves a simple server block configuration. You'll typically place this in /etc/nginx/sites-available/default on Linux. The server block directs web traffic to your frontend on port 3000 and API calls to your backend on port 5000. The trailing slash in the backend's proxy_pass directive is crucial as it determines how the backend interprets the request URL.

Additionally, forwarding headers like X-Real-IP and X-Forwarded-For ensure the backend receives the real IP address of the requester, vital for features like rate limiting and user tracking.

When deploying to a live server, it's essential not to expose internal app ports to the public internet. Instead, keep them on 127.0.0.1 and let Nginx handle routing. Pay close attention to trailing slashes in your proxy_pass rules, as they can cause silent 404 errors. Always test your Nginx configuration with sudo nginx -t before making live changes with sudo nginx -s reload.

Understanding these steps will help you avoid common pitfalls and ensure a smooth transition from local development to a robust production environment.

Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.

Read the original at dev.to →

More in Tech

More from Tuesday 13 October →