由于这些年来引起了很多关注,因此我在文章的底部列出了每个平台的最佳解决方案。


原始文章:

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

我也尝试过将进程放在后台,但是一旦关闭终端,进程也会被杀死。

那么关闭时如何让它继续运行


最佳解决方案:



Systemd(Linux)

Launchd( Mac)

节点窗口(Windows)

PM2(Node.js)


评论

我认为他打算关闭自己的本地系统

他的意思是关闭ssh会话会终止任务

github.com/Unitech/pm2是一个高度维护且非常稳定的过程管理器,请尝试一下!

您可以使用屏幕(aperiodic.net/screen/quick_reference)

#1 楼

从如何将Node.js应用程序作为自己的进程运行来复制我自己的答案?
2015年答案:几乎每个Linux发行版都随附systemd,这意味着永远不需要永久,监视,PM2等-您的操作系统已经完成了这些任务。
制作一个myapp.service文件(显然用您的应用名称替换'myapp'):
[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

请注意,如果您是Unix的新手,则/var/www/myapp/app.js应该在#!/usr/bin/env node上从第一行开始,并打开了chmod +x myapp.js的可执行模式。
将您的服务文件复制到/etc/systemd/system中。
systemctl start myapp开始。
使它可以在systemctl enable myapp引导下运行。
请参阅带有journalctl -u myapp的日志
取自我们如何在Linux版本2018上部署节点应用程序,其中还包括用于生成AWS / DigitalOcean / Azure CloudConfig来构建Linux /节点服务器的命令(包括.service文件)。 br />

评论


Upstart(如果可用)也是一个很好的解决方案。无论哪种方式,您都不应依赖Node.js进程来保持Node.js守护程序运行。这仅是操作系统的一项任务。 Killall Node.js永远消失了...

– 131
15年7月26日在9:26

请注意,也可以以用户身份运行systemd服务。例如,请参阅本教程。您可以将服务文件放在〜/ .config / systemd / user中,使用systemctl --user start myapp启动它,使用systemctl --user enable myapp启用它。

– cdauth
2015年12月29日在7:26

感谢您的回答。这就是我想要的纯净和清晰

– bmavus
16年1月10日在19:35

我接受了这个答案,而不是“永远”的答案,因为我也认为这是最好的方法。对于Mac和Windows,也有类似的答案,但我想大多数人都在寻找Linux解决方案。

– Peter Kruithof
16年1月16日在11:56

在EC2 AMI路径中/ etc / systemd / system不存在。您能否指出AWS EC2 Linux AMI中的正确路径是什么?

–RenéMichel
16年1月18日在19:02

#2 楼

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

评论


对于最新节点,我无法通过脚本名称(错误)来停止应用程序-而且-通常行为异常(在OS-X上)-都是从源代码构建的,这很奇怪。让事情陷入困境,并没有使我充满信心。

–迈克尔·尼尔(Michael Neale)
2011年4月12日在12:32

尽管nohup可以解决问题,但永远持续下去是一种更好的解决方案,因为它可以守护进程。很棒的工具!

– Peter Kruithof
2011年6月9日9:57

顺便说一句,这里有一个更简单的教程:使用Forever保持node.js服务器的正常运行

– kehers
2012年9月29日在2:20



我确实使用了Forever一段时间,一开始一切似乎都还不错,但随后发生了灾难。 Forever再也无法管理流程,而让它们疯狂运行。仍在努力寻找更好的解决方案。我会尝试使用nohup

– L N
13年1月21日在12:25

Geoffrey-不,您需要在服务器启动脚本中永久启动/path/to/yourApp.js。

– mikermcneil
13年3月3日在17:14

#3 楼

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

原始答案

使用nohup:

nohup node server.js &


编辑我想补充一下,答案确实是要走的路。我在需要保持正常运行的实例上永远使用。我喜欢做npm install -g forever,所以它在节点路径中,然后就做forever start server.js

评论


要知道的很酷的部分:nohup代表没有挂断,这是从过去开始的,当您“挂断”调制解调器时,您希望在此保持活动状态。

– jAndy
2010-10-28 19:48

如今,它只是进程1收到的信号1的名称,以警告用户关闭了外壳(或丢失了调制解调器连接,当然是:P)。

–lapo
2011-12-16 9:44

这不是最佳解决方案,因为如果应用程序遇到未捕获的错误,则节点进程将退出并且不会重新启动。尽管如此,它仍然是开发的合理选择。

– Andy E
2012年5月31日18:38



我该如何添加环境变量?例如:PORT = 80节点server.js

–赦免者
2012年10月2日在18:45

从SO中查看此答案-stackoverflow.com/questions/8825460/…

– NG。
2012年10月3日在16:05

#4 楼

这可能不是被接受的方法,但是我会在屏幕上执行此操作,尤其是在开发过程中,因为我可以将其备份并在必要时对其进行愚弄。

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


屏幕将脱离,并且在您注销后仍然可以保存。然后,您可以通过屏幕-r将其取回。点击屏幕手册获取更多详细信息。您可以命名屏幕,也可以命名。

评论


另外,tmux很好。像屏幕一样工作(默认是CTRL-B而不是CTRL-A,但是它是可配置的)。 Tmux具有面板(分屏)。

–snapfractalpop
2012年3月21日在18:17

屏幕也有面板

–比利·穆恩(Billy Moon)
13年3月3日在10:37

我已经使用了几个星期的流星应用程序。有时可能需要使用$ screen -dr进行分离和重新连接。

– Vinay Vemula
2015年4月9日在7:42



对我来说,完成工作的最简单方法。但是我同意,不是最好的解决方案

– Pomme De Terre
18年2月12日在15:11

重新启动系统后,此解决方案无法持久

– wnasich
5月8日13:12

#5 楼

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();


该模块支持诸如限制重新启动的上限(这样不良的脚本不会使您的服务器疲惫)以及重新启动之间的时间间隔越来越长。

/>由于节点Windows服务的运行方式与其他服务相同,因此可以使用已使用的任何软件来管理/监视该服务。最后,没有make依赖项。换句话说,一个简单的npm install -g node-windows将起作用。您不需要安装Visual Studio,.NET或node-gyp魔术。另外,它是MIT和BSD许可。

完整地披露,我是该模块的作者。它旨在缓解OP所遭受的确切痛苦,但与操作系统已提供的功能之间的集成更为紧密。希望以后有同样问题的观众也能从中受益。

评论


我现在将其移植到node-mac,在OSX上提供相同的功能。

– Corey
13年5月20日在20:47

我的意思是安排一些Node程序,然后再决定选择Node-windows,Forever还是Kue。我倾向于节点窗口,但想了解为什么当我要计划和监视许多节点程序时不使用Forever或Kue。一些永远运行。也需要监视。

–克里斯蒂安·韦斯特贝克(Christiaan Westerbeek)
2014年5月22日在7:15

节点窗口使用本机OS管理后台服务,并使用本机事件日志进行日志记录。 Forever拥有自己的自定义监视和日志记录。我在medium.com/p/2a602ea657a2上写过一篇文章。听起来您需要安排脚本,而不是一直将它们作为后台服务运行。为此设计了诸如Kue和Agenda之类的项目。节点窗口和永远服务于另一个目的。

– Corey
2014年5月23日0:23



@Corey,我如何从终端运行node-mac中包含的示例?我尝试了node install.js,但它似乎没有拾取helloworld.js。

–爱德华·O。
16年8月12日在9:40

@Edwin-最好打开一个新问题,其中包含有关您正在使用的代码的更多详细信息。

– Corey
16年8月12日在16:32

#6 楼

更新:我已更新为包括pm2中的最新内容:

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

https://github.com/unitech/pm2

http://pm2.io


它具有非常有用的监视功能->漂亮的“ gui”,用于使用pm2 monit监视多个进程或使用pm2 list监视进程列表

有组织的日志管理-> pm2 logs

其他内容:



行为配置
源地图支持
兼容PaaS的
监视和重载
模块系统
最大内存重载
集群模式
热重载
开发工作流程
启动脚本
自动完成
部署工作流程
关键指标监视
API






#7 楼

如果您只想不间断地运行脚本直到完成,则可以使用此处答案中已经提到的nohup。但是,所有答案都没有提供同时记录stdinstdout的完整命令。

nohup node index.js >> app.log 2>&1 &



>>意味着追加到app.log

2>&1确保将错误也发送到stdout并添加到app.log中。
结尾的&确保当前端子与命令断开连接,以便您可以继续工作。

如果要运行节点服务器(或在服务器重新启动时应备份的内容),则应使用systemd / systemctl。

评论


最佳答案M8。

–bholagabbar
18/12/26在16:03

很好的解释

– Prakhar Prakash Bhardwaj
19年12月31日在10:11

#8 楼

如果您正在运行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>


完成后,发出此命令(作为root用户):

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

评论


这将以什么用户身份运行服务?有没有设置用户的方法?

– rjmunro
16-4-29在16:30



#9 楼

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

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


也可以永久使用来启动服务器

forever start -c "npm start" ./ 


PM2还支持npm start

pm2 start npm -- start


评论


thnx,这很好用。 pm2 start npm-开始

– yadavr
19年2月4日16:00



#10 楼

我只是在使用守护程序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)来启动和管理简单的节点应用程序。 >

#11 楼

我使用Supervisor进行开发。它就是有效的。每当您对.js文件进行更改时,Supervisor都会自动在加载了这些更改的情况下重新启动您的应用。

这里是其Github页面的链接

安装:


sudo npm install administrator -g


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

即使注销后,也可以使用nohup和超级用户使节点应用程序在后台运行。


sudo nohup主管myapp.js&


评论


我认为在实践中,主管比大多数守护程序模块更好,特别是与Webhook结合使用以签出更新。

–伊恩·柯林斯
2014年2月7日在19:10

我第二把这个。如果更改PHP文件,是否要重新启动Apache或Nginx服务器?当然不。那么,为什么还要重新启动整个Node.js服务器甚至只更改一行代码呢?尽管这可能不是最佳解决方案,但与Supervisor租用时,您无需担心重新启动过程(实际上重新启动仍然会发生)。

– Zhang Buzz
17年5月14日在0:39

#12 楼

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


Kudos可以通过以下网址访问Hacksparrow:http://www.hacksparrow.com/install-node-js-and-npm-on- Windows.html,用于为Windows安装Node.js + npm的教程。
敬请访问Tatham Oddie,网址为:http://blog.tatham.oddie.com.au/2011/03/16/node-js-on -windows /用于nnsm.exe的实现。

安装:


通过安装程序安装WGET http://gnuwin32.sourceforge.net/packages/wget.htm可执行文件
通过安装程序安装GIT http://code.google.com/p/msysgit/downloads/list可执行文件
通过复制nnsm安装NSSM http://nssm.cc/download/?page=download .exe放入%windir%/ system32文件夹中

创建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/");



打开命令控制台并键入以下内容(仅在安装了Resource Kit的情况下才输入setx)。

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



一个不错的批处理糖果将创建c:\ node \ ServiceMe.cmd

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



服务管理:


现在可以通过开始->运行->
services.msc或通过开始->运行-> MSCONFIG->服务(并选中“隐藏
所有Microsoft服务”)来访问服务本身。
该脚本将在通过批处理脚本创建的每个节点前面加上
'node-'。
同样,它们可以在注册表中找到:“ HKLM \ SYSTEM \ CurrentControlSet \ Services \ node-xxxx “


#13 楼

公认的答案可能是最佳的生产答案,但是对于从事开发工作的快速黑客来说,我发现了这一点:

nodejs scriptname.js &不起作用,因为nodejs似乎吞噬了&,所以事情就这样了没让我继续使用没有scriptname.js死掉的终端。

但是我将nodejs scriptname.js放到了.sh文件中,并且
nohup sh startscriptname.sh &起作用了。

不是生产产品,而是解决了“我需要继续使用我的终端并且不想启动5个不同的终端”的问题。

#14 楼

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

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

启动服务:sudo服务nodejs start

停止服务:sudo服务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


#15 楼

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


评论


非常有趣,我只是对iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT-至8080感到好奇。请给我更多细节。我不确定,但我认为它会将流量从80重定向到8080,节点服务器侦听,对吗?

– Shakiba Moshiri
19年5月21日在7:42

#16 楼

使用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服务,该服务将在服务中列出。从那里可以启动MSC或停止该服务,该服务将自动启动,并且可以配置为在失败时重新启动。

#17 楼

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

#18 楼

看看神游!除了启动许多工作程序之外,您还可以妖怪您的节点进程!

http://github.com/pgte/fugue

#19 楼

PM2是具有内置负载平衡器的Node.js应用程序的生产过程管理器。它使您可以使应用程序永远保持活动状态,无需停机即可重新加载它们,并简化常见的系统管理任务。
https://github.com/Unitech/pm2

评论


严重的内存消耗问题!追求精神+ nginx

– Rizwan Patel
16 Mar 14 '16 at 12:34

#20 楼

我很惊讶没有人提到Guvnor

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



编辑:但是,我不确定它是否可以在Windows上运行。我只在linux上使用过。

评论


截至2017年似乎已过时。构建失败。去年没有代码推送。可疑的。

– 4Z4T4R
17年4月14日在7:52

#21 楼

有没有人注意到“ 2>&1”的位置的小错误?

2>&1 >> file


应该是

>> file 2>&1


#22 楼

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

#23 楼

对于使用较新版本的守护程序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
});


#24 楼

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

Docker支持Windows,macOS和大多数/主要的Linux发行版。在受支持的平台上安装docker非常简单明了,并有据可查。设置Node.js应用程序非常简单,只需将其放入容器中并运行该容器,同时确保其在关闭后即可重新启动。

创建容器映像

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

FROM node:lts-alpine
COPY /my-app /app
CMD ["/app/server.js"]


使用如下命令创建映像:

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


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

启动容器

使用以下命令启动容器:

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


此命令假设您的应用正在侦听端口3000,并且希望将其暴露在主机的端口80上。

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

#25 楼

如果您正在使用pm2,则可以将autorestart设置为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启动ecosystem.config.js


#26 楼

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

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


我还在末尾添加了>> logfile位,因此我可以轻松保存节点console.log()语句。

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

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

评论


我遇到了这个问题,对Linux来说还很陌生。没有屏幕或nohup怎么办?

–克雷格·诺顿(Craig Norton)
2012年5月9日20:33