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:
npm install pm2 -g
Starting your Node.js application as a background service with PM2 is straightforward:
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):
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:
pm2 start ecosystem.config.js --env production
Managing PM2 Processes
PM2 provides a rich set of commands for managing your processes:
# 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/:
sudo nano /etc/systemd/system/node-app.service
Add the following configuration:
[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:
# 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:
# 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:
npm install forever -g
Basic Usage
Starting your application with Forever is straightforward:
forever start server.js
To stop the process:
forever stop server.js
Forever Commands
Forever provides several useful commands:
# 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:
{
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:
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:
nohup node server.js &
This command:
- Runs Node.js in the background (
&) - Ignores the hangup signal (
nohup) - Redirects output to a file named
nohup.outby default
To specify custom output files:
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:
# 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:
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:
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:
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:
# 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:
npm install node-windows -g
Create a service script:
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):
- Press
Win + R, typeservices.msc, and press Enter - Right-click and select “Create new service”
- Configure the service settings
- Set the executable path to your Node.js installation
- 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:
# 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:
docker build -t my-node-app .
Run the container in detached mode:
docker run -d --name my-app -p 3000:3000 my-node-app
Advanced Docker Configuration
For production, you might want to use Docker Compose:
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:
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:
# 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:
- What platform are you deploying on?
- Linux: Systemd for production, PM2 for development
- Windows: Windows Services
- Cross-platform: PM2 or Docker
- 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
- What’s your team’s expertise?
- Unix/Linux experts: Systemd
- General developers: PM2
- Containerization experts: Docker
- 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:
- Always run as a non-root user for security
- Configure proper logging with rotation
- Set environment variables appropriately for each environment
- Implement graceful shutdown handling in your Node.js application
- Monitor your applications with appropriate tools
- Regularly update dependencies to ensure security
- Configure proper resource limits to prevent system overload
Sources
- 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
- 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/
- 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/
- 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
- 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
- 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
- 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/
- 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
- Core Technologies - How to Run Node.js as a Windows Service - Windows-specific service configuration: https://www.coretechnologies.com/products/AlwaysUp/Apps/RunNodeJSAsAService.html
- 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.