由于这篇文章在过去几年里受到了很多关注,所以我在文章的底部列出了每个平台的最佳解决方案。


原来的帖子:

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

我也尝试过把进程放在后台,但是只要我关闭终端,进程就会被杀死。

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


高级解决方案:

Systemd (Linux) Launchd (Mac) node-windows (Windows) PM2 (node . js)


当前回答

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

其他回答

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

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

在谷歌上搜索,似乎使用用户/组作为'nobody'/'nogroup'对守护进程来说是不好的实践,就像在unix堆栈交换中回答的那样。

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

您可以输入whoai和组来查看可用的解决此问题的选项。

我的服务文件为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

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

2>&1 >> file

应该是

>> file 2>&1

复制我自己的答案从我如何运行一个Node.js应用程序作为它自己的进程?

2015年的答案:几乎每个Linux发行版都带有systemd,这意味着forever、monit、PM2等不再需要——你的操作系统已经处理这些任务了。

制作一个myapp。服务文件(替换'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节点,并将可执行模式打开chmod +x app.js。

将服务文件复制到/etc/systemd/system. conf文件中。

用systemctl Start myapp启动它。

使用systemctl Enable myapp启用它在引导时运行。

使用journalctl -u myapp查看日志

这摘自我们如何在Linux上部署节点应用程序,2018年版,其中还包括生成AWS/DigitalOcean/Azure CloudConfig来构建Linux/节点服务器的命令(包括.service文件)。

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

如果出于本地开发的目的,你需要启动多个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