由于这篇文章多年来引起了很多关注,我在本文的最后列出了每个平台的顶级解决方案。
原帖:
我希望我的node.js服务器在后台运行,即:当我关闭终端时,我希望我的服务器继续运行。我已经用Google搜索了这个tutorial,但它没有按预期工作。因此,我没有使用该守护进程脚本,而是认为我只使用了输出重定向(2>&1 >> file
部分),但这也没有退出 - 我的终端中出现一个空行,就像是在等待输出/错误。
我也尝试将该过程放在后台,但是一旦我关闭终端,该过程也会被杀死。
那么当我关闭本地计算机时,如何让它保持运行?
热门解决方案:
答案 0 :(得分:345)
从How do I run a Node.js application as its own process?
复制我自己的答案2015回答:几乎每个Linux发行版都附带systemd,这意味着永远,monit,PM2等不再需要 - 您的操作系统已经处理了这些任务。 / p>
制作一个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
。
将您的服务文件复制到/etc/systemd/system
。
以systemctl start myapp
开头。
启用它以systemctl enable myapp
启动时运行。
查看journalctl -u myapp
这取自 How we deploy node apps on Linux, 2018 edition ,其中还包含生成AWS / DigitalOcean / Azure CloudConfig以构建Linux /节点服务器(包括.service
文件)的命令。
答案 1 :(得分:237)
您可以使用Forever,这是一个简单的CLI工具,用于确保给定节点脚本连续运行(即永久运行): https://www.npmjs.org/package/forever
答案 2 :(得分:203)
更新 - 如下面的其中一个答案中所述,PM2有一些非常好的功能永远不会丢失。考虑使用它。
原始答案
使用nohup:
nohup node server.js &
编辑我想补充说,接受的答案真的是要走的路。我正在永远使用需要熬夜的实例。我喜欢npm install -g forever
所以它在节点路径中,然后只做forever start server.js
答案 3 :(得分:61)
这可能不是可以接受的方式,但我是用屏幕做的,特别是在开发过程中,因为我可以将它重新启动并在必要时愚弄它。
screen
node myserver.js
>>CTRL-A then hit D
屏幕将分离并在您注销后继续存在。然后你可以回来做屏幕-r。点击屏幕手册了解更多详情。如果您愿意,可以为屏幕命名等等。
答案 4 :(得分:59)
2016年更新: node-windows / mac / linux系列在所有操作系统中使用通用API,因此它绝对是一个相关的解决方案。然而; node-linux生成systemv init文件。随着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所经历的确切痛苦,但与操作系统已经提供的功能更紧密地集成。我希望未来有相同问题的观众发现它很有用。
答案 5 :(得分:26)
更新:我已更新为包含pm2的最新内容:
对于许多用例,使用systemd服务是管理节点进程最简单,最合适的方法。对于那些在单个环境中运行大量节点进程或独立运行节点微服务的人来说,pm2是一个功能更全面的工具。
https://github.com/unitech/pm2
pm2 monit
或带有pm2 list
的进程列表对多个进程进行命令行监控非常'gui'pm2 logs
- 行为配置
- 源地图支持
- PaaS兼容
- 手表&重载
- 模块系统
- 最大内存重新加载
- 群集模式
- 热重装
- 开发工作流程
- 启动脚本
- 自动完成
- 部署工作流程
- Keymetrics监控
- API
答案 6 :(得分:16)
如果您正在运行OSX,那么生成真正系统进程的最简单方法是使用launchd
启动它。
像这样构建一个plist,并将其放入名为top-level-domain.your-domain.application.plist
的/ Library / LaunchDaemons中(放置时需要为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
答案 7 :(得分: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
});
最近我还使用mon(1)中的TJ Holowaychuk来启动和管理简单节点应用。
答案 8 :(得分:13)
如果您只是希望不间断地运行脚本直到完成,您可以使用nohop
,如此处的答案中所述。但是,没有一个答案提供的完整命令也会记录stdin
和stdout
。
nohup node index.js >> app.log 2>&1 &
>>
表示附加到app.log
。2>&1
确保错误也会发送到stdout
并添加到app.log
。&
确保您的当前终端与命令断开连接,以便继续工作。 如果要运行节点服务器(或者在服务器重新启动时应该重新启动的东西),则应使用systemd / systemctl。
答案 9 :(得分:12)
我使用Supervisor进行开发。它只是有效。当您对.js文件进行更改时,Supervisor会自动重新启动您的应用程序并加载这些更改。
Here's a link to its Github page
安装:
sudo npm install supervisor -g
您可以轻松地使用-e观看其他扩展程序。我经常使用的另一个命令是-i忽略某些文件夹。
即使您在注销后,也可以使用nohup和supervisor使您的节点应用程序在后台运行。
sudo nohup supervisor myapp.js&amp;
答案 10 :(得分:10)
如果您使用nohup,请尝试运行此命令 -
nohup npm start 2>/dev/null 1>/dev/null&
您也可以永远使用启动服务器
forever start -c "npm start" ./
PM2也支持npm start
pm2 start npm -- start
答案 11 :(得分:7)
Node.js作为 WINDOWS XP
中的后台服务安装:
创建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
服务管理:
答案 12 :(得分:7)
接受的答案可能是最好的生产答案,但是为了快速破解开发工作,我发现了这个:
nodejs scriptname.js &
没有用,因为nodejs似乎吞噬了&amp;,所以事情并没有让我继续使用终端而没有scriptname.js死亡。
但我将nodejs scriptname.js
放在.sh文件中,然后
nohup sh startscriptname.sh &
工作了。
绝对不是制作品,但它解决了&#34;我需要继续使用我的终端而不想开始5个不同的终端&#34;问题
答案 13 :(得分:4)
如果你在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
答案 14 :(得分:4)
2017年6月更新:
Linux解决方案:(红帽)。以前的评论对我不起作用。
这适用于亚马逊网络服务 - 红帽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
答案 15 :(得分: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 列出,您可以从那里启动或停止服务,此服务将自动启动,您可以配置为在失败时重新启动。
答案 16 :(得分:2)
为了完善建议的各种选项,还有一个:GNU / Linux中的daemon
命令,您可以在这里阅读:http://libslack.org/daemon/manpages/daemon.1.html。 (如果上面的一条评论中已经提到过,请道歉。)
答案 17 :(得分:1)
查看赋格!除了启动许多工作人员,你也可以妖魔化你的节点过程!
答案 18 :(得分:1)
对于使用新版本的 daemon 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
});
答案 19 :(得分:1)
是否有人注意到“2&gt;&amp; 1”的位置存在一些微不足道的错误?
2>&1 >> file
应该是
>> file 2>&1
答案 20 :(得分:1)
我在远程主机上使用tmux作为多窗口/窗格开发环境。分离并保持进程在后台运行非常简单。看看tmux
答案 21 :(得分:0)
如果您使用的是pm2,则可以将trait B {}
struct BB {}
impl B for BB {}
struct A {
pub lifetime: ALifetime,
pub data: AData,
#[allow(dead_code)]
private: (), // prevent destructuring
}
struct ALifetime {}
struct AData {}
impl A {
fn new() -> Self {
Self { lifetime: ALifetime {}, data: AData {}, private: () }
}
}
impl ALifetime {
fn get_b<'a>(&'a self) -> Box<dyn B + 'a> { Box::new(BB{}) }
}
impl AData {
fn mut_a(&mut self) {}
}
fn main() {
let mut a = A::new();
let b = a.lifetime.get_b();
a.data.mut_a(); // Only `a.data` is borrowed here.
// drop(b);
drop(a); // Not allowed. b must be dropped before a
}
设置为autorestart
来使用它:
$ pm2生态系统
这将生成一个示例false
:
ecosystem.config.js
$ pm2启动ecosystem.config.js
答案 22 :(得分:0)
由于我在所提供答案的列表中缺少此选项,因此我想在2020年之前添加一个合格选项:docker或任何equivalent container平台。除了确保您的应用程序在稳定的环境中运行外,还具有其他安全优势以及改进的可移植性。
Docker对Windows,macOS和大多数/主要的Linux发行版提供支持。 Installing docker on a supported platform非常简单明了,文档齐全。设置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。
当然,这是一个非常有限的示例,但这是一个很好的起点。
答案 23 :(得分:0)
我很惊讶没有人提到Guvnor
我已经尝试过永远,pm2等等。但是,当谈到可靠控制和基于网络的性能指标时,我发现Guvnor是迄今为止最好的。此外,它也是完全开源的。
编辑:但是,我不确定它是否适用于Windows。我只在linux上使用它。
答案 24 :(得分:0)
PM2是具有内置负载均衡器的Node.js应用程序的生产流程管理器。它允许您永久保持应用程序活动,无需停机即可重新加载它们,并促进常见的系统管理任务。 https://github.com/Unitech/pm2
答案 25 :(得分:-1)
这个答案对于派对来说已经很晚了,但我发现最好的解决方案是编写一个使用screen -dmS
和nohup
命令的shell脚本。
screen -dmS newScreenName nohup node myserver.js >> logfile.log
我还在末尾添加>> logfile
位,这样我就可以轻松保存节点console.log()
语句。
为什么我使用shell脚本?好吧,我还添加了一个if语句,检查node myserver.js
进程是否已经运行。
这样我就可以创建一个命令行选项,它既可以让我保持服务器运行,也可以在我进行更改时重新启动它,这对开发非常有帮助。