如何将node.js应用程序作为后台服务运行?

时间:2010-10-25 19:34:10

标签: node.js process background server daemon

由于这篇文章多年来引起了很多关注,我在本文的最后列出了每个平台的顶级解决方案。


原帖

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

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

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


热门解决方案

26 个答案:

答案 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代替,并提供可配置的节点包装器,以更精细地控制进程如何在失败时启动/停止。这些流程与其他服务一样可用:

enter image description here

该模块还会记录一些事件记录:

enter image description here

通过代码完成守护程序。例如:

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

http://pm2.io

  • 它有一个非常有用的监控功能 - >使用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,如此处的答案中所述。但是,没有一个答案提供的完整命令也会记录stdinstdout

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

中的后台服务

安装:

  1. 通过安装程序可执行文件
  2. 安装WGET http://gnuwin32.sourceforge.net/packages/wget.htm
  3. 通过安装程序可执行文件
  4. 安装GIT http://code.google.com/p/msysgit/downloads/list
  5. 通过将nnsm.exe复制到%windir%/ system32文件夹中安装NSSM http://nssm.cc/download/?page=download
  6. 创建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/");
    
  7. 打开命令控制台并输入以下内容(仅当安装了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
    
  8. 一个漂亮的批处理好东西是创建c:\ node \ ServiceMe.cmd

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

    • 现在可以通过Start-&gt;访问服务本身。运行 - &GT; services.msc或通过Start-&gt; Run-&gt; MSCONFIG-&GT;服务(并勾选'隐藏 所有Microsoft服务')。
    • 该脚本将为通过批处理脚本创建的每个节点添加前缀 '节点 - '。
    • 同样可以在注册表中找到它们:“ HKLM \ SYSTEM \ CurrentControlSet \ Services \ node-xxxx

答案 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)

查看赋格!除了启动许多工作人员,你也可以妖魔化你的节点过程!

http://github.com/pgte/fugue

答案 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是迄今为止最好的。此外,它也是完全开源的。

enter image description here

编辑:但是,我不确定它是否适用于Windows。我只在linux上使用它。

答案 24 :(得分:0)

PM2是具有内置负载均衡器的Node.js应用程序的生产流程管理器。它允许您永久保持应用程序活动,无需停机即可重新加载它们,并促进常见的系统管理任务。 https://github.com/Unitech/pm2

答案 25 :(得分:-1)

这个答案对于派对来说已经很晚了,但我发现最好的解决方案是编写一个使用screen -dmSnohup命令的shell脚本。

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

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

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

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