NexusCS

forever

Node.js
A simple CLI tool for ensuring that a given Node.js script runs continuously (i.e. forever). Community-maintained process manager for Node.js applications.
process-manager
nodejs
daemon

Getting started

Maintenance Status

⚠️ Community-maintained: The forever maintainer recommends pm2 or nodemon for new installations.

# Recommended alternatives for new projects
npm install -g pm2      # Production (clustering, load balancing)
npm install -g nodemon  # Development (auto-restart)

Installation

# Global installation (CLI)
npm install -g forever
# Local installation (programmatic use)
npm install forever-monitor

Quick Start

# Start a Node.js script as daemon
forever start app.js

# List running processes
forever list

# Stop a process
forever stop app.js

# View logs
forever logs 0

Basic Daemon Setup

# Start with full logging
forever start \
  -l forever.log \
  -o out.log \
  -e err.log \
  -a \
  app.js

This starts app.js as a daemon with:

  • Forever output logged to forever.log
  • stdout logged to out.log
  • stderr logged to err.log
  • Append mode enabled (-a)

Core Commands

Starting Processes

Command Description
forever start app.js Start script as daemon
forever start -c python script.py Start non-Node script
forever start config.json Start from JSON config

Stopping Processes

Command Description
forever stop app.js Stop by script name
forever stop 0 Stop by index
forever stop Uid Stop by unique ID
forever stop Pid Stop by process ID
forever stopall Stop all processes

Restarting Processes

Command Description
forever restart app.js Restart specific process
forever restart 0 Restart by index
forever restartall Restart all processes

Monitoring

Command Description
forever list List running processes
forever logs List log files
forever logs 0 Tail logs for process 0
forever logs app.js Tail logs for app.js
forever cleanlogs Delete all log files

Command Options

Restart Behavior

Option Description
-m MAX Max restart attempts
--minUptime MS Min uptime (default 2000ms)
--spinSleepTime MS Wait between launches
# Limit restart attempts to 5
forever start -m 5 app.js

# Require 10s uptime before considering stable
forever start --minUptime 10000 app.js

# Wait 5s between restart attempts
forever start --spinSleepTime 5000 app.js

Logging Options

Option Description
-l FILE Log forever output
-o FILE Log stdout
-e FILE Log stderr
-a, --append Append to logs
--silent No console output
# Full logging with append
forever start \
  -l logs/forever.log \
  -o logs/out.log \
  -e logs/err.log \
  -a \
  app.js

File Watching

Option Description
-w, --watch Watch file changes
--watchDirectory DIR Top-level directory to watch
--watchIgnore PATTERN Ignore watch patterns
# Auto-restart on file changes (development)
forever start -w app.js

# Watch specific directory
forever start -w --watchDirectory ./src app.js

# Ignore node_modules
forever start -w --watchIgnore 'node_modules/**' app.js

Process Control

Option Description
-c COMMAND Custom command (default: node)
-p PATH Base path for forever files
-t, --killTree Kill child process tree
--killSignal SIGNAL Signal to send (default: SIGKILL)
--uid NAME Custom unique ID
# Run Python script
forever start -c python script.py

# Custom forever files location
forever start -p /var/run/forever app.js

# Graceful shutdown with SIGTERM
forever start --killSignal=SIGTERM app.js

# Kill entire process tree
forever start -t app.js

JSON Configuration

Single Application

{
  "uid": "app",
  "append": true,
  "watch": true,
  "script": "app.js",
  "sourceDir": "/home/user/myapp",
  "logFile": "logs/forever.log",
  "outFile": "logs/out.log",
  "errFile": "logs/err.log"
}
# Start from config
forever start config.json

Multiple Applications

[
  {
    "uid": "api",
    "append": true,
    "watch": false,
    "script": "api/server.js",
    "sourceDir": "/home/user/apps",
    "logFile": "logs/api-forever.log",
    "outFile": "logs/api-out.log",
    "errFile": "logs/api-err.log"
  },
  {
    "uid": "worker",
    "append": true,
    "watch": false,
    "script": "worker/index.js",
    "sourceDir": "/home/user/apps",
    "logFile": "logs/worker-forever.log",
    "outFile": "logs/worker-out.log",
    "errFile": "logs/worker-err.log"
  }
]
# Start all apps from config
forever start config.json

Supported Config Options

Option Type Description
uid String Unique identifier
append Boolean Append to logs
watch Boolean Watch file changes
script String Script to run
sourceDir String Working directory
logFile String Forever log file
outFile String stdout log file
errFile String stderr log file
command String Custom command (e.g., "python")
max Number Max restart attempts
minUptime Number Min uptime in ms
spinSleepTime Number Wait between launches (ms)
killTree Boolean Kill child processes
killSignal String Signal to send on stop

Programmatic API

Basic Usage

const forever = require("forever-monitor");

const child = new forever.Monitor("app.js", {
  max: 3,
  silent: false,
  args: ["--port", "3000"],
});

child.on("exit", function () {
  console.log("app.js has exited after 3 restarts");
});

child.start();

Event Listeners

const child = new forever.Monitor("app.js");

// Process started
child.on("start", function () {
  console.log("Process started");
});

// Process stopped
child.on("stop", function () {
  console.log("Process stopped");
});

// Process restarted
child.on("restart", function () {
  console.log("Process restarted");
});

// Process exited (max restarts reached)
child.on("exit", function () {
  console.log("Process exited");
});

// stdout data
child.on("stdout", function (data) {
  console.log("stdout:", data.toString());
});

// stderr data
child.on("stderr", function (data) {
  console.error("stderr:", data.toString());
});

child.start();

Non-Node Processes

const forever = require("forever-monitor");

// Run Python script
const child = new forever.Monitor("script.py", {
  command: "python",
  args: ["--verbose"],
});

child.start();

Advanced Options

const child = new forever.Monitor("app.js", {
  max: 10, // Max restart attempts
  silent: false, // Log to console
  minUptime: 5000, // 5s min uptime
  spinSleepTime: 2000, // 2s between restarts
  killTree: true, // Kill child processes
  killSignal: "SIGTERM", // Graceful shutdown
  watch: true, // Watch file changes
  watchDirectory: "./src", // Watch directory
  watchIgnoreDotFiles: true, // Ignore dotfiles
  env: {
    // Environment variables
    NODE_ENV: "production",
  },
  cwd: "/app", // Working directory
  logFile: "logs/forever.log",
  outFile: "logs/out.log",
  errFile: "logs/err.log",
  append: true,
});

child.start();

Common Use Cases

Production Daemon

# Full logging, limited restarts, graceful shutdown
forever start \
  -l /var/log/myapp/forever.log \
  -o /var/log/myapp/out.log \
  -e /var/log/myapp/err.log \
  -a \
  -m 10 \
  --minUptime 10000 \
  --spinSleepTime 5000 \
  --killSignal=SIGTERM \
  /app/server.js

Development with Auto-Restart

# Watch files, unlimited restarts
forever start \
  -w \
  --watchDirectory ./src \
  --watchIgnore 'node_modules/**' \
  -a \
  app.js

Multiple Node.js Versions

# Use nvm node version
forever start \
  -c /home/user/.nvm/versions/node/v16.20.0/bin/node \
  app.js

Running with Arguments

# Pass arguments to script
forever start app.js -- --port 8080 --env production

# Pass arguments with options
forever start -a -l logs/forever.log app.js -- --port 8080

Python/Ruby Scripts

# Python script
forever start -c python script.py

# Ruby script
forever start -c ruby script.rb

# With arguments
forever start -c python script.py -- --verbose --config config.yml

Managing Multiple Apps

# Start with unique IDs
forever start --uid "api" api/server.js
forever start --uid "worker" worker/index.js

# List with UIDs
forever list

# Stop by UID
forever stop api
forever stop worker

Log Management

Default Log Location

# Default forever root
~/.forever/

# Log structure
~/.forever/
  ├── forever.log        # Forever daemon output
  ├── <uid>.log          # Per-process logs
  ├── <uid>.out          # stdout
  └── <uid>.err          # stderr

Custom Log Location

# Set FOREVER_ROOT environment variable
export FOREVER_ROOT=/var/log/forever

# Start with custom location
forever start app.js

# Logs now in
/var/log/forever/

Viewing Logs

# List all log files
forever logs

# Tail logs for process 0
forever logs 0

# Tail logs by script name
forever logs app.js

# Tail logs by UID
forever logs myapp

Managing Logs

# Delete all historical logs
forever cleanlogs

# Clean logs then start fresh
forever cleanlogs && forever start -a app.js

# Rotate logs manually (stops all processes!)
forever stopall
forever cleanlogs
forever start config.json

Log Rotation Best Practices

# Use system log rotation (logrotate)
# /etc/logrotate.d/forever
/var/log/myapp/*.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifysempty
    copytruncate
}

Environment Variables

FOREVER_ROOT

# Change location of forever files
export FOREVER_ROOT=/var/run/forever

# Default location
~/.forever/

Using in Scripts

#!/bin/bash
export FOREVER_ROOT=/var/log/forever
export NODE_ENV=production

forever start \
  -a \
  -l forever.log \
  -o out.log \
  -e err.log \
  app.js

Comparison with Alternatives

forever vs pm2 vs nodemon

Feature forever pm2 nodemon
Status Community-maintained ✓ Active ✓ Active
Use Case Simple daemon Production Development
Cluster Mode ✗ No ✓ Yes ✗ No
Load Balancing ✗ No ✓ Yes ✗ No
Process Monitoring Basic Advanced Basic
File Watching ✓ Yes ✓ Yes ✓ Yes
Log Management Basic Advanced Basic
Zero-Downtime Reload ✗ No ✓ Yes ✗ No
Built-in Dashboard ✗ No ✓ Yes ✗ No
Startup Scripts Manual ✓ Built-in ✗ No

Migration Recommendations

# From forever to pm2 (production)
forever stop app.js
pm2 start app.js -i max  # Cluster mode with max CPUs

# From forever to nodemon (development)
forever stop app.js
nodemon app.js

Troubleshooting

Process "Spinning"

Problem: Process crashes within minUptime and stops restarting.

# Increase minUptime threshold
forever start --minUptime 5000 app.js

# Increase wait time between restarts
forever start --spinSleepTime 3000 app.js

# Unlimited restarts (not recommended)
forever start -m -1 app.js

Logs Not Appearing

Problem: Log files empty or not created.

# Ensure append flag is set
forever start -a -l logs/forever.log app.js

# Check file permissions
ls -la logs/

# Verify FOREVER_ROOT
echo $FOREVER_ROOT
forever list

Process Won't Stop

Problem: forever stop doesn't kill process.

# Use killTree to kill child processes
forever start -t app.js

# Use SIGTERM for graceful shutdown
forever start --killSignal=SIGTERM app.js

# Force stop all
forever stopall

# Nuclear option: kill by PID
forever list  # Get PID
kill -9 <PID>

File Watch Not Working

Problem: Changes not triggering restart.

# Specify watch directory explicitly
forever start -w --watchDirectory ./src app.js

# Ignore problematic directories
forever start -w --watchIgnore 'node_modules/**' app.js

# Check if file is in watched directory
forever list  # Shows watch config

Max Restarts Reached

Problem: Process stops after max restarts.

# Check logs for crash reason
forever logs app.js

# Fix issue, then restart
forever start app.js

# Increase max restarts (temporary)
forever start -m 100 app.js

Stale Processes

Problem: Old processes still running after stopall.

# Clean slate
forever stopall
forever cleanlogs
ps aux | grep node  # Verify no orphans

# Restart fresh
forever start config.json

Also see