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

Pet*_*hof 457 daemon background process node.js server

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


原帖:

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

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

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


最佳方案:

mik*_*ana 375

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

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

创建一个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
Run Code Online (Sandbox Code Playgroud)

请注意,如果您是Unix新手: /var/www/myapp/app.js应该#!/usr/bin/env node在第一行.

将您的服务文件复制到/etc/systemd/system.

启动它systemctl start myapp.

启用它以在启动时运行systemctl enable myapp.

查看日志 journalctl -u myapp

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

  • 请注意,也可以以用户身份运行systemd服务.请参阅[本教程](https://wiki.archlinux.org/index.php/Systemd/User).您可以将您的服务文件放在`〜/ .config/systemd/user`中,使用`systemctl --user start myapp`启动它,使用`systemctl --user enable myapp`启用它. (14认同)
  • 在EC2 AMI路径/ etc/systemd/system中不存在.您能指出AWS EC2 Linux AMI中的正确路径吗? (11认同)
  • 谢谢你的回答.这就是我想要的纯粹和清晰 (5认同)
  • Upstart,如果可用,也是一个很好的解决方案.无论哪种方式,您都不应该依赖nodejs进程来保持nodejs守护进程运行.这仅仅是操作系统的一项任务.killall nodejs永远消失了.... (4认同)
  • 我接受了这个答案,而不是"永远"的答案,因为我也认为这是最好的方法.对于Mac和Windows也有类似的答案,但我猜大多数人都在寻找Linux解决方案. (4认同)
  • 我在步骤 GROUP 生成失败...没有这样的过程错误。无法启动我的应用程序。文件和目录绝对正确。有什么想法为什么我的服务可能不想启动吗? (3认同)
  • @danyim是的,Ubuntu是最后一个不发布的主要发行版.16.04(下一个LTS)使用systemd. (2认同)
  • 感谢这个伟大的答案。我正在浪费时间寻找“永远”和“pm2”。这只是原生和简单的。 (2认同)
  • 不要忘记“chmod +x app.js”。 (2认同)

muz*_*uzz 238

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

  • 顺便说一句,这里提供了一个更简单的教程:[使用Forever保持node.js服务器](http://blog.nodejitsu.com/keep-a-nodejs-server-up-with-forever) (5认同)
  • Geoffrey-不,你需要在服务器启动脚本中"永远启动/路径/到/ yourApp.js". (5认同)
  • 使用最新节点我无法通过脚本名称(错误)来停止应用程序 - 也 - 通常行为不端(在OS-X上) - 所有这些都是从源代码构建的,奇怪的是.处于糟糕状态的事情,并没有给我充满信心. (4认同)
  • 虽然nohup可以做到这一点,但永远是一个更好的解决方案,因为它会使这个过程成为一个守护者.很棒的工具! (4认同)
  • 我确实使用了Forever一段时间,开始时一切似乎都没问题,但灾难发生了.Forever再也无法管理流程,让他们疯狂.仍在努力寻找更好的解决方案.我会尽量使用nohup (2认同)

NG.*_*NG. 207

更新 - 如下面的答案之一所述,PM2有一些非常好的功能永远缺失.考虑使用它.

原始答案

使用nohup:

nohup node server.js &
Run Code Online (Sandbox Code Playgroud)

编辑我想补充说,接受的答案真的是要走的路.我正在永远使用需要熬夜的实例.我喜欢这样npm install -g forever做它在节点路径中,然后就这样做forever start server.js

  • 很酷的部分要知道:`nohup`代表来自过去的`no hangup`,你希望在你"挂断"你的调制解调器时保持一个进程存活. (130认同)
  • 这不是最好的解决方案,因为如果应用程序遇到未捕获的错误,节点进程将退出而不重新启动.不过,这是一个合理的发展选择. (7认同)
  • 我如何添加环境变量?例如:PORT=80节点server.js (2认同)

Bre*_*ent 65

这可能不是可以接受的方式,但是我用屏幕来做,特别是在开发过程中,因为我可以将它恢复原状并在必要时愚弄它.

screen
node myserver.js
>>CTRL-A then hit D
Run Code Online (Sandbox Code Playgroud)

屏幕将分离并在您注销后继续存在.然后你可以回来做屏幕-r.点击屏幕手册了解更多详情.如果您愿意,可以为屏幕命名.

  • 也许不是公认的方式,但仍然非常有帮助,谢谢! (4认同)
  • 此外,tmux很不错.像屏幕一样工作(CTRL-B是默认值而不是CTRL-A,但可以配置).Tmux有面板(分屏). (2认同)

Cor*_*rey 59

2016更新: node-windows/mac/linux系列在所有操作系统中使用通用API,因此它绝对是一个相关的解决方案.然而; node-linux生成systemv init文件.随着systemd越来越受欢迎,它实际上是Linux上更好的选择.如果有人想为node-linux添加systemd支持PR,欢迎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();
Run Code Online (Sandbox Code Playgroud)

该模块支持封顶重启等功能(因此糟糕的脚本不会影响您的服务器)以及重启之间的时间间隔.

由于node-windows服务与其他服务一样运行,因此可以使用您已使用的任何软件管理/监控服务.

最后,没有make依赖关系.换句话说,直截了当npm install -g node-windows会起作用.您不需要Visual Studio,.NET或node-gyp magic来安装它.此外,它是MIT和BSD许可.

在完整的披露中,我是这个模块的作者.它旨在减轻OP所经历的确切痛苦,但与操作系统已经提供的功能更紧密地集成.我希望未来有同样问题的观众发现它很有用.

  • 我也将它移植到[node-linux](http://github.com/coreybutler/node-linux) (9认同)
  • 我现在将其移植到[node-mac](https://github.com/coreybutler/node-mac),在OSX上提供相同的功能. (8认同)
  • 节点窗口使用本机操作系统来管理后台服务,使用本机事件日志进行日志记录.Forever拥有自己的自定义监控和日志记录功能.我在https://medium.com/p/2a602ea657a2上写了一篇关于此的文章.听起来你需要安排脚本,而不是一直作为后台服务运行它们.像Kue和Agenda这样的项目就是为此而设计的.Node-windows&Forever服务于不同的目的. (5认同)

Hut*_*tch 27

更新:我更新了包括pm2的最新消息:

对于许多用例,使用systemd服务是管理节点进程的最简单和最合适的方法.对于那些在单个环境中运行大量节点进程或独立运行节点微服务的人来说,pm2是一个功能更全面的工具.

https://github.com/unitech/pm2

http://pm2.io

  • 它有一个非常有用的监控功能 - >非常'gui'用于命令行监控多个进程pm2 monit或使用进程列表pm2 list
  • 有组织的日志管理 - > pm2 logs
  • 其他的东西:
    • 行为配置
    • 源地图支持
    • PaaS兼容
    • 观看和重新加载
    • 模块系统
    • 最大内存重新加载
    • 群集模式
    • 热重装
    • 开发流程
    • 启动脚本
    • 自动完成
    • 部署工作流程
    • Keymetrics监控
    • API


Lar*_*sen 17

如果您正在运行OSX,那么生成真正系统进程的最简单方法是使用launchd它来启动它.

像这样构建一个plist,并将其放入带有名称的/ Library/LaunchDaemons中top-level-domain.your-domain.application.plist(放置它时需要是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>
Run Code Online (Sandbox Code Playgroud)

完成后,发出此信息(以root身份):

launchctl load /Library/LaunchDaemons/top-level-domain.your-domain.application.plist
launchctl start top-level-domain.your-domain.application
Run Code Online (Sandbox Code Playgroud)

而你正在跑步.

重启后你仍然会跑步.

有关plist中的其他选项,请查看此处的手册页:https://developer.apple.com/library/mac/documentation/Darwin/Reference/Manpages/man5/launchd.plist.5.html


Xeo*_*oss 16

如果您只是希望不间断地运行脚本直到它完成,您可以使用nohop此处的答案中已经提到的.但是,没有一个答案提供了一个完整的命令,也可以记录stdinstdout.

nohup node index.js >> app.log 2>&1 &
Run Code Online (Sandbox Code Playgroud)
  • >>方法追加到app.log.
  • 2>&1确保错误也发送到stdout并添加到app.log.
  • 结尾&确保您的当前终端与命令断开连接,以便您可以继续工作.

如果要运行节点服务器(或者在服务器重新启动时应该重新启动的东西),则应使用systemd/systemctl.


LoG*_*LoG 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
});
Run Code Online (Sandbox Code Playgroud)

最近我也使用来自TJ Holowaychuk的mon(1)来启动和管理简单的节点应用程序.


Don*_*ary 12

我使用Supervisor进行开发.它只是有效.当您对.js文件进行更改时,Supervisor会自动重新启动您的应用程序并加载这些更改.

这是Github页面的链接

安装:

sudo npm安装主管-g

您可以轻松地使用-e观看其他扩展程序.我经常使用的另一个命令是-i忽略某些文件夹.

即使在您注销后,您也可以使用nohup和supervisor使您的节点应用程序在后台运行.

sudo nohup主管myapp.js&


Him*_*tia 12

如果您使用nohup,请尝试运行此命令 -

nohup npm start 2>/dev/null 1>/dev/null&
Run Code Online (Sandbox Code Playgroud)

您也可以永远使用启动服务器

forever start -c "npm start" ./ 
Run Code Online (Sandbox Code Playgroud)

PM2也支持 npm start

pm2 start npm -- start
Run Code Online (Sandbox Code Playgroud)

  • thnx,这很好用。pm2 start npm-开始 (2认同)

Pag*_*Pro 7

Node.js作为WINDOWS XP中的后台服务

安装:

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

    @echo off
    nssm.exe install node-%~n1 "C:\Program Files\nodejs\node.exe" %~s1
    net start node-%~n1
    pause
    
    Run Code Online (Sandbox Code Playgroud)

服务管理:

  • 现在可以通过Start-> Run-> services.msc或通过Start-> Run-> MSCONFIG-> Services访问服务本身(并选中'Hide All Microsoft Services').
  • 该脚本将通过批处理脚本为每个节点添加前缀'node-'.
  • 同样,它们可以在注册表中找到:" HKLM\SYSTEM\CurrentControlSet\Services \node-xxxx "


Art*_*are 7

接受的答案可能是最好的生产答案,但是为了快速破解做开发工作,我发现了这个:

nodejs scriptname.js & 没有工作,因为nodejs似乎吞噬了&,所以事情没有让我继续使用终端没有scriptname.js死亡.

但是我输入nodejs scriptname.js了一个.sh文件,并且 nohup sh startscriptname.sh &工作了.

绝对不是生产的东西,但它解决了"我需要继续使用我的终端而不想启动5个不同终端"的问题.


小智 6

2017 年 6 月更新:
Linux 解决方案:(红帽)。以前的评论对我不起作用。这对我在 Amazon Web Service - 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
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)


Ped*_*niz 5

如果您在 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
Run Code Online (Sandbox Code Playgroud)