如何在 Ubuntu 16.04 上设置用于生产的 Node.js 应用程序

介绍

Node.js 是一个开源的 JavaScript 运行环境,用于构建服务器侧和网络应用程序. 该平台运行在 Linux、MacOS、FreeBSD 和 Windows 上. Node.js 应用程序可以在命令行运行,但我们将专注于将其作为服务运行,以便在重新启动或故障时自动重新启动,并可以在生产环境中安全使用。

在本教程中,我们将涵盖在一台Ubuntu 16.04服务器上设置一个生产准备的Node.js环境,该服务器将运行由PM2管理的Node.js应用程序,并通过Nginx反向代理程序为用户提供安全访问。

前提条件

本指南假定您有以下内容:

当您完成前提条件后,您将有一个服务器,服务于默认的 Nginx 位置主页 https://example.com/

让我们通过在您的服务器上安装 Node.js 运行时间来开始。

步骤 1 – 安装 Node.js

我们将使用 NodeSource包档案安装 Node.js 的最新 LTS 版本。

首先,您需要安装 NodeSource PPA 才能访问其内容. 请确保您位于您的主目录中,并使用‘curl’来获取 Node.js 16.x 档案的安装脚本:

1cd ~
2curl -sL https://deb.nodesource.com/setup_16.x -o nodesource_setup.sh

您可以使用nano检查本脚本的内容(或您喜爱的文本编辑器):

1nano nodesource_setup.sh

然后在sudo下运行脚本:

1sudo bash nodesource_setup.sh

PPA 将被添加到您的配置中,您的本地包缓存将自动更新。从 nodesource 运行安装脚本后,您可以以上面的方式安装 Node.js 包:

1sudo apt-get install nodejs

nodejs包包含node二进制和npm,因此您不需要单独安装npm

1sudo apt-get install build-essential

Node.js 运行时间已安装,并准备运行应用程序. 让我们写一个 Node.js 应用程序。

步骤 2 — 创建 Node.js 应用程序

我们会写一个 Hello World 应用程序,该应用程序会返回任何 HTTP 请求的Hello World,这是一个样本应用程序,可以帮助您设置 Node.js,您可以用自己的应用程序代替它 - 只需确保您修改您的应用程序以倾听适当的 IP 地址和端口。

世界代码

首先,创建并打开您的 Node.js 应用程序进行编辑. 对于本教程,我们将使用nano来编辑名为hello.js的样本应用程序:

1cd ~
2nano hello.js

如果您想要,您可以在两个位置更换突出的端口,‘8080’(请确保使用非管理员端口,即1024或更大):

1[label hello.js]
2#!/usr/bin/env nodejs
3var http = require('http');
4http.createServer(function (req, res) {
5  res.writeHead(200, {'Content-Type': 'text/plain'});
6  res.end('Hello World\n');
7}).listen(8080, 'localhost');
8console.log('Server running at http://localhost:8080/');

现在保存和退出。

此 Node.js 应用程序在指定地址(‘localhost’)和端口(‘8080’)上收听,并以‘200’ HTTP 成功代码返回Hello World

测试应用

要测试您的应用程序,请将hello.js设置为使用chmod进行执行:

1chmod +x ./hello.js

然后这样运行:

1./hello.js
1[secondary_label Output]
2Server running at http://localhost:8080/

<$>[注] 注: 以这种方式运行 Node.js 应用程序将阻止额外的命令,直到应用程序通过按压 Ctrl-C 被杀死。

要测试应用程序,请在您的服务器上打开另一个终端会话,并使用弯曲连接到 localhost:

1curl http://localhost:8080

如果您看到以下输出,应用程序正在正常工作,并在正确的地址和端口上收听:

1[secondary_label Output]
2Hello World

如果您看不到正确的输出,请确保您的 Node.js 应用程序正在运行,并配置为听取正确的地址和端口。

一旦你确定它正在工作,转回到你的其他终端,并杀死Node.js应用程序(如果你还没有)通过按 Ctrl+C

步骤三:安装PM2

现在我们将安装PM2,这是Node.js应用程序的流程管理器,PM2提供了管理和解除应用程序(作为服务在背景中运行应用程序)的简单方法。

我們將使用「npm」,即與 Node.js 一起安裝的 Node 模組的包管理器,在我們的伺服器上安裝 PM2。

1sudo npm install -g pm2

-g选项告诉npm安装模块 globally,以便它在整个系统中可用。

步骤 4 – 使用 PM2 管理应用程序

我们将讨论一些PM2的基本用途。

启动应用

您要做的第一件事是使用pm2 start命令在背景中运行您的应用程序hello.js:

1pm2 start hello.js

这还会将您的应用程序添加到 PM2 的流程列表中,该列表每次启动应用程序时都会输出:

 1[secondary_label Output]
 2[PM2] Spawning PM2 daemon with pm2_home=/home/sammy/.pm2
 3[PM2] PM2 Successfully daemonized
 4[PM2] Starting /home/sammy/hello.js in fork_mode (1 instance)
 5[PM2] Done.
 6┌─────┬──────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
 7│ id  │ name     │ namespace   │ version │ mode    │ pid      │ uptime │ ↺    │ status    │ cpu      │ mem      │ user     │ watching │
 8├─────┼──────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
 9│ 0   │ hello    │ default     │ N/A     │ fork    │ 13734    │ 0s     │ 0    │ online    │ 0%       │ 25.0mb   │ sammy    │ disabled │
10└─────┴──────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘

正如您所看到的,PM2 会自动分配一个 name(基于文件名,不含.js扩展)和一个 PM2 id

如果应用程序故障或死亡,在PM2下运行的应用程序将自动重新启动,但需要采取额外的步骤来让应用程序在系统启动(启动或重新启动)上启动。

启动子命令生成并配置一个启动脚本,以便在服务器机器人上启动PM2及其管理流程:

1pm2 startup systemd

结果输出的最后一行将包含一个命令,您必须使用超级用户权限运行:

1[secondary_label Output]
2[PM2] Init System found: systemd
3[PM2] You have to run this command as root. Execute the following command:
4sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy

运行生成的命令(类似于上面的突出输出,但使用您的用户名而不是sammy)以设置PM2开始启动(使用来自自己的输出的命令):

1sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy

这将创建一个 systemd unit,为您的启动用户运行pm2。这个pm2实例,反过来,运行hello.js

1systemctl status pm2-sammy

有关 systemd 的详细概述,请参阅 Systemd Essentials: Working with Services, Units, and the Journal

其他 PM2 用途(可选)

PM2提供了许多子命令,允许您管理或搜索有关您的应用程序的信息。 请注意,运行pm2没有任何论点会显示一个帮助页面,包括示例使用,该页面比本教程的本节更详细地涵盖了PM2的使用。

使用此命令停止应用程序(指定PM2应用程序名称id):

1pm2 stop app_name_or_id

使用此命令重新啟動應用程式(指定 PM2「應用程式名稱」或「id」):

1pm2 restart app_name_or_id

目前由 PM2 管理的应用程序列表也可以通过列表子命令查看:

1pm2 list

有关特定应用程序的更多信息可以通过使用info子命令找到(指定 PM2 App nameid):

1pm2 info example

PM2 流程监视器可以通过monit子命令拉上,显示应用程序状态、CPU 和内存使用量:

1pm2 monit

现在您的 Node.js 应用程序正在运行,并由 PM2 管理,让我们设置反向代理。

步骤 5 — 将 Nginx 设置为反向代理服务器

现在你的应用程序正在运行,并听到 localhost,你需要为你的用户设置一种方式来访问它. 我们将为此目的设置 Nginx Web 服务器作为反向代理。

在前提教程中,我们将我们的 Nginx 配置设置为 /etc/nginx/sites-available/default 文件。

1sudo nano /etc/nginx/sites-available/default

服务器区块中,你应该有一个现有的位置/区块,用以下配置来替换该区块的内容,如果你的应用程序设置为在不同的端口上聆听,请将突出部分更新到正确的端口号。

 1[label /etc/nginx/sites-available/default]
 2. . .
 3    location / {
 4        proxy_pass http://localhost:8080;
 5        proxy_http_version 1.1;
 6        proxy_set_header Upgrade $http_upgrade;
 7        proxy_set_header Connection 'upgrade';
 8        proxy_set_header Host $host;
 9        proxy_cache_bypass $http_upgrade;
10    }
11}

假设我们的服务器在example.com上可用,通过网页浏览器访问https://example.com/将请求发送到hello.js,在端口8080听到localhost**

您可以将额外的位置块添加到相同的服务器块中,以便提供在相同的服务器上其他应用程序的访问。例如,如果您也在端口8081上运行另一个 Node.js 应用程序,您可以添加此位置块来允许通过http://example.com/app2访问:

1[label /etc/nginx/sites-available/default — Optional]
2    location /app2 {
3        proxy_pass http://localhost:8081;
4        proxy_http_version 1.1;
5        proxy_set_header Upgrade $http_upgrade;
6        proxy_set_header Connection 'upgrade';
7        proxy_set_header Host $host;
8        proxy_cache_bypass $http_upgrade;
9    }

一旦您完成为您的应用程序添加位置块,保存和退出。

确保您没有输入任何语法错误,键入:

1sudo nginx -t

接下来,重新启动 Nginx:

1sudo systemctl restart nginx

假设您的 Node.js 应用程序正在运行,您的应用程序和 Nginx 配置是正确的,您现在应该能够通过 Nginx 反向代理程序访问您的应用程序。

结论

恭喜您! 您现在有 Node.js 应用程序在 Ubuntu 16.04 服务器上运行 Nginx 反向代理程序后面。 此反向代理程序设置足够灵活,可为用户提供您想要共享的其他应用程序或静态 Web 内容。

Published At
Categories with 技术
comments powered by Disqus