Node.js设置便于部署和更新

时间:2012-06-18 13:48:13

标签: node.js deployment updates

我们目前正在为一个node.js / socket.io应用程序支持的客户开发一个网站(Apache下的TYPO3),该应用程序为CMS提供的内容提供实时更新。

由于这是我们的第一个node.js项目,因此在完美设置方面,我没有任何最佳实践经验。所以我花了一些时间研究部署技术。

为了实现良好的设置,我仍然有几个问题:

  1. 客户易于部署。这非常重要,因为我们的网站将被整合到他们的“直播”中。 TYPO3安装服务于大量网站,并且运行在不受客户管理的服务器上,而是另一个(集中式)组织,这使得支持呼叫和服务器更改变得缓慢。

  2. 应该很容易更新。如上所述,请求重新启动并进行服务器更改是一个缓慢的过程,因此理想情况下,节点安装应该在收到推送到的更改时重新启动/更新使用git进行实时安装。

  3. 部署

    general consensus似乎是在部署节点应用程序以使其运行时使用forever。我已经对forever进行了测试,并且在npm install forever -g(全球)安装后似乎工作正常。这需要外部帮助来全局安装在实时环境中,所以我更喜欢从应用程序的node_modules目录运行它,但我还没有能够创建这样做的坚实包装。

    此外,forever工作正常,但必须手动启动。什么是确保它在服务器启动时启动并保持运行的最佳方法?

    • 一个简单的init.d脚本?
    • 编写看门狗包装器?
    • 检查forever状态的TYPO3调度程序任务?

    快速开发/重新启动

    我们目前仍处于项目的开发阶段,每次我对node.js应用程序进行更改时,我都会手动重启nodeforever。这有效,但远非理想。 有几个较小的npm模块用于检查文件修改并在检测到更改时重新启动node,例如:

    有没有人有过这方面的经验?

    更新:为什么不使用群集?

    Cluster module通过reload机制提供类似功能,但doesn't work with Node 0.5+。替换它的core Cluster module (Node 0.6+)没有所有这些功能,但只提供群集。反过来doesn't play well with socket.io。至少not without using Redis(这对我们来说是一个问题,因为我们无法向客户强制使用另一个先决条件服务)。

    -

    显然,在尝试将项目交给客户之前,我试图找到最稳定的解决方案,将更新重启器与forever结合起来,我真的希望有人能够生成经过验证的组合技术。

3 个答案:

答案 0 :(得分:63)

结合所收集的所有知识(非常感谢Julian Knight的想法)和过去一周测试的方法,我决定采用下面描述的部署解决方案(我认为我很高兴分享帮助其他有类似问题的人):

自动重启脚本错误 自动重新加载脚本更改由forever处理,因为它还包含脚本监视,只要Forever是从node.js脚本中生成的。

为此,我添加了server.js来启动我们实际想要运行的app.js脚本:

<强> server.js

var forever = require('forever'),
    child = new(forever.Monitor)('app.js', {
        'silent': false,
        'pidFile': 'pids/app.pid',
        'watch': true,
        'watchDirectory': '.',      // Top-level directory to watch from.
        'watchIgnoreDotFiles': true, // whether to ignore dot files
        'watchIgnorePatterns': [], // array of glob patterns to ignore, merged with contents of watchDirectory + '/.foreverignore' file
        'logFile': 'logs/forever.log', // Path to log output from forever process (when daemonized)
        'outFile': 'logs/forever.out', // Path to log output from child stdout
        'errFile': 'logs/forever.err'
    });
child.start();
forever.startServer(child);

这将监视应用程序目录中的所有文件以进行更改,并在更改后立即重新启动forever中运行的脚本。由于日志和pidfile位于应用程序的子目录中,因此必须从文件监视中忽略这些日志,否则脚本将循环重新启动:

<强> .foreverignore

pids/**
logs/**

要使这一切始于系统启动并使我们能够使用start node-appstop node-app轻松控制服务,我们会使用Ubuntu's Upstart。 我将两个例子(thisthis一个)组合成一个能很好地完成工作的例子:

<强> /etc/init/node-app.conf

# This is an upstart (http://upstart.ubuntu.com/) script
# to run the node.js server on system boot and make it
# manageable with commands such as
# 'start node-app' and 'stop node-app'
#
# This script is to be placed in /etc/init to work with upstart.
#
# Internally the 'initctl' command is used to manage:
# initctl help
# initctl status node-app
# initctl reload node-app
# initctl start node-app

description "node.js forever server for node-app"
author      "Remco Overdijk <remco@maxserv.nl>"
version "1.0"

expect fork

# 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

env HOME=/home/user/node-app-dir

script
    # Not sure why $HOME is needed, but we found that it is:
    export HOME=$HOME
    chdir $HOME
    exec /usr/local/bin/node server.js > logs/node.log &
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

作为Kevin wisely mentions in his article以root身份运行节点是不明智的,所以当我们下周迁移到新服务器时,我们会将其更改为exec sudo -u www-data /usr/local/bin/node

因此,forevernode server.js自动启动,upstart由{{1}}启动,并监控崩溃和文件更改,并保持整个设置尽可能长时间运行。

我希望这对任何人都有帮助。

答案 1 :(得分:7)

因为我的上一个答案是为了将来!以下是其他一些辅助链接:

似乎还没有一个完美的答案,但有很多人在运行生产节点实例。希望这会指出你正确的方向。

答案 2 :(得分:5)

对于生产用途,您可能会更好地查看Cluster之类的内容。您可能不需要群集功能,但它还包括其他生产功能,例如零停机重启,日志记录,工作人员等。

正如你所说,Forever可以进行测试,但实际上没有生产用途。

我似乎依稀记得Cluster或类似的东西可能被采纳到Node本身来v0.7