DevOps

Node.js Background Service: PM2, Forever & Systemd Solutions

Learn how to run Node.js applications as background services using PM2, forever, systemd, and nohup. Cross-platform solutions for production deployments.

1 answer 1 view

How do I run a Node.js application as a background service that continues running after closing the terminal? I’ve tried using output redirection with 2>&1 >> file but it doesn’t exit properly, and putting the process in the background doesn’t work either as the process gets killed when I close the terminal. What are the recommended solutions for different platforms?

Running a Node.js application as a background service that persists after terminal closure is a common requirement for production deployments. The most reliable solutions include using process managers like PM2, systemd for Linux, Windows Services for Windows, and supervisor for cross-platform needs. Each approach offers different benefits in terms of restart capabilities, monitoring, and system integration.


Contents


Why Background Processes Fail


When you run a Node.js application in your terminal and then close that terminal, the operating system typically sends a SIGHUP (Hangup) signal to all child processes. This signal tells them that their controlling terminal has been disconnected. Without proper signal handling, most Node.js applications will terminate immediately.

The simple approach of running node server.js & puts the process in the background, but it still has a parent-child relationship with your terminal. When you exit the terminal, the shell sends a SIGHUP to its child processes, causing them to terminate. Even with output redirection like node server.js 2>&1 >> output.log, the process still inherits the terminal’s process group and receives the SIGHUP signal when the terminal closes.

Modern Node.js applications can handle these signals with proper code, but this requires implementing signal handlers and graceful shutdown logic. For most production scenarios, it’s more practical to use dedicated process management tools that handle these issues automatically.


PM2 - The Production Process Manager


PM2 (Process Manager 2) is arguably the most popular and feature-rich solution for managing Node.js applications in production environments. It goes beyond simple process detachment and provides comprehensive process management capabilities.

Installation and Basic Usage

First, install PM2 globally using npm:

bash
npm install pm2 -g

Starting your Node.js application as a background service with PM2 is straightforward:

bash
pm2 start server.js

PM2 automatically handles process detachment, logging, and restarts. The application will continue running even after you close the terminal.

Key PM2 Features

  • Automatic restarts: PM2 monitors your application and restarts it if it crashes
  • Clustering: PM2 can run your application in cluster mode to utilize all CPU cores
  • Logging: All console output is captured and stored in rotating log files
  • Monitoring: Real-time monitoring of application metrics
  • Zero-downtime reloads: Graceful application reloads without service interruption

Advanced Configuration

For more control, you can create an ecosystem configuration file (ecosystem.config.js):

javascript
module.exports = {
 apps: [{
 name: 'my-node-app',
 script: 'server.js',
 instances: 'max', // Use all available CPU cores
 exec_mode: 'cluster',
 autorestart: true,
 watch: false,
 max_memory_restart: '1G',
 env: {
 NODE_ENV: 'development'
 },
 env_production: {
 NODE_ENV: 'production'
 }
 }]
}

Start with this configuration using:

bash
pm2 start ecosystem.config.js --env production

Managing PM2 Processes

PM2 provides a rich set of commands for managing your processes:

bash
# List all running processes
pm2 list

# Monitor processes in real-time
pm2 monit

# Stop a specific process
pm2 stop my-node-app

# Restart a process
pm2 restart my-node-app

# Delete a process
pm2 delete my-node-app

# Save current processes to start on boot
pm2 save
pm2 startup

PM2’s startup command generates and configures an init script to automatically start your processes when the system boots.


Systemd for Linux Services


For Linux systems, systemd provides the most robust and integrated approach to running Node.js applications as system services. systemd is the standard init system for most modern Linux distributions and offers excellent process management, logging, and service lifecycle control.

Creating a Systemd Service File

Create a service file in /etc/systemd/system/:

bash
sudo nano /etc/systemd/system/node-app.service

Add the following configuration:

ini
[Unit]
Description=My Node.js Application
After=network.target

[Service]
User=www-data
Group=www-data
WorkingDirectory=/path/to/your/app
ExecStart=/usr/bin/node server.js
Restart=always
RestartSec=10
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=node-app
Environment=NODE_ENV=production

[Install]
WantedBy=multi-user.target

Key Configuration Elements

  • User/Group: Runs the service as a specific user (not root)
  • WorkingDirectory: Sets the working directory for your application
  • ExecStart: The command to start your application
  • Restart=always: Automatically restarts the service if it fails
  • Environment: Sets environment variables

Managing the Systemd Service

After creating the service file:

bash
# Reload systemd to recognize the new service
sudo systemctl daemon-reload

# Start the service
sudo systemctl start node-app

# Enable the service to start on boot
sudo systemctl enable node-app

# Check service status
sudo systemctl status node-app

# View logs
sudo journalctl -u node-app -f

# Stop the service
sudo systemctl stop node-app

# Disable auto-start on boot
sudo systemctl disable node-app

Advanced Systemd Features

systemd offers many advanced features for production deployments:

ini
# Resource limits
LimitNOFILE=65536
LimitNPROC=4096

# Security settings
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ReadWritePaths=/path/to/data

# Logging
StandardOutput=file:/var/log/node-app/out.log
StandardError=file:/var/log/node-app/error.log

The systemd approach provides excellent integration with the operating system, making it ideal for production Linux deployments.


Forever - Simple Process Management


Forever is a simple, lightweight process manager designed specifically for Node.js applications. It’s easier to set up than PM2 but offers fewer features. Forever is a good choice for simpler applications or when you need a quick solution without complex configuration.

Installation

Install Forever globally:

bash
npm install forever -g

Basic Usage

Starting your application with Forever is straightforward:

bash
forever start server.js

To stop the process:

bash
forever stop server.js

Forever Commands

Forever provides several useful commands:

bash
# List all running Forever processes
forever list

# Monitor processes
forever logs

# Restart a process
forever restart server.js

# Start with specific options
forever start -l forever.log -o out.log -e err.log server.js

# Stop all processes
forever stopall

Configuration File

For more complex setups, you can use a configuration file:

javascript
{
 uid: "myapp",
 script: "server.js",
 sourceDir: "/path/to/app",
 watch: false,
 logFile: "/var/log/myapp/forever.log",
 outFile: "/var/log/myapp/out.log",
 errFile: "/var/log/myapp/error.log",
 args: ["--production"],
 env: {
 NODE_ENV: "production"
 }
}

Start with this configuration using:

bash
forever start -c config.json

Limitations

While Forever is simple to use, it has some limitations compared to more advanced solutions:

  • Less comprehensive monitoring and metrics
  • Limited clustering support
  • Fewer configuration options
  • No built-in zero-dptime reloads

For most production scenarios, PM2 or systemd would be better choices, but Forever remains a viable option for simpler applications or development environments.


Nohup - Basic Terminal Detachment


Nohup (No Hang Up) is a Unix utility that allows commands to continue running after you log out or close the terminal. It’s the simplest approach to detaching processes but offers minimal process management features.

Basic Usage

The basic nohup command:

bash
nohup node server.js &

This command:

  • Runs Node.js in the background (&)
  • Ignores the hangup signal (nohup)
  • Redirects output to a file named nohup.out by default

To specify custom output files:

bash
nohup node server.js > output.log 2>&1 &

Managing Nohup Processes

Nohup doesn’t provide built-in process management, so you’ll need to use system tools:

bash
# Find the process ID
ps aux | grep "node server.js"

# Kill the process
kill <pid>

Using Disown

For better process detachment, you can use disown after starting a process in the background:

bash
node server.js &
disown

Limitations

Nohup has significant limitations for production use:

  • No automatic restarts on crash
  • No monitoring or metrics
  • No log rotation
  • Difficult to manage multiple processes
  • No graceful shutdown handling

While nohup can work for temporary background processes, it’s not recommended for production deployments where reliability and monitoring are important.


Windows Services


On Windows systems, the recommended approach is to run Node.js applications as Windows Services. This provides proper system integration, automatic startup, and service management through the Windows Service Manager.

Using NSSM (Non-Sucking Service Manager)

NSSM is a popular tool for creating Windows services from any executable, including Node.js applications.

Installation

Download NSSM from https://nssm.cc and extract it to a directory in your PATH.

Creating the Service

Open Command Prompt as Administrator and run:

bash
nssm install "My Node App" "C:\Program Files\nodejs\node.exe" "C:\path\to\your\server.js"

This creates a service named “My Node App” that runs your Node.js application.

Configuring the Service

You can configure additional settings:

bash
nssm set "My Node App" AppDirectory "C:\path\to\your"
nssm set "My Node App" AppEnvironmentExtra NODE_ENV=production
nssm set "My Node App" AppStdout "C:\path\to\logs\stdout.log"
nssm set "My Node App" AppStderr "C:\path\to\logs\stderr.log"
nssm set "My Node App" Start SERVICE_AUTO_START

Managing the Service

Use standard Windows service commands:

bash
# Start the service
net start "My Node App"

# Stop the service
net stop "My Node App"

# Delete the service
nssm remove "My Node App" confirm

Using Node.js Service Wrapper

Alternatively, you can use a Node.js-specific service wrapper like node-windows:

bash
npm install node-windows -g

Create a service script:

javascript
const Service = require('node-windows').Service;

const svc = new Service({
 name:'My Node App',
 description: 'My Node.js application as a Windows service',
 script: 'C:\\path\\to\\your\\server.js',
 env: {
 name: "NODE_ENV",
 value: "production"
 }
});

svc.on('install', function(){
 svc.start();
});

svc.install();

Run this script to install and start the service.

Using Windows Service Manager

You can also configure services through the Windows Service Manager (services.msc):

  1. Press Win + R, type services.msc, and press Enter
  2. Right-click and select “Create new service”
  3. Configure the service settings
  4. Set the executable path to your Node.js installation
  5. Add your application path as an argument

Windows Service Advantages

Running as a Windows Service provides:

  • Automatic startup on system boot
  • Integration with Windows Service Manager
  • Proper process isolation
  • Event logging integration
  • Ability to run without user login

Docker Containerization


Docker provides a modern, platform-independent approach to running Node.js applications as background services. Containerization offers consistency across different environments and simplifies deployment.

Creating a Dockerfile

Create a Dockerfile for your application:

dockerfile
# Use the official Node.js runtime
FROM node:18-alpine

# Set working directory
WORKDIR /app

# Copy package files
COPY package*.json ./

# Install dependencies
RUN npm install --production

# Copy application code
COPY . .

# Expose application port
EXPOSE 3000

# Run the application
CMD ["node", "server.js"]

Building and Running the Container

Build your Docker image:

bash
docker build -t my-node-app .

Run the container in detached mode:

bash
docker run -d --name my-app -p 3000:3000 my-node-app

Advanced Docker Configuration

For production, you might want to use Docker Compose:

yaml
version: '3.8'

services:
 node-app:
 build: .
 ports:
 - "3000:3000"
 environment:
 - NODE_ENV=production
 restart: unless-stopped
 volumes:
 - ./logs:/app/logs
 healthcheck:
 test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
 interval: 30s
 timeout: 10s
 retries: 3

Start with Docker Compose:

bash
docker-compose up -d

Docker Advantages

Docker containerization offers several benefits:

  • Consistent environments across development, staging, and production
  • Isolation from the host system
  • Easy scaling with orchestration tools like Kubernetes
  • Simplified deployment and versioning
  • Built-in process management

Monitoring Docker Containers

You can monitor your Node.js application running in Docker:

bash
# View container logs
docker logs my-app

# Follow logs in real-time
docker logs -f my-app

# View running containers
docker ps

# Stop a container
docker stop my-app

# Restart a container
docker restart my-app

For more advanced monitoring, you can integrate tools like Prometheus or Datadog with your Dockerized Node.js applications.


Comparison and Recommendations


When choosing a solution for running Node.js applications as background services, several factors should be considered: development environment, deployment platform, required features, and team expertise.

Feature Comparison

Solution Cross-platform Auto-restart Clustering Monitoring System Integration Learning Curve
PM2 Limited Low
Systemd Linux only Limited Medium
Forever Limited Limited Limited Low
Nohup Limited Very Low
Windows Services Windows only Limited Medium
Docker Limited Medium

Platform-Specific Recommendations

Linux Production Systems:

  • Recommended: Systemd
  • Alternative: PM2
  • Why: Systemd provides the deepest integration with the operating system, offering better security, logging, and system lifecycle management. PM2 is easier to set up but offers less system integration.

Windows Production Systems:

  • Recommended: Windows Services (NSSM)
  • Alternative: PM2
  • Why: Windows Services provides native system integration and management through the Windows Service Manager. PM2 works well but requires more manual configuration.

Development/Testing Environments:

  • Recommended: PM2 or Docker
  • Alternative: Forever
  • Why: PM2 offers easy setup and good development features. Docker provides consistent environments across platforms. Forever is simpler but less feature-rich.

Cross-Platform Requirements:

  • Recommended: PM2 or Docker
  • Alternative: Forever
  • Why: PM2 works consistently across different platforms. Docker provides complete environment isolation. Forever is simpler but lacks advanced features.

Making the Right Choice

Consider these questions when choosing a solution:

  1. What platform are you deploying on?
  • Linux: Systemd for production, PM2 for development
  • Windows: Windows Services
  • Cross-platform: PM2 or Docker
  1. What features do you need?
  • Basic process detachment: Nohup or Forever
  • Auto-restart and monitoring: PM2
  • System integration: Systemd or Windows Services
  • Environment consistency: Docker
  1. What’s your team’s expertise?
  • Unix/Linux experts: Systemd
  • General developers: PM2
  • Containerization experts: Docker
  1. What’s your deployment complexity?
  • Simple applications: Forever or PM2
  • Complex applications: Systemd or Docker with orchestration

Best Practices

Regardless of the solution you choose, follow these best practices:

  1. Always run as a non-root user for security
  2. Configure proper logging with rotation
  3. Set environment variables appropriately for each environment
  4. Implement graceful shutdown handling in your Node.js application
  5. Monitor your applications with appropriate tools
  6. Regularly update dependencies to ensure security
  7. Configure proper resource limits to prevent system overload

Sources


  1. Stack Overflow - How do I run a node.js app as a background service? — Community discussion with multiple working solutions: https://stackoverflow.com/questions/4018154/how-do-i-run-a-node-js-app-as-a-background-service
  2. GeeksforGeeks - How to Run a Node.js App as a Background Service? — Comprehensive guide with forever tool instructions: https://www.geeksforgeeks.org/node-js/how-to-run-a-node-js-app-as-a-background-service/
  3. Iulian Popa - Runing Node JS Server In Background - Detailed systemd configuration for Linux: https://iulianpopa.ro/nodejs/2021/06/04/running-node-js-server-in-background/
  4. Stack Overflow - How to run node js server as a daemon process? - Code examples with multiple approaches including detached processes: https://stackoverflow.com/questions/34490690/how-to-run-node-js-server-as-a-daemon-process/34490924
  5. DigitalOcean - Use PM2 to Setup a Node.js Environment On An Ubuntu VPS - Production-ready PM2 setup with performance comparisons: https://www.digitalocean.com/community/tutorials/how-to-use-pm2-to-setup-a-node-js-production-environment-on-an-ubuntu-vps
  6. Medium - Running a Node.js App as a Background Service - Step-by-step guide for process detachment: https://medium.com/@techclaw/running-a-node-js-app-as-a-background-service-a-step-by-step-guide-c1077c8aa2f7
  7. Dev2QA - How To Run Node JS Server In Background - Simple PM2 command implementation: https://www.dev2qa.com/how-to-run-node-js-server-in-background/
  8. Stack Overflow - How to make a node.js application run permanently? - Basic nohup explanation with practical examples: https://stackoverflow.com/questions/12701259/how-to-make-a-node-js-application-run-permanently
  9. Core Technologies - How to Run Node.js as a Windows Service - Windows-specific service configuration: https://www.coretechnologies.com/products/AlwaysUp/Apps/RunNodeJSAsAService.html
  10. PixelJets - Best way to daemonize node.js process in 2021 - Comprehensive comparison of different approaches: https://pixeljets.com/blog/using-supervisorctl-for-node-processes-common-gotchas/

Conclusion

Running Node.js applications as background services that persist after terminal closure is essential for production deployments. The solution you choose depends on your platform, required features, and team expertise. For Linux systems, systemd provides the deepest integration with the operating system, while Windows Services offers native system management on Windows platforms. PM2 serves as a cross-platform solution with excellent process management features, and Docker provides environment consistency through containerization.

For most production scenarios, systemd on Linux or Windows Services on Windows are the recommended approaches due to their system integration capabilities. PM2 remains an excellent choice for development environments or when you need cross-platform compatibility. While solutions like nohup and forever can work for simple cases, they lack the monitoring, automatic restarts, and system integration needed for robust production deployments.

Regardless of the solution you implement, remember to run your applications as non-root users, configure proper logging, implement graceful shutdown handling, and regularly update your dependencies to ensure reliability and security.

Authors
Verified by moderation
Moderation
Node.js Background Service: PM2, Forever & Systemd Solutions