如何在 Debian 10 上为生产设置 Node.js 应用程序

介绍

Node.js是一个开源的JavaScript运行环境,用于构建服务器侧和网络应用程序. 该平台运行在Linux,macOS,FreeBSD和Windows上. 虽然您可以在命令行运行Node.js应用程序,但本教程将专注于将它们作为服务运行。

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

前提条件

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

当您完成前提条件后,您将有一个服务器,以服务您的域的默认位置主页在https://your_domain/`。

步骤 1 – 安装 Node.js

让我们先安装 Node.js 的最新 LTS 版本,使用 NodeSource包存档。

要安装 NodeSource PPA 并访问其内容,您首先需要更新您的包索引并安装 curl:

1sudo apt update
2sudo apt install curl

请确保您在您的主目录中,然后使用弯曲来获取 Node.js 10.x 档案的安装脚本:

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

您可以通过nano或您的 偏好文本编辑器检查本脚本的内容:

1nano nodesource_setup.sh

当你完成检查脚本时,在sudo下运行它:

1sudo bash nodesource_setup.sh

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

1sudo apt install nodejs

要检查在这些初步步骤后安装了哪个版本的 Node.js,请键入:

1nodejs -v
1[secondary_label Output]
2v10.16.0

<$>[注] 注: 在从 NodeSource PPA 安装时,Node.js 可执行程序被称为nodejs,而不是node

nodejs包包含了nodejs二进制以及npm(https://www.npmjs.com/),它是Node模块的包管理器,因此您不需要单独安装npm

npm 使用您的主目录中的配置文件来跟踪更新. 它将创建在您首次运行 npm. 执行此命令以验证 npm 已安装并创建配置文件:

1npm -v
1[secondary_label Output]
26.9.0

为了使某些npm包工作(例如需要编译源代码的包),您需要安装build-essential包:

1sudo apt install build-essential

您现在有必要的工具来处理需要编译源代码的npm包。

安装了 Node.js 运行时,我们可以继续写一个 Node.js 应用程序。

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

让我们写一个 Hello World 应用程序,该应用程序会返回任何 HTTP 请求的Hello World。这个样本应用程序将帮助您设置 Node.js。

首先,让我们创建一个名为hello.js的样本应用程序:

1cd ~
2nano hello.js

将以下代码插入到文件中:

 1[label ~/hello.js]
 2const http = require('http');
 3
 4const hostname = 'localhost';
 5const port = 3000;
 6
 7const server = http.createServer((req, res) => {
 8  res.statusCode = 200;
 9  res.setHeader('Content-Type', 'text/plain');
10  res.end('Hello World!\n');
11});
12
13server.listen(port, hostname, () => {
14  console.log(`Server running at http://${hostname}:${port}/`);
15});

保存文件并离开编辑器。

这个 Node.js 应用程序在指定的地址(‘localhost’)和端口(‘3000’)上收听,并以‘200’ HTTP 成功代码返回Hello World! 因为我们正在收听‘localhost’,所以远程客户端将无法连接到我们的应用程序。

要测试您的应用程序,类型:

1node hello.js

您将看到以下结果:

1[secondary_label Output]
2Server running at http://localhost:3000/

<$>[注] 注: 以这种方式运行 Node.js 应用程序将阻止额外的命令,直到您通过按下 CTRL+C来杀死该应用程序。

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

1[environment second]
2curl http://localhost:3000

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

1[secondary_label Output]
2[environment second]
3Hello World!

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

一旦你确定它工作,杀死应用程序(如果你还没有)通过按CTRL+C

步骤三:安装PM2

接下来,让我们安装 PM2,用于 Node.js 应用程序的流程管理器。

使用npm在您的服务器上安装最新版本的 PM2:

1sudo npm install pm2 -g

-g选项告诉npm在全球范围内安装模块,因此它可以在整个系统中使用。

让我们先使用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│ App name │ id │ mode │ pid  │ status │ restart │ uptime │ cpu │ mem       │ user  │ watching │
 8├──────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────┼───────────┼───────┼──────────┤
 9│ hello    │ 0  │ fork │ 1338 │ online │ 0       │ 0s     │ 0%  │ 23.0 MB   │ sammy │ disabled │
10└──────────┴────┴──────┴──────┴────────┴─────────┴────────┴─────┴───────────┴───────┴──────────┘
11 Use `pm2 show <id|name>` to get more details about an app

正如您所看到的,PM2 会根据文件名而自动分配一个应用名称,而不含.js扩展,以及一个 PM2 id。PM2 还保留其他信息,如过程的PID,其当前状态和内存使用情况。

如果应用程序故障或被杀死,在 PM2 下运行的应用程序将自动重新启动,但我们可以采取额外的步骤,通过启动子命令将应用程序启动到系统启动上。

1sudo pm2 startup

您将看到这样的输出,描述 PM2 产生的服务配置:

 1[secondary_label Output]
 2[PM2] Init System found: systemd
 3Platform systemd
 4Template
 5[Unit]
 6Description=PM2 process manager
 7Documentation=https://pm2.keymetrics.io/
 8After=network.target
 9
10[Service]
11Type=forking
12User=root
13LimitNOFILE=infinity
14LimitNPROC=infinity
15LimitCORE=infinity
16Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
17Environment=PM2_HOME=/root/.pm2
18PIDFile=/root/.pm2/pm2.pid
19Restart=on-failure
20
21ExecStart=/usr/lib/node_modules/pm2/bin/pm2 resurrect
22ExecReload=/usr/lib/node_modules/pm2/bin/pm2 reload all
23ExecStop=/usr/lib/node_modules/pm2/bin/pm2 kill
24
25[Install]
26WantedBy=multi-user.target
27
28Target path
29/etc/systemd/system/pm2-root.service
30Command list
31[ 'systemctl enable pm2-root' ]
32[PM2] Writing init configuration in /etc/systemd/system/pm2-root.service
33[PM2] Making script booting at startup...
34[PM2] [-] Executing: systemctl enable pm2-root...
35Created symlink /etc/systemd/system/multi-user.target.wants/pm2-root.service  /etc/systemd/system/pm2-root.service.
36[PM2] [v] Command successfully executed.
37+---------------------------------------+
38[PM2] Freeze a process list on reboot via:
39$ pm2 save
40
41[PM2] Remove init script via:
42$ pm2 unstartup systemd

您现在已经创建了一个 systemd unit,在启动时运行pm2,而这个pm2实例则运行hello.js

使用systemctl开始服务:

1sudo systemctl start pm2-root.service

检查系统d 单元的状态:

1systemctl status pm2-root.service

你应该看到的输出如下:

1[secondary_label Output]
2 pm2-root.service - PM2 process manager
3   Loaded: loaded (/etc/systemd/system/pm2-root.service; enabled; vendor preset: enabled)
4   Active: active (running) since Fri 2019-07-12 16:09:54 UTC; 4s ago

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

除了我们所涵盖的,PM2还提供许多子命令,允许您管理或搜索有关您的应用程序的信息。

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

1pm2 stop app_name_or_id

重新启动应用程序:

1pm2 restart app_name_or_id

列出目前由 PM2 管理的应用程序:

1pm2 list

使用其应用名称获取有关特定应用程序的信息:

1pm2 info app_name

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

1pm2 monit

请注意,在没有任何参数的情况下运行pm2也会显示有示例使用的帮助页面。

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

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

您的应用程序正在运行并听到本地主机,但您需要为您的用户设置一种访问方式,我们将为此设置 Nginx 网页服务器作为反向代理。

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

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

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

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

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

您可以向相同的服务器块添加额外的位置块,以便在相同的服务器上访问其他应用程序. 例如,如果您也在端口3001上运行另一个 Node.js 应用程序,您可以添加此位置块,以便通过https://your_domain/app2访问它:

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

完成为您的应用程序添加位置块后,保存文件并退出编辑器。

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

1sudo nginx -t

重新启动 Nginx:

1sudo systemctl restart nginx

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

结论

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

Published At
Categories with 技术
comments powered by Disqus