How do I run a node.js app as a background service?
由于这篇文章在过去的几年里得到了广泛的关注,我已经在这篇文章的底部列出了每个平台的顶级解决方案。
原始职位:
我希望node.js服务器在后台运行,即:当我关闭终端时,我希望服务器继续运行。我在google上找到了这个教程,但是它并没有按预期工作。因此,我没有使用这个守护进程脚本,我认为我只是使用了输出重定向(
我也试着把这个过程放到后台,但是一旦我关闭终端,这个过程也会被终止。
那么,当我关闭本地计算机时,如何让它保持运行?
顶级解决方案:
- 系统(Linux)
- Launchd(MAC)
- 节点窗口(Windows)
- PM2(节点JS)
从如何将node.js应用程序作为自己的进程运行复制我自己的答案?
2015年的答案:几乎每个Linux发行版都有SystemD,这意味着永久、monit等不再是必需的——您的操作系统已经处理了这些任务。
制作一个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | [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新手:
将您的服务文件复制到
从
使用
见带
这是从我们如何在Linux上部署节点应用程序(2018版)中获得的,该版本还包括生成用于构建Linux/节点服务器(包括
您可以使用Forever,这是一个简单的CLI工具,用于确保给定的节点脚本连续运行(即Forever):https://www.npmjs.org/package/forever/永远
更新-正如下面的一个答案中提到的,PM2有一些非常好的功能永远不会出现。考虑使用它。
原始答案
使用NOHUP:
1 | nohup node server.js & |
编辑我想补充的是,接受的答案是真正的出路。我永远都在使用那些需要保持警惕的实例。我喜欢做
这可能不是公认的方法,但我是用屏幕来做的,尤其是在开发过程中,因为我可以把它恢复过来,并在必要时用它来愚弄它。
1 2 3 | screen node myserver.js >>CTRL-A then hit D |
屏幕将分离,并在您注销后存活下来。然后你可以把它放回去做屏幕-R。点击屏幕手册了解更多细节。你可以给屏幕命名,如果你喜欢什么也可以。
2016更新:节点windows/mac/linux系列在所有操作系统中都使用一个通用的API,因此它绝对是一个相关的解决方案。但是,node linux生成systemv init文件。随着SystemD的普及,它实际上是Linux上更好的选择。如果有人想向node linux添加systemd支持,欢迎使用pr:-)
原始线程:
现在这是一个非常古老的线程,但是节点窗口提供了在Windows上创建后台服务的另一种方法。它松散地基于在节点脚本周围使用
在某些事件日志记录中,模块也会烘焙:
脚本的后台监控是通过代码完成的。例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 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\ ode\\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! Visit http://127.0.0.1:3000 to see it in action.'); }); // Install the script as a service. svc.install(); |
该模块支持诸如封顶重新启动(这样糟糕的脚本就不会影响服务器)和增加重新启动之间的时间间隔等功能。
由于节点Windows服务与其他任何服务一样运行,因此可以使用您已经使用的任何软件来管理/监视该服务。
最后,没有
完全公开,我是这个模块的作者。它的设计是为了减轻操作人员所经历的痛苦,但是通过与操作系统已经提供的功能的紧密集成。我希望未来有同样问题的观众会发现它是有用的。
更新:我更新了PM2的最新版本:
对于许多用例,使用SystemD服务是管理节点流程最简单和最合适的方法。对于那些在单个环境中运行多个节点进程或独立运行节点微服务的用户来说,PM2是一个功能更加完整的工具。
网址:https://github.com/unitech/pm2
HTTP//PM2.IO
- 它有一个非常有用的监视功能—>漂亮的"gui",用于使用
pm2 monit 或使用pm2 list 的进程列表对多个进程进行命令行监视。 - 有组织的日志管理
- 其他材料:
- Behavior configuration
- Source map support
- PaaS Compatible
- Watch & Reload
- Module System
- Max memory reload
- Cluster Mode
- Hot reload
- Development workflow
- Startup Scripts
- Auto completion
- Deployment workflow
- Keymetrics monitoring
- API
如果您运行的是OSX,那么产生真正系统进程的最简单方法就是使用
构建一个这样的plist,并将其放入名为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <?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> <string>/usr/local/bin/node</string> <string>your-script-file</string> </array> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <true/> </dict> </plist> |
完成后,发出(作为根目录):
1 2 | 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
如果您只想在脚本完成之前不间断地运行它,那么您可以使用
1 | nohup node index.js >> app.log 2>&1 & |
>> 表示追加到app.log 上。2>&1 确保错误也发送到stdout 并添加到app.log 中。- 结束的
& 确保当前终端与命令断开连接,以便继续工作。
如果要运行节点服务器(或服务器重新启动时应启动备份的服务器),则应使用systemd/systemctl。
我只是使用守护进程NPM模块:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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: ', err); return process.exit(-1); } console.log('Daemonized successfully with pid: ' + pid); // Your Application Code goes here }); |
最近,我还使用来自TJ Holowaychuk的mon(1)来启动和管理简单的节点应用程序。
我使用主管进行开发。它只是工作。当您对.js文件管理器进行更改时,会自动在加载这些更改的情况下重新启动应用程序。
这里有一个指向其Github页面的链接
安装:
sudo npm install supervisor -g
您可以很容易地让它用-e来监视其他扩展名。我经常使用的另一个命令是-i来忽略某些文件夹。
您可以使用nohup和supervisor使您的节点应用程序在后台运行,即使在您注销之后。
sudo nohup supervisor myapp.js &
如果使用nohup,请尝试运行此命令-
1 | nohup npm start 2>/dev/null 1>/dev/null& |
您还可以永远使用来启动服务器
1 | forever start -c"npm start" ./ |
PM2还支持
1 | pm2 start npm -- start |
公认的答案可能是最佳的生产答案,但对于快速黑客进行开发工作,我发现:
但我把
当然不是生产问题,但它解决了"我需要继续使用我的终端,不想启动5个不同的终端"的问题。
node.js作为Windows XP中的后台服务
- 有关安装node.js+npm for windows的教程,请访问hacksparrow:http://www.hacksparrow.com/install-node-js-and-npm-on-windows.html。
- 对于nnsm.exe的实现,可以访问tatham oddie,网址为:http://blog.tatham.oddie.com.au/2011/03/16/node-js-on-windows/。
安装:
创建c:odehelloworld.js
1 2 3 4 5 6 7 8 9 | // 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 "); }); server.listen(8000); console.log("Server running at http://127.0.0.1:8000/"); |
打开命令控制台并键入以下内容(仅当安装了资源工具包时才输入setx)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | C: ode> set path=%PATH%;%CD% C: ode> setx path"%PATH%" C: ode> set NODE_PATH="C:\Program Files odejs ode_modules" C: ode> git config --system http.sslcainfo /bin/curl-ca-bundle.crt C: ode> git clone --recursive git://github.com/isaacs/npm.git C: ode> cd npm C: ode pm> node cli.js install npm -gf C: ode> cd .. C: ode> nssm.exe install node-helloworld"C:\Program Files odejs ode.exe" c: ode\helloworld.js C: ode> net start node-helloworld |
一个漂亮的批处理程序是创建c:odeservice.cmd
1 2 3 4 5 6 | @echo off nssm.exe install node-%~n1"C:\Program Files odejs ode.exe" %~s1 net start node-%~n1 pause |
服务管理:
- 现在可以通过start->run->services.msc或通过start->run->msconfig->services(并选中"hide所有Microsoft服务)。
- 脚本将为通过批处理脚本生成的每个节点添加前缀"节点-"。
- 同样,它们也可以在注册表中找到:"hklmsystemcurrentcontrolsetservicesode xxxx"
如果您在Linux服务器上运行nodejs,我认为这是最好的方法。
创建服务脚本并复制到/etc/init/nodejs.conf
启动服务:sudo服务nodejs start
停止服务:sudo服务nodejs停止
服务脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | description"DManager node.js server - Last Update: 2012-08-06" author "Pedro Muniz - [email protected]" 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 |
2017年6月更新:Linux解决方案:(Red Hat)。以前的评论对我不起作用。这对我在亚马逊网络服务上有效——RedHat7。希望这对外面的人有用。
1 2 3 4 5 6 7 8 9 10 11 12 | 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 |
1 2 3 4 5 6 7 8 9 | 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) |
1 2 3 4 5 6 7 8 | 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 |
使用nssm是Windows的最佳解决方案,只需下载nssm,打开cmd到nssm目录并键入
1 2 3 4 | nssm install <service name> <node path> eg: nssm install myservice"C:\Program Files odejs""C:\myapp\app.js" |
这将安装一个新的Windows服务,该服务将在services.msc中列出。您可以从此处启动或停止该服务,该服务将自动启动,并且可以配置为在失败时重新启动。
为了完善各种建议的选项,这里还有一个:gnu/linux中的
对于使用更新版本的守护进程NPM模块的用户,您需要传递文件描述符而不是字符串:
1 2 3 4 5 6 7 | var fs = require('fs'); var stdoutFd = fs.openSync('output.log', 'a'); var stderrFd = fs.openSync('errors.log', 'a'); require('daemon')({ stdout: stdoutFd, stderr: stderrFd }); |
有没有人注意到"2>1"的位置有点小错误?
1 | 2>&1 >> file |
应该是
1 | >> file 2>&1 |
我将tmux用于远程主机上的多窗口/窗格开发环境。分离并保持进程在后台运行非常简单。看看TMUX
看看赋格!除了启动许多工人,您还可以将您的节点进程妖魔化!
网址:http://github.com/pgte/fugue
PM2是node.js应用程序的生产流程管理器,具有内置的负载均衡器。它允许您永远保持应用程序的活动状态,在不停机的情况下重新加载应用程序,并方便执行常见的系统管理任务。网址:https://github.com/unitech/pm2
我很惊讶没有人提到古夫纳
我一直在尝试PM2等。但是,当涉及到可靠的控制和基于Web的性能指标时,我发现Guvnor是迄今为止最好的。另外,它也是完全开放源码的。
编辑:但是,我不确定它是否适用于Windows。我只在Linux上使用过它。
这个答案对派对来说已经很晚了,但我发现最好的解决方案是编写一个shell脚本,该脚本同时使用
1 | screen -dmS newScreenName nohup node myserver.js >> logfile.log |
我还在末尾添加了
我为什么要使用shell脚本?我还添加了一个if语句,检查
这样,我就可以创建一个命令行选项,既可以让服务器继续运行,也可以在进行更改时重新启动它,这对开发非常有帮助。