如何在 AWS 上的 Amazon Linux AMI 中自动启动 node.js 应用程序?

Posted

技术标签:

【中文标题】如何在 AWS 上的 Amazon Linux AMI 中自动启动 node.js 应用程序?【英文标题】:How can I automatically start a node.js application in Amazon Linux AMI on aws? 【发布时间】:2012-07-01 19:35:45 【问题描述】:

是否有简要指南来说明如何在实例启动和运行时启动应用程序?如果它是通过yum 安装的服务之一,那么我想我可以使用/sbin/chkconfig 将其添加到服务中。 (为了确定,是否正确?)

但是,我只想运行不是通过yum 安装的程序。要运行 node.js 程序,我必须在系统启动时在主目录中运行脚本 sudo node app.js

我不习惯 Amazon Linux AMI,因此我很难找到一种在每次启动时自动运行某些脚本的“正确”方法。

有没有优雅的方法来做到这一点?

【问题讨论】:

试试这个解决方案。这很简单。 ***.com/a/22171598/1028103 【参考方案1】:

一种方法是创建一个新贵的工作。这样,您的应用程序将在 Linux 加载后启动,如果它崩溃将自动重新启动,您可以通过 sudo start yourapp / sudo stop yourapp / sudo restart yourapp 启动/停止/重新启动它。

以下是开始步骤:

1) 安装 upstart 实用程序(如果您使用标准的 Amazon Linux AMI,则可能已预先安装):

sudo yum install upstart

对于 Ubuntu:

sudo apt-get install upstart

2) 为您的节点应用创建新贵脚本:

/etc/init 中添加文件yourappname.conf,代码行如下:

#!upstart
description "your app name"

start on started mountall
stop on shutdown

# Automatically Respawn:
respawn
respawn limit 99 5

env NODE_ENV=development

# Warning: this runs node as root user, which is a security risk
# in many scenarios, but upstart-ing a process as a non-root user
# is outside the scope of this question
exec node /path_to_your_app/app.js >> /var/log/yourappname.log 2>&1

3) 通过sudo start yourappname启动您的应用

【讨论】:

据我所知,亚马逊上运行的Linux是RedHat派生的,不是Ubuntu派生的,所以我不认为upstart可用。 也许吧。我在 Debian 上运行我的 Node.js 应用程序。 在 AWS 上:sudo yum install upstart sudo: start: command not found,我是否纠正了 ubunto 切换到 systemd 的问题? upstart 已被删除 :(【参考方案2】:

您可以使用 forever-service 将节点脚本配置为服务并在引导期间自动启动。下面的命令就可以了,

npm install -g forever-service
forever-service install test

这会将当前目录中的 app.js 提供为永久服务。每次系统重启时服务都会自动重启。此外,当停止时,它会尝试优雅地停止。该脚本还提供了logrotate 脚本。

Github 网址:https://github.com/zapty/forever-service

截至目前,forever-service 支持 Amazon Linux、CentOS、Redhat 对其他 Linux 发行版的支持,Mac 和 Windows 正在开发中..

注意:我是永远服务的作者。

【讨论】:

或如何在启动时启动您想要的任何应用程序,而无需在实例中编写代码。谢谢! 这不起作用让“永远服务必须以root身份运行”尝试“sudo永远服务安装测试”并且亚马逊linux响应“sudo:永远服务:找不到命令”【参考方案3】:

您的快速解决方案是从 /etc/rc.local 启动您的应用程序;只需在此处添加您的命令。

但如果你想走优雅的路,你必须将你的应用程序打包成一个 rpm 文件, 有一个进入 /etc/rc.d 的启动脚本,以便您可以在您的应用程序上使用 chkconfig,然后在您的实例上安装 rpm。

也许this 或this 有帮助。 (或者只是谷歌“创建 rpm 包”)

【讨论】:

如果我使用rpm方式,每次修改我的应用程序时是否必须重新构建rpm包? 是的,您的应用程序中的更改意味着创建和重新部署新的 .rpm,就像使用 yum 更新常规包一样。 无需创建 RPM 文件 - 您可以使用 init 脚本和 chkconfig 而无需创建 RPM。 当您打开 rc.local 时,您会看到一个很大的警告,告诉您它已被弃用,现在首选的方法是:systemd --> 请参阅我的答案。 :)【参考方案4】:

您可以创建一个可以启动和停止您的应用程序的脚本并将其放置在 /etc/init.d 中;使脚本遵守 chkconfig 的约定(如下),然后使用 chkconfig 将其设置为在其他服务启动时启动。

您可以从 /etc/init.d 中选择一个现有脚本作为示例; this article 描述的需求,基本上是:

标识所需 shell 的可执行脚本(即 #!/bin/bash) #chkconfig 格式的注释:where 通常是 345,startprio 表示服务的启动顺序,stopprio 是服务停止的顺序。我通常会选择一个已经存在的类似服务并将其用作这些值的指南(即,如果您有一个与 Web 相关的服务,请从与 httpd 相同的级别开始,并具有相似的启动和停止优先级)。

一旦你的脚本设置好了,你就可以使用

 chkconfig --add yourscript 
 chkconfig yourscript on 

你应该很高兴。 (某些发行版可能要求您手动将脚本符号链接到 /etc/init.d/rc.d,但我相信您的 AWS 发行版会在您启用脚本时为您执行此操作。

【讨论】:

【参考方案5】:

我的 Amazon Linux 实例在 Ubuntu 上运行,我使用 systemd 进行设置。

首先您需要创建一个<servicename>.service 文件。 (在我的情况下cloudyleela.service

sudo nano /lib/systemd/system/cloudyleela.service

在此文件中键入以下内容:

[Unit]
Description=cloudy leela
Documentation=http://documentation.domain.com
After=network.target

[Service]
Type=simple
TimeoutSec=0
User=ubuntu
ExecStart=/usr/bin/node /home/ubuntu/server.js
Restart=on-failure

[Install]
WantedBy=multi-user.target

在此应用程序中,node 应用程序已启动。您将需要一个完整的路径。我配置了如果出现问题,应用程序应该简单地重新启动。默认情况下,Amazon 使用的实例没有用户密码。

从磁盘重新加载文件,然后您就可以启动您的服务了。您需要启用它以使其作为服务激活,该服务会在启动时自动启动。

ubuntu@ip-172-31-21-195:~$ sudo systemctl daemon-reload
ubuntu@ip-172-31-21-195:~$ sudo systemctl start cloudyleela
ubuntu@ip-172-31-21-195:~$ sudo systemctl enable cloudyleela
Created symlink /etc/systemd/system/multi-user.target.wants/cloudyleela.service → /lib/systemd/system/cloudyleela.service.
ubuntu@ip-172-31-21-195:~$

一个很棒的 node.js 系统教程可用here。

如果您运行网络服务器:

您可能会在端口 80 上运行您的网络服务器时遇到一些问题。最简单的解决方案实际上是在不同的端口(例如 4200)上运行您的网络服务器,然后将该端口重定向到端口 80。 您可以使用以下命令完成此操作:

sudo iptables -t nat -A PREROUTING -i -p tcp --dport 80 -j REDIRECT --to-port 4200

不幸的是,这不是持久的,因此您必须在服务器重新启动时重复它。 更好的方法是在我们的服务脚本中也包含这个命令:

    ExecStartPre添加端口转发 ExecStopPost 去掉端口转发 PermissionStartOnly 使用 sudo 电源来完成此操作

所以,是这样的:

[Service]
...
PermissionsStartOnly=true
ExecStartPre=/sbin/iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 4200
ExecStopPost=/sbin/iptables -t nat -D PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 4200

不要忘记重新加载并重新启动您的服务:

[ec2-user@ip-172-31-39-212 system]$ sudo systemctl daemon-reload
[ec2-user@ip-172-31-39-212 system]$ sudo systemctl stop cloudyleela
[ec2-user@ip-172-31-39-212 system]$ sudo systemctl start cloudyleela
[ec2-user@ip-172-31-39-212 system]$

对于微服务(2020 年 12 月更新)

前面提到的解决方案提供了很大的灵活性,但设置它确实需要一些时间。对于每个额外的应用程序,您都需要再次完成整个过程。当您安装第 5 个节点应用程序时,您肯定会开始怀疑:“必须有一个快捷方式”

PM2 的优势在于它只需安装一项服务。接下来是管理实际应用程序的 PM2。

即使是 PM2 的初始设置也很容易,因为它会自动为您安装 pm2 服务。

npm install pm2 -g

而且添加新服务更加容易:

pm2 start index.js --name "foo"`. 

一切正常运行后,您可以保存设置,让它在重新启动时自动启动。

pm2 save

如果您想了解所有正在运行的节点应用程序, 你可以运行pm2 list

PM2 还提供了一个在线(基于 Web)仪表板来远程监控您的应用程序。不过,您可能需要许可证才能访问某些仪表板功能(恕我直言,这有点高估了)。

【讨论】:

请注意,PermissionsStartOnly 已被更灵活的“+”、“!”和“!!”弃用ExecStart= 和其他命令的前缀。相关问题:superuser.com/questions/1504114/…【参考方案6】:

使用 Elastic Beanstalk :) 提供对自动缩放、SSL 终止、蓝/绿部署等的支持

如果您想要基于 RedHat 的 linux 发行版(Amazon Linux 是 RedHat 的一种)的咸味 sysadmin 方式,请学习systemd,正如@bvdb 在上面的答案中提到的那样:

https://en.wikipedia.org/wiki/Systemd

按照描述在 EC2 实例上设置所有内容,创建自定义 AMI 的快照,并将此自定义 AMI 用作托管应用程序的 EC2 实例的基础。这样您就不必多次完成所有设置。如果您在具有正常运行时间要求的生产环境中运行,您可能还想熟悉负载均衡器。

或者,是的,正如@bvdb 所述,您还可以使用pm2systemd 进行交互。虽然我不认为 pm2 有助于跨多个 EC2 实例运行您的应用程序,但绝对推荐用于有正常运行时间要求的生产环境。

所有这些都是一个非常陡峭的学习曲线。由于 OP 似乎对这一切都很陌生,因此 Elastic Beanstalk、Google App Engine 等是让代码在云中运行而无需所有这些的好方法。

这些天我在 TypeScript 中进行开发,大多数事情都部署到云中的无服务器函数执行,根本不必考虑包安装或应用启动。

【讨论】:

【参考方案7】:

您可以使用screen。运行crontab -e 并添加这一行:

@reboot  screen -d -m bash -c "cd /home/user/yourapp/; node app"

【讨论】:

【参考方案8】:

一直在 AWS 上使用 forever,它做得很好。安装使用

 [sudo] npm install forever -g

添加应用程序使用

 forever start path_to_application

并停止应用程序使用

 forever stop path_to_application

This 是一篇有用的文章,帮助我进行了设置。

【讨论】:

但我需要在每次启动时运行forever node 模块? 是的。这在您从 shell 运行应用程序并希望在不停止应用程序的情况下退出 shell 的情况下很有用。如果应用程序因错误而终止,它还会重新启动应用程序。 不,永远不会在每次启动时启动。 -1。很抱歉,但这并不能回答问题 - 尽管是图片的一部分。如果您解释如何在启动时永远运行它,那么我将更改为 +1 在重启时永远运行脚本 crontab 可以使用:$ crontab -u user -e 并添加@reboot /usr/lib/node_modules/forever/bin/forever start /user/script.js

以上是关于如何在 AWS 上的 Amazon Linux AMI 中自动启动 node.js 应用程序?的主要内容,如果未能解决你的问题,请参考以下文章

如何检查 Amazon Linux 机器 (AMI) 上的 Tomcat 版本?

如何在 Amazon AWS 上设置一台 Linux 服务器

如何在 AWS EB Amazon Linux 2 平台上为 cron.d 添加环境属性引用

运行 AWS Deep Learning Base AMI (Amazon Linux 2) 时,如何在 Elastic Beanstalk 中设置 WSGI?

amazon免费服务器12个月linux查看硬盘信息命令

如何使用 Amazon Linux 2、单容器、无 Docker Compose 在 AWS Elastic Beanstalk 上获取 SYS_PTRACE