Background
Deploying a full-stack applications built in React, Node.js, and Next.js on a single server using Nginx involves a series of steps to ensure smooth operation. Here's a concise guide:
Since it's a deployment tutorial, I assume you already have your applications up and running in development mode. If you don't have it, just create a hello world apps on each platform.
For this deployment tutorial, we will be using Nginx as a revers-proxy server to handle and redirect request to different applications from a single server.
NGINX Reverse Proxy

Fig [1.1]: Nginx as a reverse proxy server
Let's breakdown what's happening in the fig [1.1]:
Request/Response flow through Nginx:
- Client sends the request from browser
- Request is intercepted by Nginx Server and depending on the request details it resolves to one of three servers
- Request is processed inside application server
- Response goes back to the Nginx Server
- Nginx serves the requested content to the client
Now, let's dive into the deployment. First of all, we need a deployment server (Can use Free AWS server) and install following packages on that server.
- Node JS: Install Node JS
- Nginx: Install Nginx in Ubuntu
- Git (Pull code into deployment server): Install Git
- Install PM2:
sudo npm install pm2@latest -g
- Database (MongoDB) - Only if you are using database
Once you have everything installed, Login to your deployment server (lets say AWS EC2) using your credentials ssh -i aws_credential.pem ubuntu@SERVER_IP_ADDRESS
Once you are logged in to your server, clone your projects into that server from Github (or any other service you are using.
Now change directory and install npm packages to run your node application at any suitable port, say 7777 and map this port to deployment server IP using Nginx.
To do that, go to directory cd /etc/nginx/sites-available
and run sudo nano default
. You should see the nginx configuration file there. Delete everything and paste following configuration to deploy Node JS application.
Deploy Node JS App
# Node JS Backend
server {
underscores_in_headers on; # used to pass access_token in header
server_name SERVER_IP_ADDRESS; # Eg: 16.34.453.43
location / {
proxy_pass http://127.0.0.1:7777;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
And then restart Nginx with the command sudo service nginx restart
then check your SERVER_IP in the browser, it should be there.
Deploy React JS App
To deploy React application we just need to pull the latest code from Github or any other service you use and build using the command npm run build
or yarn build
. It will create a static build folder which we can be served through Nginx by symply pointing file location as a root inside server block of Nginx.
#Raect JS Admin
server {
root /var/www/example/build;
index index.html index.htm app.js;
server_name admin.example.com www.admin.example.com;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Deploy Next JS app
Deploying Next JS application is quite similar with running Node JS application. We just need to build with command yarn build
and run the project (Will run with PM2 command at the end of this article) and map the port inside config file as follows.
# Next JS Website
server {
server_name example.com www.example.com;
location / {
proxy_pass http://127.0.0.1:3000; # Next JS Website
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Altogether, we will have follwing Nginx configuration in a single file.
# Node JS Backend
server {
underscores_in_headers on; # used to pass access_token in header
server_name api.example.com;
location / {
proxy_pass http://127.0.0.1:7777;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
#Raect JS Admin
server {
root /var/www/example/build;
index index.html index.htm app.js;
server_name admin.example.com www.admin.example.com;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
# Next JS Website
server {
server_name example.com www.example.com;
location / {
proxy_pass http://127.0.0.1:3000; # Next JS Website
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Each application deployed so far will work fine untill we exit from our deployment server. And the reason is, we are not using any process manager to run the application in background. As soon as we close/shut down the server the application processes are terminated and the app will go down. To overcome this issue, there is a package called pm2, which helps us to run applications, monitor and see logs in production.
To install pm2 simply paste the following code inside your server:
yarn global add pm2 // using yarn
npm install pm2 -g // using npm
Finally, we can run our applications using PM2:
Node Js App: pm2 start app.js --name 'APP_NAME'
Next Js App: pm2 start "npm run start" --name 'APP_NAME'
All set! Now restart the Nginx service (sudo service nginx restart) to apply changes, all applications would be deployed successfully and work even after closing/exiting from the server.
If you are here, hopefully it's working for you. If you still have some issue feel free to reach out to me. I am mostly active on Twitter.
Happy Coding ;)
Binod Chaudhary

Software Engineer | Full-Stack Developer