Domain

How to Host a Node.js Application on a Linux VPS With a Production-Safe Setup

How to Host a Node.js Application on a Linux VPS With a Production-Safe Setup

How to host a Node.js application on a VPS

To host a Node.js application on a Linux VPS safely, you need more than copying the project files to a server and running @@AICODE0@@. A production setup should use a non-root application user, protected environment variables, a process manager, a reverse proxy, restricted firewall rules, centralised logs, a domain name and HTTPS.

This approach works for many Express, NestJS, Next.js server applications, APIs and other Node.js projects. The exact commands may vary between Ubuntu, Debian and other Linux distributions, but the deployment principles remain similar.

Direct answer: the production deployment path

A typical Node.js VPS deployment follows this sequence:

  1. Create and secure a Linux VPS.
  2. Create a separate user for the application.
  3. Install a supported Node.js release and required system packages.
  4. Upload or clone the application code.
  5. Install production dependencies and build the application.
  6. Store secrets in an environment file outside public web directories.
  7. Run the application with systemd or another reliable process manager.
  8. Configure Nginx as a reverse proxy.
  9. Allow only required ports through the firewall.
  10. Point the domain to the VPS IP address.
  11. Issue an SSL certificate and redirect HTTP traffic to HTTPS.
  12. Test the application, service restart behaviour, logs and renewal process.

A Linux VPS gives you more control than shared hosting, but it also makes you responsible for operating-system updates, application security, firewall configuration, backups and monitoring. If you do not need server-level control, managed Node.js hosting or a suitable shared hosting environment may be simpler. If your application needs custom processes, background workers, specific Node.js versions or long-running services, a VPS is often more flexible.

1. Prepare the Linux VPS

Start with a supported Linux distribution and connect over SSH using an administrative account. Do not run the application as @@AICODE0@@.

Update installed packages before deployment:

@@AICODE0@@

The package command differs on distributions that use @@AICODE0@@ or @@AICODE1@@. You should also confirm that the VPS has enough CPU, memory and storage for the application, its database, build process, logs and future updates.

For a new server, review HostPeppy's related Linux VPS and server-security resources before exposing the VPS to the internet. These are useful internal-link opportunities for explaining SSH hardening, backups, resource planning and server management.

2. Create a dedicated application user

A separate Linux user limits the damage caused by an application error or compromised process. The user should own the application files and run the Node.js service, but it should not have unnecessary administrative privileges.

Example:

@@AICODE0@@

Create an application directory with appropriate ownership:

@@AICODE0@@

@@AICODE0@@

Switch to that user before installing dependencies or running application commands:

@@AICODE0@@

The application user should not be used for unrelated websites or services. Keeping projects separated makes permissions, troubleshooting and future migrations easier.

3. Install Node.js and deploy the application

Install a Node.js release supported by your application. Check the project's @@AICODE0@@, lockfile and framework documentation before selecting the runtime. Avoid installing an unmaintained Node.js version simply because it is available in an old operating-system repository.

After Node.js and npm are available, place the project in the application directory. You can upload an archive, use Git or copy the files through a secure deployment process.

Example Git workflow:

@@AICODE0@@

@@AICODE0@@

Install only the dependencies required at runtime:

@@AICODE0@@

If the application requires a build step, install the dependencies needed for the build, run the build, and then remove development dependencies if the framework supports that workflow:

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

Do not use commands blindly. Some applications require development packages at runtime, while others produce a standalone build directory. Follow the project's deployment instructions.

Confirm how the application starts. Common examples include @@AICODE0@@, @@AICODE1@@, @@AICODE2@@ or a framework-specific command. Test it locally on the VPS before adding Nginx:

@@AICODE0@@

If the application listens on port 3000, test it from the server with a local request:

@@AICODE0@@

A successful local response confirms that the Node.js process is running, but it does not yet prove that DNS, Nginx, the firewall or SSL are configured correctly.

4. Configure environment variables safely

Applications commonly require variables for the database connection, session secret, API keys, application URL, port and runtime mode. These values should not be committed to Git or placed in a publicly accessible web directory.

Create an environment file owned by the application user:

@@AICODE0@@

A basic example may look like this:

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

Use the variable names expected by the application. Do not paste real passwords, API keys or private certificates into articles, tickets or shell history.

Restrict access to the file:

@@AICODE0@@

The application must explicitly load these variables. Some frameworks load @@AICODE0@@ files automatically, while a systemd service may need an @@AICODE1@@ directive. Confirm the behaviour in the framework documentation and test that required variables are available.

For a larger deployment, consider a dedicated secrets-management process rather than storing all secrets in a plain text file. Whatever method you use, ensure that secrets are excluded from backups or logs where appropriate.

5. Use systemd for process management

A terminal session is not a production process manager. If the SSH session closes, a manually started process may stop. The application may also fail to restart after a VPS reboot.

Create a systemd unit as an administrator:

@@AICODE0@@

Example configuration:

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

Change @@AICODE0@@ to match the real entry point and Node.js path on the VPS. If the application must start through npm, use the appropriate command and confirm its path with @@AICODE1@@.

Enable and start the service:

@@AICODE0@@

@@AICODE0@@

Check its status:

@@AICODE0@@

Systemd can restart a failed process and start it after a reboot. It does not replace application-level monitoring, backups or security updates, so those should be planned separately.

6. Configure Nginx as a reverse proxy

Node.js can listen directly on a public port, but Nginx is commonly placed in front of it. Nginx accepts requests for the domain, handles HTTP and HTTPS, and forwards application traffic to a private local port such as @@AICODE0@@.

Install Nginx using your distribution's package manager and create a virtual-host configuration:

@@AICODE0@@

Example:

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

Enable the configuration and test it:

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

The forwarded headers matter because the Node.js application may need to identify the original hostname, client IP or HTTPS protocol. Configure the framework's trusted-proxy setting carefully rather than trusting arbitrary headers from every source.

This is a useful place to link internally to HostPeppy's guides on Nginx, DNS configuration, SSL certificates and website performance.

7. Configure firewall rules

Only expose ports that are required. A common web application needs SSH, HTTP and HTTPS. The Node.js port should normally remain accessible only from the local server when Nginx is handling public traffic.

With UFW, review the existing rules before enabling the firewall:

@@AICODE0@@

Allow SSH using the correct port or provider rule, then allow web traffic:

@@AICODE0@@

@@AICODE0@@

@@AICODE0@@

Enable UFW only after confirming that your SSH access is permitted:

@@AICODE0@@

Do not expose port 3000 publicly unless there is a specific reason. If it is already open, remove the rule or restrict it to trusted sources. Firewall configuration is only one layer of security; the application, operating system, database and credentials must also be protected.

8. Point the domain to the VPS

Create an A record for the domain or subdomain that should serve the application. For example, @@AICODE0@@ should point to the VPS's public IPv4 address. If the VPS has IPv6 and the application is configured for it, an AAAA record may also be appropriate.

DNS changes may not appear everywhere immediately because resolvers cache records according to their TTL. Before requesting SSL, confirm that the domain resolves to the correct VPS and that Nginx answers for the expected hostname.

Useful checks include:

@@AICODE0@@

@@AICODE0@@

Do not point a production domain at a server until the application, firewall and Nginx configuration are ready. For DNS-specific issues, link to HostPeppy's DNS troubleshooting knowledge-base content.

9. Add SSL and redirect HTTP to HTTPS

After DNS resolves correctly, use a certificate tool compatible with your Linux distribution and Nginx configuration. The tool should obtain a certificate for the domain and configure renewal according to the certificate authority's requirements.

After installation, verify both the HTTPS response and automatic renewal process. A certificate that works today is not enough if renewal later fails.

The final request path should be:

@@AICODE0@@ → Nginx → @@AICODE1@@ → Node.js application

The Node.js process can continue listening on localhost while Nginx handles public TLS connections. This reduces direct exposure of the application port and gives you one place to manage web traffic.

10. Check logs and plan updates

When a deployment fails, inspect each layer separately.

For the Node.js service:

@@AICODE0@@

@@AICODE0@@

For Nginx:

@@AICODE0@@

@@AICODE0@@

Also review application-specific logs, database connectivity, memory usage and disk space. A service can be running while requests fail because of an incorrect environment variable, database permission, proxy header or file path.

Use a deployment process that makes updates reversible. Keep the current working version available, test changes before switching traffic and back up application data and configuration. If your VPS is managed by a hosting provider, confirm which server-management and backup responsibilities are included rather than assuming they are automatic.

Common production mistakes

Running Node.js as root

This gives the application more privileges than it needs. Use a dedicated service account instead.

Keeping secrets in Git

Environment files containing passwords or API keys can remain in repository history even after deletion. Rotate exposed credentials and add secret files to @@AICODE0@@.

Starting the app with an SSH command

The process may stop when the shell closes and will not necessarily return after a reboot. Use systemd or an equivalent process manager.

Opening the Node.js port to everyone

If Nginx is the public entry point, bind the application to localhost and keep its port closed externally.

Forgetting the build step

TypeScript, NestJS and some frontend-backed Node.js projects require a build before the production entry point exists.

Incorrect proxy or HTTPS settings

Applications that generate HTTP URLs, reject secure cookies or report the wrong client IP may need trusted-proxy and forwarded-header configuration.

Ignoring disk and memory usage

Build files, logs and database data can fill a small VPS. Set a log-retention policy and monitor available resources.

FAQ

Can I host a Node.js application on shared hosting?

It depends on the hosting environment. Some shared hosting platforms provide Node.js application support, but they may restrict background processes, runtime versions, ports or server configuration. A Linux VPS offers more control but requires more administration.

Should I use PM2 or systemd?

Both can manage Node.js processes. Systemd integrates with the Linux operating system and is suitable for a service-based deployment. PM2 provides Node.js-focused process features. Choose one primary process manager rather than running both for the same application.

Does my Node.js app need Nginx?

Not always. A small internal service may listen directly on a controlled port. Nginx is useful for domain-based routing, HTTPS termination, security controls, static files and forwarding traffic to one or more application processes.

Which VPS resources does a Node.js app need?

The correct CPU, RAM and storage depend on traffic, framework, database workload, build process, background jobs and caching. A simple low-traffic API may need far fewer resources than an e-commerce application or a build-heavy project. Monitor actual usage instead of selecting a VPS solely by price.

Why does the domain show a connection error after deployment?

Check DNS resolution, Nginx server names, firewall ports 80 and 443, the Node.js service status, the local application port and SSL configuration. Testing each layer separately is faster than changing several settings at once.

Is a Linux VPS suitable for developers in India?

It can be suitable when you need root-level configuration, custom Node.js services, background workers or application-specific software. Compare the VPS resources, operating system, management requirements, backup options and support process with your team's technical ability before choosing a plan.

Final checklist

A production-safe Node.js VPS deployment should have a dedicated application user, protected environment variables, a reliable process manager, a reverse proxy, a restricted firewall, working DNS, HTTPS, readable logs, tested restarts and a backup and update plan. HostPeppy's Linux VPS and server-management resources can help with the infrastructure side, but the application owner remains responsible for application code, dependencies and secrets.

Share: