Apr 08, 2026
Ariffud M.
11min Read
To deploy a Node.js application, you can either follow a general deployment workflow that works across most hosting environments or use hosting-specific options like web app hosting or a virtual private server (VPS).
Node.js deployment means moving your application from a local development machine to a production server where users can access it over the internet.
Proper deployment directly affects how your Node.js application performs under real traffic. A misconfigured server can cause slow response times, unexpected downtime, or security vulnerabilities that expose sensitive data.
Setting up the Node.js production environment correctly from the start helps prevent these issues and keeps the application stable as traffic grows.
The typical Node.js deployment process includes five stages: preparation, hosting selection, environment configuration, deployment, and monitoring.
Here’s what each stage involves:
Deploying a Node.js application follows a universal workflow that works regardless of the hosting provider.
The core process includes preparing the app for production, pushing the code to Git, setting up the server with a process manager, configuring a reverse proxy with HTTPS, and testing the live deployment.
Preparing a Node.js application for deployment means making sure the project includes everything a production server needs to install dependencies and start the app automatically.
Three files form the foundation of a deployment-ready Node.js project: app.js (the main application file), package.json (project metadata, dependencies, and scripts), and .gitignore (files excluded from version control).
Every package your application imports must appear under the dependencies field in package.json. The file tells npm install which packages to download on the server.
If a required package is missing, the application will crash in production even if it worked locally, where the package already existed in node_modules. Here’s an example:
{
"name": "node-deploy-test",
"version": "1.0.0",
"description": "Sample Node.js app for deployment tutorial",
"main": "app.js",
"scripts": {
"start": "node app.js"
},
"dependencies": {
"express": "^4.21.0"
}
}The scripts section defines how hosting platforms and process managers start the application. The “start”: “node app.js” entry tells the server to run app.js as the entry point.
Node.js environment variables store configuration values that change between environments, such as development and production. Use them for values such as port numbers, database credentials, and API keys, rather than hardcoding them in source files.
In the application code, reference these values using process.env:
const PORT = process.env.PORT || 3000;
This line reads the PORT variable if it exists. Otherwise, it defaults to 3000. The same pattern applies to NODE_ENV, which hosting platforms usually set to production automatically.
Keeping configuration in environment variables prevents sensitive data from leaking into your repository. It also lets you change settings for each environment without modifying the code.
Version control is essential for Node.js deployment because it creates a reliable, trackable record of every change to the codebase.
If a deployment introduces a bug, you can revert to the last working commit in seconds, rather than blindly troubleshooting.
Git is the standard version control system, and GitHub is the most common platform for hosting Git repositories. Start by creating a repository on GitHub:

The simplest way to add files is through the browser:
Keep in mind that most operating systems hide dotfiles like .gitignore, so drag-and-drop uploads won’t work. Create the file directly on GitHub instead:
node_modules/
Alternatively, if Git is installed on your computer, you can push all your files, including .gitignore, using Git CLI commands:
cd path/to/node-deploy-test git init git add . git commit -m "Initial commit" git remote add origin https://github.com/your-username/node-deploy-test.git git push -u origin main
Replace your-username with your actual GitHub username.
The Git CLI method works better for ongoing development. Running git push sends only the changes, while browser uploads require you to upload files again.
Setting up the server starts with installing Node.js. You can install it using Node Version Manager (NVM) or a system package manager.
NVM is the better option because it lets you install and switch between multiple Node.js versions without requiring root permissions.
Node.js processes stop when the terminal session closes or when the server reboots. This means a crash can take the application offline until someone manually restarts it.
PM2, a production-grade Node.js process manager, solves this problem. It runs the application as a background daemon and automatically restarts it after failures or server reboots.
At this point, the application runs internally on a port such as 3000, but users still can’t access it through standard web ports like 80 or 443. To expose the application to the public internet, you need to set up a reverse proxy.
A reverse proxy server like NGINX routes public traffic to the Node.js application running on an internal port.
NGINX listens on ports 80 (HTTP) and 443 (HTTPS), accepts incoming requests, and forwards them to localhost:3000 or to whichever port your app uses. Users never interact with the Node.js process directly.
This setup also serves as the termination point for SSL/TLS connections, keeping encryption management separate from your application code.
After configuring the reverse proxy, enable HTTPS using Certbot with a Let’s Encrypt SSL certificate.
After deployment, test the Node.js application by opening a browser and visiting your application’s root URL, for example, http://domain.tld. The main page should load with the expected content.
If you added a health check route, append /health to your application’s URL and confirm it returns JSON output like:
{"status":"healthy","uptime":...}
Next, check the Node.js logs using your process manager. For PM2, the pm2 logs command shows a real-time stream of your application’s output and error messages.
For a broader view, run pm2 monit to open an interactive dashboard. It shows CPU usage, memory consumption, event loop latency, and logs in one place.
As a baseline, a healthy Node.js application typically stays under 50 ms event loop latency, uses around 300–500 MB of memory for a standard Express app, and keeps CPU usage below 70% under normal traffic.
Deploying a Node.js application with web app hosting involves connecting a Git repository, defining build commands, and triggering deployment from a dashboard.
Hostinger Node.js web app hosting provides a managed hosting environment that lets you deploy applications without setting up a server from scratch.
It handles the underlying infrastructure, including server configuration, Node.js installation, process management, and SSL certificates.
It also supports automatic redeployment, so when you push changes to GitHub, the system rebuilds and redeploys your application automatically.
After purchasing a Node.js hosting plan, log in to hPanel using your Hostinger account to create a new application.
Go to Websites → Add website → Node.js Web App.

If you have a Business plan or higher on regular web hosting, you can follow the same steps to create a Node.js application.

Connecting a Git repository links your GitHub project to the Node.js web app hosting environment.
Once connected, every time you update your code on GitHub, the platform pulls the latest version, installs dependencies, and restarts the application automatically.
To connect the repository:


A single hosting plan connects to one GitHub account at a time. All Node.js websites on that plan share the same connection.
If the project files aren’t in a Git repository, select Upload your website files instead and upload a compressed ZIP file. This method doesn’t support automatic redeployment when you update your code.

After you select the repository, the system automatically detects the framework and suggests build settings.

You can adjust these settings if your project needs different values:
Click Deploy to start the build. The system installs dependencies, runs the build command, and starts the Node.js application.
Once deployment finishes, you should see a “Deployment completed” message.

Click Go to Dashboard and open the temporary domain in a new browser tab to confirm the application loads correctly.

The Node.js dashboard in hPanel provides a quick overview of the deployed application, so you can monitor performance and manage settings.
Deploying a Node.js application on a VPS involves connecting to a remote server via SSH, installing Node.js, uploading your application code, setting up a process manager and reverse proxy, and enabling HTTPS.
VPS hosting gives you full control over the server environment so that you can configure everything from the operating system to firewall rules.
This approach requires more setup than managed web app hosting. Still, it gives you direct access to the server for custom configurations, OS-level debugging, and running other services alongside your Node.js application.

Start by creating a VPS instance and connecting to it via SSH. Choose the most recent Ubuntu long-term support (LTS) version, such as 24.04, as the operating system.
Then connect using an SSH client like PuTTY or hPanel’s browser terminal.

After that, complete the initial VPS server setup by updating system packages, configuring the firewall using ufw, and creating a non-root user with sudo privileges for daily use.
To install Node.js on Ubuntu, you can use NVM or a system package manager. Follow these steps if you choose the former:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.2/install.sh | bash
nvm install --lts
node -v
npm -v
Both commands should return version numbers like this:

If you’ve already pushed your application to a GitHub repository, you can transfer the code to the server using Git:
cd /var/www git clone https://github.com/your-username/your-repository.git cd your-repository npm install
Replace your-username and your-repository with your actual GitHub username and repository name.

The npm install command reads package.json and installs all dependencies into the node_modules folder on the server.
Alternatively, you can transfer files directly using the scp command. Open a new terminal window on your computer (not the one connected to the server) and run:
scp -r /local/path/node-deploy-test root@192.0.2.1:/var/www/
Replace /local/path/node-deploy-test with the path to your project folder, root with your server username, and 192.0.2.1 with your server’s IP address.
Hostinger VPS customers can find their server’s IP address in hPanel by going to VPS → Manage → Overview → VPS details.

After the transfer finishes, switch back to the server terminal and run npm install inside the project directory.
Then set the required environment variables before starting the application:
export NODE_ENV=production export PORT=3000
NODE_ENV=production tells frameworks to optimize for performance and disable development features. PORT should match the port your application listens on, as configured in app.js.
Start your Node.js application with PM2 to keep it running in the background.
npm install -g pm2 pm2 start app.js --name "node-app"
pm2 startup pm2 save
pm2 startup generates a system service that launches PM2 on boot. pm2 save persists the current process list so PM2 knows which applications to restart.
ufw allow http ufw allow https

apt update apt install nginx -y
nano /etc/nginx/sites-available/node-app
server {
listen 80;
server_name your-hostname;
location / {
proxy_pass http://localhost:3000;
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;
}
}
This configuration forwards all incoming HTTP requests to the Node.js process on port 3000. The proxy_set_header directives preserve client information and enable WebSocket connections.
ln -s /etc/nginx/sites-available/node-app /etc/nginx/sites-enabled/ rm /etc/nginx/sites-enabled/default
nginx -t systemctl reload nginx

apt install certbot python3-certbot-nginx -y certbot --nginx -d your-hostname
Once done, visit your application’s URL again and confirm that the “Connection is secure” message appears in your browser.
Visit your Node.js application’s URL and confirm the page loads with the expected content. If it doesn’t load, check that NGINX is running with systemctl status nginx and that PM2 shows the app as “online” with pm2 list.

Once the application is live, use PM2 to monitor its runtime behavior:



Press Ctrl + C to exit any of these views.
Best practices for Node.js deployment focus on automation, environment separation, and proactive monitoring to keep production applications stable and secure.
To scale a Node.js application in production, combine server-level strategies with architectural changes that distribute traffic and workload across multiple processes or machines.
Horizontal scaling adds more server instances to handle increased traffic, with a load balancer distributing requests between them.
Vertical scaling increases resources like CPU, RAM, and storage on a single server. It’s simpler to set up, but it has limits because a single machine can only scale so far.
Load balancing distributes requests evenly, preventing any single process from becoming a bottleneck. NGINX can act as a load balancer by defining an upstream block with multiple backend servers and routing traffic between them.
Node.js runs on a single thread by default, so it uses only one CPU core even if the server has more available.
The built-in cluster module solves this by forking the main process into multiple worker processes, usually one per CPU core, all sharing the same server port.
PM2 simplifies clustering with cluster mode. Running pm2 start app.js -i max spawns one worker per available CPU core automatically.
For larger setups, containerization with Docker packages your Node.js application and its dependencies into a portable image that runs consistently across environments.
Tools like Kubernetes manage containers across multiple machines. They handle scaling, rolling updates, health checks, and load balancing automatically.
All of the tutorial content on this website is subject to Hostinger's rigorous editorial standards and values.