介绍
Node.js是一个开源的JavaScript运行环境,用于构建服务器侧和网络应用程序. 该平台运行在Linux,macOS,FreeBSD和Windows上. 虽然您可以在命令行运行Node.js应用程序,但本教程将专注于将它们作为服务运行。
在本教程中,您将在单个Rocky Linux 9服务器上设置一个生产准备的Node.js环境,该服务器将运行由PM2(http://pm2.keymetrics.io/)管理的Node.js应用程序,并通过Nginx反向代理提供用户安全访问该应用程序。
前提条件
本指南假定您有以下内容:
- Rocky Linux 9 服务器设置,如在 Rocky Linux 9 初始服务器设置指南中所述) 你应该有一个非 root 用户,具有 sudo 特权和活跃的防火墙。
- A 域名指向您的服务器的公共 IP。本教程将使用域名 example.com在整个过程中。
- Nginx 安装,如在 How To Install Nginx on Rocky Linux 9中所述。
- Nginx 配置与 SSL 使用
Let’s Encrypt
证书。 How To Secure Nginx with Let’s Encrypt on Rocky Linux 9 将
](https://andsky.com/tech/tutorials/如何安装-node-js-on-rocky-linux-9)
当您完成前提条件后,您将有一个服务器来服务您的域的默认位置主页在https://example.com/`。
步骤 1 — 创建一个 Node.js 应用程序
让我们写一个 Hello World 应用程序,该应用程序将返回任何 HTTP 请求的Hello World
。这个样本应用程序将帮助您在 Node.js 上运行,您可以用自己的应用程序代替它 - 只需确保您修改您的应用程序以倾听适当的 IP 地址和端口。
Rocky Linux 9 附带的默认文本编辑器是 vi
。 vi
是一个非常强大的文本编辑器,但对于缺乏经验的用户来说,它可能有点杂,您可能想安装一个更易于使用的编辑器,例如 nano
,以便在 Rocky Linux 9 服务器上编辑配置文件:
1sudo dnf install nano
现在,使用nano
或您最喜欢的文本编辑器,创建一个名为hello.js
的样本应用程序:
1nano 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});
保存文件并退出编辑器. 如果您正在使用nano
,请按Ctrl+X
,然后在提示时按Y
,然后输入。
这个 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
。
第2步:安装PM2
接下来,让我们安装 PM2,一个 Node.js 应用程序的流程管理器。
使用npm
在您的服务器上安装最新版本的 PM2:
1sudo npm install pm2@latest -g
-g
选项告诉npm
安装模块 globally,以便它在整个系统中可用。
让我们先使用pm2 start
命令在背景中运行您的应用程序hello.js
:
1pm2 start hello.js
这还会将您的应用程序添加到 PM2 的流程列表中,该列表每次启动应用程序时都会输出:
1[secondary_label Output]
2...
3[PM2] Spawning PM2 daemon with pm2_home=/home/sammy/.pm2
4[PM2] PM2 Successfully daemonized
5[PM2] Starting /home/sammy/hello.js in fork_mode (1 instance)
6[PM2] Done.
7┌────┬────────────────────┬──────────┬──────┬───────────┬──────────┬──────────┐
8│ id │ name │ mode │ ↺ │ status │ cpu │ memory │
9├────┼────────────────────┼──────────┼──────┼───────────┼──────────┼──────────┤
10│ 0 │ hello │ fork │ 0 │ online │ 0% │ 25.2mb │
11└────┴────────────────────┴──────────┴──────┴───────────┴──────────┴──────────┘
如上所示,PM2 会自动分配一个应用名称
(基于文件名,不含.js
扩展)和一个 PM2 id
。PM2 还保留了其他信息,如过程的PID
,其当前状态和内存使用情况。
如果应用程序故障或被杀死,在PM2下运行的应用程序将自动重新启动,但我们可以采取额外的步骤,通过startup
子命令将应用程序启动到系统启动上。
1pm2 startup systemd
1[secondary_label Output]
2…
3[PM2] To setup the Startup Script, copy/paste the following command:
4sudo env PATH=$PATH:/usr/bin /usr/local/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy
复制并运行所提供的命令(这是为了避免在运行 Node.js 工具时的权限问题sudo
):
1sudo env PATH=$PATH:/usr/bin /usr/local/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy
1[secondary_label Output]
2…
3[ 'systemctl enable pm2-sammy' ]
4[PM2] Writing init configuration in /etc/systemd/system/pm2-sammy.service
5[PM2] Making script booting at startup...
6[PM2] [-] Executing: systemctl enable pm2-sammy...
7Created symlink /etc/systemd/system/multi-user.target.wants/pm2-sammy.service → /etc/systemd/system/pm2-sammy.service.
8[PM2] [v] Command successfully executed.
9+---------------------------------------+
10[PM2] Freeze a process list on reboot via:
11$ pm2 save
12
13[PM2] Remove init script via:
14$ pm2 unstartup systemd
现在,您需要对刚刚生成的系统服务进行编辑,以使其与Rocky Linux的SELinux安全系统兼容。使用nano
或您最喜欢的文本编辑器,打开/etc/systemd/system/pm2-sammy.service
:
1sudo nano /etc/systemd/system/pm2-sammy.service
在配置文件的[服务]
块中,如下所示,替换PIDFile
设置的内容为/run/pm2.pid
,并添加另一个突出的环境
行:
1[label /etc/systemd/system/pm2-sammy.service]
2[Unit]
3Description=PM2 process manager
4Documentation=https://pm2.keymetrics.io/
5After=network.target
6
7[Service]
8Type=forking
9User=sammy
10LimitNOFILE=infinity
11LimitNPROC=infinity
12LimitCORE=infinity
13Environment=PATH=/home/sammy/.local/bin:/home/sammy/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/usr/bin:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
14Environment=PM2_HOME=/home/sammy/.pm2
15PIDFile=/run/pm2.pid
16Restart=on-failure
17Environment=PM2_PID_FILE_PATH=/run/pm2.pid
18
19ExecStart=/usr/local/lib/node_modules/pm2/bin/pm2 resurrect
20ExecReload=/usr/local/lib/node_modules/pm2/bin/pm2 reload all
21ExecStop=/usr/local/lib/node_modules/pm2/bin/pm2 kill
22
23[Install]
保存并关闭文件. 您现在已经创建了一个 systemd unit 运行为您的用户在启动时的 pm2
这个 pm2
实例,反过来运行为 hello.js
。
使用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 管理,让我们设置反向代理。
步骤 3 — 将 Nginx 设置为反向代理服务器
您的应用程序正在运行并听到本地主机
,但您需要为您的用户设置一种访问方式,我们将为此设置 Nginx 网页服务器作为反向代理。
在前提教程中,您将设置您的 Nginx 配置到 /etc/nginx/conf.d/your_domain.conf
文件中。
1sudo nano /etc/nginx/conf.d/your_domain.conf
在服务器
区块中,你应该有一个现有的位置/
区块,用以下配置来替换该区块的内容,如果你的应用程序设置为在不同的端口上收听,请将突出部分更新到正确的端口号:
1[label /etc/nginx/conf.d/your_domain.conf]
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/conf.d/your_domain.conf — 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 应用程序在 Rocky Linux 9 服务器上运行 Nginx 反向代理程序后面。
接下来,您可能想查看 如何使用 Docker 构建 Node.js 应用程序。