介绍
Node.js是一个开源的JavaScript运行环境,用于构建服务器侧和网络应用程序. 该平台运行在Linux,macOS,FreeBSD和Windows上. 虽然您可以在命令行运行Node.js应用程序,但本教程将专注于将它们作为服务运行。
在本教程中,您将在单一的 Debian 9 服务器上设置一个生产准备的 Node.js 环境,该服务器将运行由 PM2管理的 Node.js 应用程序,并通过 Nginx反向代理提供用户安全访问该应用程序。
前提条件
本指南假定您有以下内容:
- Debian 9 服务器设置,如在 Debian 9 初始服务器安装指南中所述。你应该有一个具有 sudo 特权和活跃防火墙的非根用户。
- A 域名指向你的服务器的公共 IP。本教程将使用域名 example.com在整个过程中。
- Nginx 安装,如在 如何在 Debian 9 上安装 Nginx中所述)。
- Nginx 使用 SSL 配置使用 Let's Encrypt 证书。
当您完成前提条件后,您将有一个服务器来服务您的域的默认位置主页在https://example.com/`。
步骤 1 – 安装 Node.js
让我们先安装 Node.js 的最新 LTS 版本,使用 NodeSource包存档。
要安装 NodeSource PPA 并访问其内容,您首先需要更新您的包索引并安装 curl
:
1sudo apt update
2sudo apt install curl
请确保您在您的主目录中,然后使用弯曲
来获取 Node.js 8.x 档案的安装脚本:
1cd ~
2curl -sL https://deb.nodesource.com/setup_8.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]
2v8.11.4
<$>[注]
注: 在从 NodeSource PPA 安装时,Node.js 可执行程序被称为nodejs
,而不是node
。
nodejs
包包含了nodejs
二进制以及npm
(https://www.npmjs.com/),它是Node模块的包管理器,因此您不需要单独安装npm
。
npm
使用您的主目录中的配置文件来跟踪更新. 它将创建在您首次运行 npm
. 执行此命令以验证 npm
已安装并创建配置文件:
1npm -v
1[secondary_label Output]
25.6.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@latest -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下运行的应用程序将自动重新启动,但我们可以采取额外的步骤,通过startup
子命令将应用程序启动到系统启动上。
1pm2 startup systemd
结果输出的最后一行将包含一个命令以超级用户权限运行,以设置PM2开始启动:
1[secondary_label Output]
2[PM2] Init System found: systemd
3[PM2] To setup the Startup Script, copy/paste the following command:
4sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy
从输出中运行命令,使用您的用户名代替sammy
:
1sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy
作为一个额外的步骤,我们可以保存 PM2 流程列表和相应的环境:
1pm2 save
您现在已经创建了一个 systemd unit,该实例为您的启动用户运行pm2
。
使用systemctl
开始服务:
1sudo systemctl start pm2-sammy
检查系统d 单元的状态:
1systemctl status pm2-sammy
有关 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/example.com
文件。
1sudo nano /etc/nginx/sites-available/example.com
在服务器
区块中,你应该有一个现有的位置/
区块,用以下配置来替换该区块的内容,如果你的应用程序设置为在不同的端口上收听,请将突出部分更新到正确的端口号:
1[label /etc/nginx/sites-available/example.com]
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}
假设我们的服务器在example.com
上可用,通过网页浏览器访问https://example.com/
将请求发送到hello.js
,在localhost
端口3000
上聆听。
您可以将额外的位置
块添加到相同的服务器块中,以便提供在相同的服务器上其他应用程序的访问。例如,如果您也在端口3001
上运行另一个 Node.js 应用程序,您可以添加此位置块,以便通过https://example.com/app2
访问它:
1[label /etc/nginx/sites-available/example.com — 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 9 服务器上运行 Nginx 反向代理程序后面,此反向代理程序设置足够灵活,可以让您的用户访问您想要共享的其他应用程序或静态 Web 内容。