由于这篇文章在过去几年里受到了很多关注,所以我在文章的底部列出了每个平台的最佳解决方案。
原来的帖子:
我希望我的node.js服务器在后台运行,即:当我关闭我的终端时,我希望我的服务器继续运行。我在谷歌上搜索过这个,并提出了这个教程,但它并不像预期的那样工作。因此,我没有使用这个守护进程脚本,我认为我只是使用了输出重定向(2>&1 >>文件部分),但这也不退出-我在终端中得到一个空行,就像它在等待输出/错误一样。
我也尝试过把进程放在后台,但是只要我关闭终端,进程就会被杀死。
那么,当我关闭本地计算机时,如何让它继续运行呢?
高级解决方案:
Systemd (Linux)
Launchd (Mac)
node-windows (Windows)
PM2 (node . js)
如果你在linux服务器上运行nodejs,我认为这是最好的方法。
创建业务脚本,拷贝到/etc/init/nodejs.conf目录下
Start service: sudo service nodejs Start
Stop service: 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
如果出于本地开发的目的,你需要启动多个NodeJS应用实例(express, fastify等),那么并发可能是一个选项。下面是一个设置:
先决条件
你的NodeJS应用(express, fastify等)被放置在/opt/mca/www/mca-backend/app路径下。
假设您使用的是通过brew install node@16安装的节点v.16
设置
Install concurrently: npm install -g concurrently
Create a file ~/Library/LaunchAgents/mca.backend.plist
<?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>mca.backend</string>
<key>LimitLoadToSessionType</key>
<array>
<string>Aqua</string>
<string>Background</string>
<string>LoginWindow</string>
<string>StandardIO</string>
<string>System</string>
</array>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/concurrently</string>
<string>--names</string>
<string>dev,prd</string>
<string>--success</string>
<string>all</string>
<string>--kill-others</string>
<string>--no-color</string>
<string>MCA_APP_STAGE=dev node ./server.mjs</string>
<string>MCA_APP_STAGE=prod node ./server.mjs</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/usr/local/opt/node@16/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin</string>
</dict>
<key>WorkingDirectory</key>
<string>/opt/mca/www/mca-backend/app</string>
<key>StandardErrorPath</key>
<string>/opt/mca/www/mca-backend/err.log</string>
<key>StandardOutPath</key>
<string>/opt/mca/www/mca-backend/out.log</string>
</dict>
</plist>
Load and run: launchctl bootstrap gui/`id -u` $HOME/Library/LaunchAgents/mca.backend.plist
Get a status: launchctl print gui/`id -u`/mca.backend
Stop: launchctl kill SIGTERM gui/`id -u`/mca.backend
Start/Restart: launchctl kickstart -k -p gui/`id -u`/mca.backend
Unload if not needed anymore: launchctl bootout gui/`id -u`/mca.backend
重要提示:一旦你用launchctl加载service,引导你在文件中所做的任何更改
~ /图书馆/ LaunchAgents / mca.backend。Plist将不会在行动,直到你卸载服务(通过使用launchctl bootout)
然后再次加载它(通过使用launchctl bootstrap)。
故障排除
查看启动日志:/private/var/log/com.apple.xpc.launchd/launchd.log
2016年更新:
node-windows/mac/linux系列使用跨所有操作系统的通用API,因此它绝对是一个相关的解决方案。然而;Node-linux会生成systemv init文件。随着systemd越来越受欢迎,它实际上是Linux上更好的选择。如果有人想为node-linux添加systemd支持,欢迎PR:-)
原始线程:
这是一个非常老的线程,但是node-windows提供了另一种在Windows上创建后台服务的方法。它松散地基于在节点脚本周围使用exe包装器的nssm概念。然而;它使用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();
该模块支持限制重启(这样糟糕的脚本就不会影响服务器)和增加重启之间的时间间隔。
由于节点窗口服务像其他服务一样运行,因此可以使用您已经使用的任何软件来管理/监视服务。
最后,没有make依赖项。换句话说,简单的npm install -g node-window就可以了。你不需要Visual Studio、. net或node-gyp魔法来安装它。而且,它是MIT和BSD授权的。
坦白地说,我是这个模块的作者。它的设计是为了减轻OP所经历的痛苦,但与操作系统已经提供的功能更紧密地集成。我希望未来有同样问题的观众会觉得有用。
2017年6月更新:
Linux解决方案:(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