【问题标题】:How do I run a Node.js application as its own process?如何将 Node.js 应用程序作为自己的进程运行?
【发布时间】:2011-06-08 12:57:30
【问题描述】:

部署 Node.js 的最佳方式是什么?

我有一个 Dreamhost VPS(他们称之为VM),我已经能够安装 Node.js 并设置代理。只要我保持打开节点的 SSH 连接,这将非常有效。

【问题讨论】:

  • 嗯,您将使用 Forever 称为“部署 node.js”对我来说似乎很奇怪。它不只是一个过程监控/监督工具吗?通常,Web 部署意味着(至少我在文章中遇到的)几个相互关联的活动,这些活动使 Web 应用程序可用(这个过程工具是其中的一部分)。无论如何,这仍然是 StackOverflow 中的一篇很棒的帖子,正如我从每个人的回答中了解到的那样。
  • 这只是在 Dreamhost 上最简单的 node.js 部署。目标只是让节点可靠地运行,以此作为构建的起点。
  • 您是如何处理将域转发到正在运行的端口节点的?
  • @grm 我使用 HTTP-Proxy github.com/nodejitsu/node-http-proxy
  • 我们现在正在使用 Elastic Beanstalk,它运行良好。

标签: node.js service deployment daemon


【解决方案1】:

2016 年回答:几乎每个 Linux 发行版都带有 systemd,这意味着 不再需要永远、monit、PM2 等 - 您的操作系统已经处理这些任务

制作一个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=nobody
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,并打开可执行模式 chmod +x myapp.js

将您的服务文件复制到/etc/systemd/system 文件夹中。

通过systemctl daemon-reload 告诉 systemd 新服务。

systemctl start myapp 开头。

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

使用journalctl -u myapp查看日志

这取自 How we deploy node apps on Linux, 2018 edition,其中还包括生成 AWS/DigitalOcean/Azure CloudConfig 以构建 Linux/节点服务器的命令(包括 .service 文件)。

【讨论】:

  • 知道如何处理Failed to issue method call: Unit name ... is not valid. 吗?
  • @JulienGenestoux “单位”名称与您的服务相同。那里好像有异曲同工之妙。将文件复制到/etc/systemd/system 后,您可能需要运行systemctl daemon-reload(systemd 通常会告诉您是否需要这样做)。 TBH 这最好作为一个单独的问题提出。
  • 您可以使用systemctl enable /full/path/to/myapp.service,而不是将您的服务文件复制到/etc/systemd/system,它会在/etc/systemd/system 中为您创建一个符号链接。
  • 与pm2相比如何?它可以替代 pm2 还是 pm2 提供更多必要的功能?
  • @VinodSrivastav node/var/www/myapp/app.js 本身调用。在 Unix 中,如果您使文件可执行,并且第一行以 #!/some/file 开头,则该文件将使用该二进制文件进行解释。谷歌“解释 Unix”以了解更多信息。
【解决方案2】:

试试node-deploy-server。它是一个复杂的工具集,用于将应用程序部署到您的私有服务器上。它是用 Node.js 编写的,使用 npm 进行安装。

【讨论】:

    【解决方案3】:

    pm2 可以解决问题。

    功能包括:监控、热代码重载、内置负载平衡器、自动启动脚本和复活/转储进程。

    【讨论】:

    • 是否兼容 Heroku 等服务?
    • @FRD 我不认为它适用于 heroku,检查this article
    • 这对我来说是最好的。
    【解决方案4】:

    正如 Box9 所说,Forever 是生产代码的不错选择。但即使从客户端关闭SSH 连接,也可以保持进程继续进行。

    虽然对于生产来说不一定是一个好主意,但这在长时间调试会话中非常方便,或者跟踪冗长进程的控制台输出,或者在断开 SSH 连接但保持终端活动时有用在服务器中稍后重新连接(例如在家里启动 Node.js 应用程序,然后在工作时重新连接到控制台以检查事情进展如何)。

    假设您的服务器是 *nix 机器,即使客户端 SSH 关闭,您也可以使用 shell 中的screen 命令来保持进程运行。如果尚未安装,您可以从 Web 下载/安装屏幕(如果是 Linux,请为您的发行版查找软件包,如果是 OS X,请使用 MacPorts)。

    它的工作原理如下:

    1. 当您第一次打开 SSH 连接时,输入“screen” - 这将启动您的 screen 会话。
    2. 开始正常工作(即启动您的 Node.js 应用程序)
    3. 完成后,关闭终端。您的服务器进程将继续运行。
    4. 要重新连接到您的控制台,请通过 ssh 回到服务器,登录并输入“screen -r”以重新连接。您的旧控制台上下文将弹出,供您继续使用。
    5. 要退出屏幕,在连接到服务器时,在控制台提示符下键入“exit” - 这将使您进入常规 shell。

    如果需要,您可以像这样同时运行多个屏幕会话,并且可以从任何客户端连接到其中的任何一个。在线阅读文档以了解所有选项。

    【讨论】:

    • 有很好的信息。我同意它不适用于生产,但在远程服务器上调试时可能非常有用。
    • 为什么不直接使用 nohup node myapp.js & 2>/var/log/myapp.log 1>/dev/null
    • 我发现这个 av 有用 youtube.com/watch?v=P4mT5Tbx_KE 解释 nohupforever
    【解决方案5】:

    我已经编写了一个非常全面的 Node.js 部署指南,其中包含示例文件:

    Tutorial: How to Deploy Node.js Applications, With Examples

    它涵盖了诸如 http-proxy、SSLSocket.IO 之类的东西。

    【讨论】:

    • 这看起来很棒。我正在使用 heroku 进行开发和初始启动,但最终需要超越 heroku 并直接部署到 EC2。有时间我会玩这个。
    【解决方案6】:

    我在这里写过我的部署方法:Deploying node.js apps

    简而言之:

    • 使用 git post-receive hook
    • Jake 用于构建工具
    • Upstart 作为节点的服务包装器
    • 监控并在应用程序出现故障时重新启动它们
    • nginx 将请求路由到同一服务器上的不同应用程序

    【讨论】:

    • 如果我的服务器上总是只有一个 Node 站点,我可以安全地抛弃 Nginx 吗?
    • 链接好像坏了
    • @Dor 我知道这是一个迟到的回复,但我不会。除了 SSL 终止和缓存之类的东西之外,主机前面的 nginx 反向代理可以让您比直接在端口 80 上运行节点具有更大的基础设施灵活性。这也意味着您不必以 root 身份运行节点,我认为这是支持 nginx 设置的一个相当激烈的论点。
    【解决方案7】:

    在您的情况下,您可以使用upstart 守护程序。对于完整的部署解决方案,我可能会建议capistrano。两个有用的指南是 How to setup Node.js envHow to deploy via capistrano + upstart

    【讨论】:

    • 最后两个的死链接
    【解决方案8】:

    Forever 可以解决问题。

    @Kevin:您应该能够很好地终止进程。我会仔细检查一下文档。如果您可以重现该错误,最好将其作为问题发布在 GitHub 上。

    【讨论】:

    • 凯文是谁? OP?
    【解决方案9】:

    使用Forever。它在单独的进程中运行 Node.js 程序,并在任何进程死亡时重新启动它们。

    用法:

    • forever start example.js 启动进程。
    • forever list 查看由 forever 启动的所有进程的列表
    • forever stop example.js 停止进程,或forever stop 0 停止索引为 0 的进程(如 forever list 所示)。

    【讨论】:

    • 这很接近。它开始很好,但不会让我停止任何事情。我能够注销并重新登录,然后终止节点进程。永远没有重新启动它。所以我在想它的工作方式与 DH 不兼容。
    • @Kevin,你不能杀死节点进程,因为 Forever 本身在节点上运行!我在答案中添加了一些使用说明,包括如何停止进程。我一直在我的 VPS 上使用它,它就像一个魅力。
    • forever stop 0 有一个错误,事情就从那里分崩离析了。我一直在尝试在自己的用户没有 root 的情况下执行此操作,以便在找到正确的解决方案后轻松清理。那可能是我的问题。我会再研究一下。
    • 我的 npm 出了点问题,导致了问题。正确安装 npm 和节点后,效果会很好。我最终做的是将永远启动命令添加到一个 cronjob 集以在重新启动时运行。我现在正在开发一个小节点应用程序,它可以让我永远启动和停止 procs。
    • Forever 有一个替代方案,它使用节点的本机集群 API:github.com/superjoe30/naught
    【解决方案10】:

    如果您具有 root 访问权限,则最好设置一个守护程序,以便它在后台安全运行。您可以在博文 Run Node.js as a Service on Ubuntu 中阅读 DebianUbuntu 的操作方法。

    【讨论】:

    • 我不认为我有 root 但似乎我只需要在网络面板中启用它。我会试一试。
    【解决方案11】:

    https://paastor.com 是一项相对较新的服务,可以为您部署到 VPS 或其他服务器。有一个 CLI 可以推送代码。 Paastor 有一个免费套餐,至少在发布此内容时是这样。

    【讨论】:

      【解决方案12】:

      试试这个:http://www.technology-ebay.de/the-teams/mobile-de/blog/deploying-node-applications-with-capistrano-github-nginx-and-upstart.html

      使用 Capistrano、Upstart 和 Nginx 部署 Node.js 应用程序的详细指南

      【讨论】:

        【解决方案13】:

        我制作了一个目前用于我的应用程序的 Upstart 脚本:

        description "YOUR APP NAME"
        author "Capy - http://ecapy.com"
        
        env LOG_FILE=/var/log/node/miapp.log
        env APP_DIR=/var/node/miapp
        env APP=app.js
        env PID_NAME=miapp.pid
        env USER=www-data
        env GROUP=www-data
        env POST_START_MESSAGE_TO_LOG="miapp HAS BEEN STARTED."
        env NODE_BIN=/usr/local/bin/node
        env PID_PATH=/var/opt/node/run
        env SERVER_ENV="production"
        
        ######################################################
        
        start on runlevel [2345]
        stop on runlevel [016]
        
        respawn
        respawn limit 99 5
        
        pre-start script
            mkdir -p $PID_PATH
            mkdir -p /var/log/node
        end script
        
        script
            export NODE_ENV=$SERVER_ENV
            exec start-stop-daemon --start --chuid $USER:$GROUP --make-pidfile --pidfile $PID_PATH/$PID_NAME --chdir $APP_DIR --exec $NODE_BIN -- $APP >> $LOG_FILE 2>&1
        end script
        
        post-start script
            echo $POST_START_MESSAGE_TO_LOG >> $LOG_FILE
        end script
        

        自定义#########之前的所有内容,在/etc/init/your-service.conf中创建一个文件并粘贴到那里。

        那么你可以:

        start your-service
        stop your-service
        restart your-service
        status your-service
        

        【讨论】:

        • 谢谢,正是我需要的。
        【解决方案14】:

        Forever 是保持应用程序运行的好选择(它可以作为一个模块安装在 npm 中,这很不错)。

        但是对于更严肃的“部署”——比如远程管理部署、重启、运行命令等——我会使用带有节点扩展的 capistrano。

        https://github.com/loopj/capistrano-node-deploy

        【讨论】:

          【解决方案15】:

          这里有一篇关于使用 systemd 解决这个问题的较长文章:http://savanne.be/articles/deploying-node-js-with-systemd/

          注意事项:

          • 谁将开始您的过程监控? Forever 是一个很棒的工具,但它需要一个监控工具来保持自身运行。有点傻,为什么不直接用你的init系统呢?
          • 您能否充分监控您的流程?
          • 您是否正在运行多个后端?如果是这样,您是否有适当的规定来防止其中任何一个在资源使用方面降低其他的?
          • 是否始终需要该服务?如果没有,请考虑激活套接字(参见文章)。

          所有这些事情都可以通过 systemd 轻松完成。

          【讨论】:

            【解决方案16】:

            您可以使用monitforeverupstartsystemd 来启动您的服务器。

            您可以使用 Varnish 或 HAProxy 代替 Nginx(已知 Nginx 不能与 websockets 一起使用)。

            作为一种快速而肮脏的解决方案,您可以使用nohup node your_app.js & 来防止您的应用与您的服务器终止,但forevermonit 和其他建议的解决方案更好。

            【讨论】:

            • 一位用户“Sergey Yarotskiy”试图编辑你的帖子,说 Nginx 现在支持 WebSockets(从 1.3 版开始)。我拒绝了编辑,因为我认为它应该作为评论发布。 (否则你会在同一篇文章中有两个相互矛盾的句子,这会令人困惑。)
            猜你喜欢
            • 2019-03-09
            • 2014-12-07
            • 2012-11-02
            • 2011-04-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多