586

由于这篇文章多年来受到了很多关注,我在这篇文章的底部列出了每个平台的顶级解决方案。


原帖

我希望我的 node.js 服务器在后台运行,即:当我关闭终端时,我希望我的服务器继续运行。我已经用谷歌搜索了这个并想出了这个教程,但是它没有按预期工作。因此,我没有使用该守护程序脚本,而是认为我只是使用了输出重定向(2>&1 >> file部分),但这也没有退出 - 我在终端中得到一个空行,就像它正在等待输出/错误一样。

我也尝试将进程置于后台,但是一旦我关闭终端,进程也会被终止。

那么,当我关闭本地计算机时,如何让它继续运行呢?


顶级解决方案

4

28 回答 28

534

Copying my own answer from How do I run a Node.js application as its own process?

2015 answer: nearly every Linux distro comes with systemd, which means forever, monit, PM2, etc are no longer necessary - your OS already handles these tasks.

Make a myapp.service file (replacing 'myapp' with your app's name, obviously):

[Unit]
Description=My app

[Service]
ExecStart=/var/www/myapp/app.js
Restart=always
User=nobody
# Note Debian/Ubuntu uses 'nogroup', RHEL/Fedora uses 'nobody'
Group=nogroup
Environment=PATH=/usr/bin:/usr/local/bin
Environment=NODE_ENV=production
WorkingDirectory=/var/www/myapp

[Install]
WantedBy=multi-user.target

Note if you're new to Unix: /var/www/myapp/app.js should have #!/usr/bin/env node on the very first line and have the executable mode turned on chmod +x myapp.js.

Copy your service file into the /etc/systemd/system.

Start it with systemctl start myapp.

Enable it to run on boot with systemctl enable myapp.

See logs with journalctl -u myapp

This is taken from How we deploy node apps on Linux, 2018 edition, which also includes commands to generate an AWS/DigitalOcean/Azure CloudConfig to build Linux/node servers (including the .service file).

于 2015-03-13T22:23:06.197 回答
247

您可以使用 Forever,一个简单的 CLI 工具,用于确保给定节点脚本连续运行(即永远): https ://www.npmjs.org/package/forever

于 2011-03-18T01:49:17.443 回答
234

更新- 正如以下答案之一所述,PM2永远缺少一些非常好的功能。考虑使用它。

原始答案

使用nohup

nohup node server.js &

编辑我想补充一点,接受的答案确实是要走的路。我永远在需要熬夜的实例上使用。我喜欢这样做npm install -g forever,它在节点路径中,然后就这样做forever start server.js

于 2010-10-25T19:43:12.920 回答
72

这可能不是公认的方式,但我用屏幕来做,尤其是在开发过程中,因为我可以把它恢复过来并在必要时愚弄它。

screen
node myserver.js
>>CTRL-A then hit D

屏幕将分离并在您注销后继续存在。然后您可以通过 screen -r 将其取回。点击屏幕手册了解更多详情。如果您愿意,您可以命名屏幕等等。

于 2010-10-25T19:42:57.867 回答
68

2016 更新: node-windows/mac/linux 系列使用跨所有操作系统的通用 API,因此它绝对是一个相关的解决方案。然而; node-linux 生成 systemv 初始化文件。随着 systemd 继续流行,它实际上是 Linux 上的更好选择。如果有人想向 node-linux 添加 systemd 支持,欢迎 PR :-)

原帖:

这是一个相当古老的线程,但node-windows提供了另一种在 Windows 上创建后台服务的方法。它松散地基于在节点脚本周围nssm使用exe包装器的概念。然而; 它winsw.exe改为使用并提供一个可配置的节点包装器,以更精细地控制进程在失败时如何启动/停止。这些过程与任何其他服务一样可用:

在此处输入图像描述

该模块还包含一些事件日志记录:

在此处输入图像描述

守护您的脚本是通过代码完成的。例如:

var Service = require('node-windows').Service;

// Create a new service object
var svc = new Service({
  name:'Hello World',
  description: 'The nodejs.org example web server.',
  script: 'C:\\path\\to\\my\\node\\script.js'
});

// Listen for the "install" event, which indicates the
// process is available as a service.
svc.on('install',function(){
  svc.start();
});

// Listen for the "start" event and let us know when the
// process has actually started working.
svc.on('start',function(){
  console.log(svc.name+' started!\nVisit http://127.0.0.1:3000 to see it in action.');
});

// Install the script as a service.
svc.install();

该模块支持限制重启(所以糟糕的脚本不会占用您的服务器)和增加重启之间的时间间隔。

由于 node-windows 服务与其他任何服务一样运行,因此可以使用您已经使用的任何软件来管理/监视服务。

最后,没有make依赖关系。换句话说,直截了当的npm install -g node-windows就行了。您不需要 Visual Studio、.NET 或 node-gyp magic 来安装它。此外,它是 MIT 和 BSD 许可的。

完全公开,我是这个模块的作者。它旨在减轻 OP 所经历的确切痛苦,但更紧密地集成到操作系统已经提供的功能中。我希望未来有同样问题的观众会发现它很有用。

于 2013-03-25T14:03:13.813 回答
41

如果您只是想不间断地运行脚本直到它完成,您可以使用nohup这里的答案中已经提到的。但是,没有一个答案提供了一个完整的命令,该命令也记录stdinstdout.

nohup node index.js >> app.log 2>&1 &
  • 手段>>附加到.app.log
  • 2>&1确保错误也被发送到stdout并添加到app.log.
  • 结尾&确保您当前的终端与命令断开连接,以便您可以继续工作。

如果您想运行节点服务器(或在服务器重新启动时应该启动的东西),您应该使用systemd / systemctl

于 2017-10-13T15:05:26.327 回答
31

更新:我更新以包括来自 pm2 的最新信息:

对于许多用例,使用 systemd 服务是管理节点进程的最简单和最合适的方法。对于那些在单一环境中运行多个节点进程或独立运行节点微服务的人来说,pm2 是一个功能更全的工具。

https://github.com/unitech/pm2

http://pm2.io

  • 它有一个非常有用的监控功能->漂亮的'gui'用于命令行监控多个进程pm2 monit或进程列表pm2 list
  • 有组织的日志管理 ->pm2 logs
  • 其他的东西:
    • 行为配置
    • 源地图支持
    • 兼容 PaaS
    • 观看并重新加载
    • 模块系统
    • 最大内存重载
    • 集群模式
    • 热重载
    • 开发工作流程
    • 启动脚本
    • 自动完成
    • 部署工作流程
    • 关键指标监控
    • API
于 2013-06-09T02:45:16.653 回答
22

如果您使用的是 nohup,请尝试运行此命令 -

nohup npm start 2>/dev/null 1>/dev/null&

你也可以用forever来启动服务器

forever start -c "npm start" ./ 

PM2还支持npm start

pm2 start npm -- start
于 2016-03-02T04:22:40.880 回答
20

如果您正在运行 OSX,那么生成真正系统进程的最简单方法是使用launchd启动它。

像这样构建一个plist,并把它放到/Library/LaunchDaemons 中,名称为top-level-domain.your-domain.application.plist(放置时需要root):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>top-level-domain.your-domain.application</string>

    <key>WorkingDirectory</key>
    <string>/your/preferred/workingdirectory</string>

    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/bin/node</string>
        <string>your-script-file</string>
    </array>

    <key>RunAtLoad</key>
    <true/>

    <key>KeepAlive</key>
    <true/>

</dict>
</plist>

完成后,发出这个(作为根):

launchctl load /Library/LaunchDaemons/top-level-domain.your-domain.application.plist
launchctl start top-level-domain.your-domain.application

你正在跑步。

重新启动后您仍将运行。

对于 plist 中的其他选项,请查看此处的手册页:https ://developer.apple.com/library/mac/documentation/Darwin/Reference/Manpages/man5/launchd.plist.5.html

于 2014-09-23T15:00:07.450 回答
13

我只是使用守护进程npm 模块:

var daemon = require('daemon');

daemon.daemonize({
    stdout: './log.log'
  , stderr: './log.error.log'
  }
, './node.pid'
, function (err, pid) {
  if (err) {
    console.log('Error starting daemon: \n', err);
    return process.exit(-1);
  }
  console.log('Daemonized successfully with pid: ' + pid);

  // Your Application Code goes here
});

最近我也在使用TJ Holowaychuk的mon(1)来启动和管理简单的节点应用程序。

于 2012-07-24T14:21:00.337 回答
12

我使用主管进行开发。它只是工作。每当您对 .js 文件进行更改时,Supervisor 会自动重新启动您的应用程序并加载这些更改。

这是其 Github 页面的链接

安装 :

sudo npm 安装主管 -g

您可以使用 -e 轻松使其观看其他扩展。我经常使用的另一个命令是 -i 来忽略某些文件夹。

即使在您注销后,您也可以使用 nohup 和 supervisor 让您的节点应用程序在后台运行。

sudo nohup 主管 myapp.js &

于 2013-07-16T17:25:05.090 回答
7

Node.js 作为WINDOWS XP中的后台服务

  • 向 Hacksparrow 致敬:http ://www.hacksparrow.com/install-node-js-and-npm-on-windows.html用于安装 Node.js + npm for windows 的教程。
  • 感谢Tatham Oddie,网址为:http : //blog.tatham.oddie.com.au/2011/03/16/node-js-on-windows/ 用于 nnsm.exe 实施。

安装:

  1. 通过安装程序可执行文件安装 WGET http://gnuwin32.sourceforge.net/packages/wget.htm
  2. 通过安装程序可执行文件安装 GIT http://code.google.com/p/msysgit/downloads/list
  3. 通过将 nnsm.exe 复制到 %windir%/system32 文件夹来安装 NSSM http://nssm.cc/download/?page=download
  4. 创建 c:\node\helloworld.js

    // http://howtonode.org/hello-node
    var http = require('http');
    var server = http.createServer(function (request, response) {
        response.writeHead(200, {"Content-Type": "text/plain"});
        response.end("Hello World\n");
    });
    server.listen(8000);
    console.log("Server running at http://127.0.0.1:8000/");
    
  5. 打开命令控制台并输入以下内容(仅在安装了资源工具包时才设置)

    C:\node> set path=%PATH%;%CD%
    C:\node> setx path "%PATH%"
    C:\node> set NODE_PATH="C:\Program Files\nodejs\node_modules"
    C:\node> git config --system http.sslcainfo /bin/curl-ca-bundle.crt    
    C:\node> git clone --recursive git://github.com/isaacs/npm.git    
    C:\node> cd npm    
    C:\node\npm> node cli.js install npm -gf   
    C:\node> cd ..    
    C:\node> nssm.exe install node-helloworld "C:\Program Files\nodejs\node.exe" c:\node\helloworld.js    
    C:\node> net start node-helloworld
    
  6. 一个漂亮的批处理好东西是创建 c:\node\ServiceMe.cmd

    @echo off
    nssm.exe install node-%~n1 "C:\Program Files\nodejs\node.exe" %~s1
    net start node-%~n1
    pause
    

服务管理:

  • 现在可以通过 Start-> Run-> services.msc 或通过 Start->Run-> MSCONFIG-> Services 访问服务本身(并选中“隐藏所有 Microsoft 服务”)。
  • 该脚本将为通过批处理脚本创建的每个节点添加“node-”前缀。
  • 同样,它们可以在注册表中找到:“ HKLM\SYSTEM\CurrentControlSet\Services\node-xxxx
于 2012-10-18T16:26:26.650 回答
7

接受的答案可能是最好的生产答案,但是为了快速进行开发工作,我发现了这个:

nodejs scriptname.js &没用,因为 nodejs 似乎吞噬了 &,所以这件事并没有让我在没有 scriptname.js 死亡的情况下继续使用终端。

但是我放入nodejs scriptname.js了一个 .sh 文件,然后 nohup sh startscriptname.sh &就开始工作了。

绝对不是生产的东西,但它解决了“我需要继续使用我的终端并且不想启动 5 个不同的终端”的问题。

于 2016-03-22T18:47:05.963 回答
5

如果您在 linux 服务器上运行 nodejs,我认为这是最好的方法。

创建服务脚本并复制到 /etc/init/nodejs.conf

启动服务:sudo service nodejs start

停止服务:sudo service nodejs stop

服务脚本

description "DManager node.js server - Last Update: 2012-08-06"
author      "Pedro Muniz - pedro.muniz@geeklab.com.br"

env USER="nodejs" #you have to create this user 
env APPNAME="nodejs" #you can change the service name
env WORKDIR="/home/<project-home-dir>" #set your project home folder here
env COMMAND="/usr/bin/node <server name>" #app.js ?

# used to be: start on startup
# until we found some mounts weren't ready yet while booting:
start on started mountall
stop on shutdown

# Automatically Respawn:
respawn
respawn limit 99 5

pre-start script
    sudo -u $USER echo "[`date -u +%Y-%m-%dT%T.%3NZ`] (sys) Starting" >> /var/log/$APPNAME.log
end script

script
    # Not sure why $HOME is needed, but we found that it is:
    export HOME="<project-home-dir>"  #set your project home folder here
    export NODE_PATH="<project node_path>"

    #log file, grant permission to nodejs user
    exec start-stop-daemon --start --make-pidfile --pidfile /var/run/$APPNAME.pid --chuid $USER --chdir $WORKDIR --exec $COMMAND >> /var/log/$APPNAME.log 2>&1
end script

post-start script
   # Optionally put a script here that will notifiy you node has (re)started
   # /root/bin/hoptoad.sh "node.js has started!"
end script

pre-stop script
    sudo -u $USER echo "[`date -u +%Y-%m-%dT%T.%3NZ`] (sys) Stopping" >> /var/log/$APPNAME.log
end script
于 2014-09-03T12:46:42.527 回答
5

2017 年 6 月更新:
Linux 解决方案:(红帽)。以前的评论对我不起作用。这适用于我在 Amazon Web Service - Red Hat 7 上。希望这适用于那里的人。

A. Create the service file 
sudo vi /etc/systemd/system/myapp.service
[Unit]
Description=Your app
After=network.target

[Service]
ExecStart=/home/ec2-user/meantodos/start.sh
WorkingDirectory=/home/ec2-user/meantodos/

[Install]
WantedBy=multi-user.target

B. Create a shell file
/home/ec2-root/meantodos/start.sh
#!/bin/sh -
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to 8080
npm start

then:
chmod +rx /home/ec2-root/meantodos/start.sh
(to make this file executable)

C. Execute the Following

sudo systemctl daemon-reload
sudo systemctl start myapp
sudo systemctl status myapp

(If there are no errors, execute below.  Autorun after server restarted.)
chkconfig myapp -add
于 2017-06-27T10:40:30.870 回答
3

使用nssm是 windows 的最佳解决方案,只需下载nssm,打开 cmd 到 nssm 目录并输入

nssm install <service name> <node path> <app.js path> 

eg: nssm install myservice "C:\Program Files\nodejs" "C:\myapp\app.js" 

这将安装一个新的 Windows 服务,该服务将在services.msc中列出,您可以从那里启动或停止该服务,该服务将自动启动,您可以配置在失败时重新启动。

于 2014-03-21T12:20:03.617 回答
2

为了完善建议的各种选项,这里还有一个:daemonGNU/Linux 中的命令,您可以在此处阅读:http: //libslack.org/daemon/manpages/daemon.1.html。(如果上述评论之一已经提到这一点,我们深表歉意)。

于 2013-06-04T04:16:08.017 回答
2

由于我在提供的答案列表中缺少此选项,我想从 2020 年开始添加一个符合条件的选项:docker或任何等效的 容器平台。除了确保您的应用程序在稳定的环境中运行之外,还有其他安全优势以及改进的可移植性。

Docker 支持 Windows、macOS 和大多数/主要 Linux 发行版。在受支持的平台上安装 docker相当简单且有据可查。设置 Node.js 应用程序就像将其放入容器并运行该容器一样简单,同时确保它在关闭后重新启动。

创建容器镜像

假设您的应用程序在该服务器上的/home/me/my-app中可用,请在文件夹/home/me中创建一个文本文件Dockerfile ,其内容类似于以下内容:

FROM node:lts-alpine
COPY /my-app/ /app/
RUN cd /app && npm ci
CMD ["/app/server.js"]

它正在为在 Alpine Linux 下运行 LTS 版本的 Node.js 创建一个映像,将应用程序的文件复制到该映像中并运行npm ci以确保依赖项与该运行时上下文匹配。

在包含内容的同一文件夹中创建另一个文件.dockerignore

**/node_modules

这将防止您的主机系统的现有依赖项被注入到容器中,因为它们可能无法在那里工作。Dockerfile中提供的RUN命令将解决这个问题。

使用如下命令创建图像:

docker build -t myapp-as-a-service /home/me

-t选项是选择构建容器图像的“名称”。这用于下面运行的容器。

注意:最后一个参数是选择包含该 Dockerfile 的文件夹,而不是 Dockerfile 本身。您可以使用 option 选择不同的-f

启动容器

使用此命令启动容器:

docker run -d --restart always -p 80:3000 myapp-as-a-service

此命令假设您的应用程序正在侦听端口 3000,并且您希望它在主机的端口 80 上公开。

这当然是一个非常有限的例子,但它是一个很好的起点。

于 2020-01-01T10:12:21.843 回答
1

看看赋格!除了启动许多工人之外,您还可以妖魔化您的节点进程!

http://github.com/pgte/fugue

于 2010-10-26T05:10:05.560 回答
1

对于使用较新版本的守护进程npm 模块的人 - 您需要传递文件描述符而不是字符串:

var fs = require('fs');
var stdoutFd = fs.openSync('output.log', 'a');
var stderrFd = fs.openSync('errors.log', 'a');
require('daemon')({
    stdout: stdoutFd, 
    stderr: stderrFd
});
于 2018-10-13T18:49:44.480 回答
1

有没有人注意到 "2>&1" 位置的一个小错误?

2>&1 >> file

应该

>> file 2>&1
于 2016-02-20T13:49:56.320 回答
1

我很惊讶没有人提到Guvnor

我一直在尝试,pm2 等。但是,当谈到可靠的控制和基于 Web 的性能指标时,我发现Guvnor是迄今为止最好的。另外,它也是完全开源的。

在此处输入图像描述

编辑:但是,我不确定它是否适用于 Windows。我只在linux上使用过。

于 2015-10-24T15:23:24.027 回答
1

使用 pm2 模块。pm2 nodejs 模块

于 2021-09-07T06:41:21.337 回答
1

PM2 是具有内置负载均衡器的 Node.js 应用程序的生产流程管理器。它允许您使应用程序永远保持活动状态,在不停机的情况下重新加载它们,并促进常见的系统管理任务。 https://github.com/Unitech/pm2

于 2015-10-09T19:15:45.193 回答
1

我将 tmux 用于远程主机上的多窗口/窗格开发环境。分离并保持进程在后台运行非常简单。看看tmux

于 2017-03-07T08:52:17.947 回答
1

如果您使用的是 pm2,则可以将其与autorestartset 一起使用false

$ pm2 生态系统

这将生成一个示例ecosystem.config.js

module.exports = {
  apps: [
    {
      script: './scripts/companies.js',
      autorestart: false,
    },
    {
      script: './scripts/domains.js',
      autorestart: false,
    },
    {
      script: './scripts/technologies.js',
      autorestart: false,
    },
  ],
}

$ pm2 启动生态系统.config.js

于 2020-06-06T14:32:17.637 回答
1

在 RHEL 8 AWS EC2 实例上使用@mikemaccana的接受答案时,我收到以下错误:(code=exited, status=216/GROUP)

这是由于将用户/组设置为:'nobody'。

谷歌搜索后,似乎将用户/组用作“nobody”/“nogroup”对于守护进程来说是不好的做法,正如在 unix 堆栈交换中回答的那样。

在我将用户/组设置为我的实际用户和组后,它工作得很好。

您可以输入whomaigroups查看解决此问题的可用选项。

我的带有 mongodb 的全栈节点应用程序的服务文件:

[Unit]
Description=myapp
After=mongod.service

[Service]
ExecStart=/home/myusername/apps/myapp/root/build/server/index.js
Restart=always
RestartSec=30
User=myusername
Group=myusername
Environment=PATH=/usr/bin:/usr/local/bin
Environment=NODE_ENV=production
WorkingDirectory=/home/myusername/apps/myapp

[Install]
WantedBy=multi-user.target
于 2021-08-13T19:26:18.313 回答
-1

这个答案对聚会来说已经很晚了,但我发现最好的解决方案是编写一个同时使用 thescreen -dmSnohup命令的 shell 脚本。

screen -dmS newScreenName nohup node myserver.js >> logfile.log

我还在最后添加了>> logfile一点,这样我就可以轻松地保存节点console.log()语句。

为什么我使用 shell 脚本?好吧,我还添加了一个 if 语句来检查node myserver.js进程是否已经在运行。

这样我就能够创建一个命令行选项,既可以让我保持服务器运行,也可以在我进行更改时重新启动它,这对开发非常有帮助。

于 2012-04-19T15:00:29.513 回答