如何在Rocky Linux 9上为生产环境设置Node.js应用程序

介绍

Node.js是一个用于构建服务器端和网络应用程序的开源JavaScript运行环境。该平台可在Linux、macOS、FreeBSD和Windows上运行。尽管您可以在命令行上运行Node.js应用程序,但本教程将专注于将它们作为服务运行。这意味着它们将在重启或失败时重新启动,并且在生产环境中使用是安全的。

在本教程中,您将在一台Rocky Linux 9服务器上设置一个可投入生产的Node.js环境。该服务器将运行由PM2管理的Node.js应用程序,并通过Nginx反向代理为用户提供安全访问应用程序的方式。Nginx服务器将使用由Let’s Encrypt提供的免费证书提供HTTPS服务。

先决条件 jué

在进行本指南之前,假设您具备以下条件:

  • A Rocky Linux 9 server setup, as described in the initial server setup guide for Rocky Linux 9. You should have a non-root user with sudo privileges and an active firewall.
  • A domain name pointed at your server’s public IP. This tutorial will use the domain name example.com throughout.
  • Nginx installed, as covered in How To Install Nginx on Rocky Linux 9.
  • Nginx configured with SSL using Let’s Encrypt certificates. How To Secure Nginx with Let’s Encrypt on Rocky Linux 9 will walk you through the process.
  • Node.js installed on your server. How To Install Node.js on Rocky Linux 9

当您完成先决条件后,您将在https://example.com/上拥有一个为您的域名提供默认占位页面的服务器。

第一步 — 创建一个 Node.js 应用程序

让我们编写一个Hello World的应用程序,它会对任何HTTP请求返回“Hello World”。这个示例应用程序将帮助您开始使用Node.js。您可以将其替换为自己的应用程序,只需确保修改应用程序以侦听适当的IP地址和端口。

Rocky Linux 9自带的默认文本编辑器是vi。vi是一个非常强大的文本编辑器,但对于没有经验的用户来说,可能会有些复杂。您可能希望安装一个更用户友好的编辑器,比如nano,以便在您的Rocky Linux 9服务器上编辑配置文件。

  1. sudo dnf install nano

 

现在,使用nano或您最喜欢的文本编辑器,创建一个名为hello.js的示例应用程序。

  1. nano hello.js

 

将以下代码插入文件中:

你好.js
const http = require('http');

const hostname = 'localhost';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World!\n');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

保存文件并退出编辑器。如果使用的是nano,按下Ctrl+X,然后在提示时按下Y,最后按下Enter键。

这个Node.js应用程序监听指定的地址(本地主机)和端口(3000),并以200 HTTP成功代码返回“Hello World!”。由于我们在本地主机上监听,远程客户端无法连接到我们的应用程序。

要测试您的应用程序,请输入:

  1. node hello.js

 

你将会收到以下的输出结果。

Output

Server running at http://localhost:3000/

Note

注意:以这种方式运行Node.js应用程序将阻塞其他命令,直到通过按下CTRL+C来终止应用程序。

为了测试应用程序,在您的服务器上打开另一个终端会话,并通过curl连接到本地主机。

  1. curl http://localhost:3000

 

如果您得到以下输出,则表示应用程序正常工作并正在正确的地址和端口上进行监听:

Output

Hello World!

如果您没有得到预期的输出,请确保您的Node.js应用程序正在运行并配置为在正确的地址和端口上侦听。

确认应用程序正常运行后,按下CTRL+C键关闭应用程序(如果你还没有关闭的话)。

第二步-安装PM2

接下来,让我们安装PM2,这是一个用于Node.js应用程序的进程管理器。PM2可以将应用程序设为守护进程,使其作为后台服务一直运行。

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

  1. sudo npm install pm2@latest -g

 

-g选项告诉npm在全局安装该模块,使其在整个系统范围内可用。

让我们首先使用pm2 start命令在后台运行你的应用程序hello.js。

  1. pm2 start hello.js

 

这也会将您的应用程序添加到PM2的进程列表中,每次启动应用程序时会输出该列表。

Output

… [PM2] Spawning PM2 daemon with pm2_home=/home/sammy/.pm2 [PM2] PM2 Successfully daemonized [PM2] Starting /home/sammy/hello.js in fork_mode (1 instance) [PM2] Done. ┌────┬────────────────────┬──────────┬──────┬───────────┬──────────┬──────────┐ │ id │ name │ mode │ ↺ │ status │ cpu │ memory │ ├────┼────────────────────┼──────────┼──────┼───────────┼──────────┼──────────┤ │ 0 │ hello │ fork │ 0 │ online │ 0% │ 25.2mb │ └────┴────────────────────┴──────────┴──────┴───────────┴──────────┴──────────┘

如上所述,PM2会自动分配一个应用名称(基于文件名,不包括.js扩展名)和一个PM2 id。 PM2还会维护其他信息,例如进程的PID,当前状态以及内存使用情况。

如果应用程序在PM2下运行,如果应用程序崩溃或被杀死,它将自动重新启动。但是,我们可以采取额外的步骤,使用启动子命令来在系统启动时启动应用程序。这个命令会生成并配置一个启动脚本,以在服务器启动时启动PM2及其管理的进程。

  1. pm2 startup systemd

 

Output

… [PM2] To setup the Startup Script, copy/paste the following command: sudo env PATH=$PATH:/usr/bin /usr/local/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy –hp /home/sammy

复制并运行提供的命令(这样可以避免以sudo方式运行Node.js工具时出现权限问题)。

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

 

Output

… [ ‘systemctl enable pm2-sammy‘ ] [PM2] Writing init configuration in /etc/systemd/system/pm2-sammy.service [PM2] Making script booting at startup… [PM2] [-] Executing: systemctl enable pm2-sammy… Created symlink /etc/systemd/system/multi-user.target.wants/pm2-sammy.service → /etc/systemd/system/pm2-sammy.service. [PM2] [v] Command successfully executed. +—————————————+ [PM2] Freeze a process list on reboot via: $ pm2 save [PM2] Remove init script via: $ pm2 unstartup systemd

现在,您需要对刚刚生成的系统服务进行编辑,以使其与Rocky Linux的SELinux安全系统兼容。使用nano或您喜欢的文本编辑器打开/etc/systemd/system/pm2-sammy.service文件。

  1. sudo nano /etc/systemd/system/pm2-sammy.service

 

在配置文件的[Service]块中,将PIDFile设置的内容替换为/run/pm2.pid,并添加另一个高亮显示的Environment行。

/etc/systemd/system/pm2-sammy.service 可以被改写为:
[Unit]
Description=PM2 process manager
Documentation=https://pm2.keymetrics.io/
After=network.target

[Service]
Type=forking
User=sammy
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
Environment=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
Environment=PM2_HOME=/home/sammy/.pm2
PIDFile=/run/pm2.pid
Restart=on-failure
Environment=PM2_PID_FILE_PATH=/run/pm2.pid

ExecStart=/usr/local/lib/node_modules/pm2/bin/pm2 resurrect
ExecReload=/usr/local/lib/node_modules/pm2/bin/pm2 reload all
ExecStop=/usr/local/lib/node_modules/pm2/bin/pm2 kill

[Install]

保存并关闭文件。您现在已经创建了一个在启动时为您的用户运行pm2的systemd单元。而这个pm2实例会运行hello.js。

使用systemctl启动服务。

  1. sudo systemctl start pm2-sammy

 

查看systemd单元的状态

  1. systemctl status pm2-sammy

 

要详细了解systemd,请查阅《Systemd Essentials: Working with Services, Units, and the Journal》。

除了我们已经涵盖的内容之外,PM2还提供了许多子命令,可以让您管理或查询有关您的应用程序的信息。

使用该命令停止一个应用程序(请指定PM2应用的名称或ID)

  1. pm2 stop app_name_or_id

 

重启一个应用程序:

  1. pm2 restart app_name_or_id

 

列出当前由PM2管理的应用程序。

  1. pm2 list

 

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

  1. pm2 info app_name

 

可以使用monit子命令调出PM2进程监视器。这将显示应用程序的状态、CPU和内存使用情况。

  1. pm2 monit

 

请注意,运行pm2时不带任何参数也会显示帮助页面及示例用法。

既然你的Node.js应用程序正在运行并由PM2管理,那么让我们设置反向代理。

第三步-将Nginx设置为反向代理服务器

你的应用正在本地运行和监听,但是你需要设置一个方式让用户访问它。我们将设置Nginx作为反向代理服务器来实现这个目的。

在先决教程中,你需要在 /etc/nginx/conf.d/your_domain.conf 文件中设置你的 Nginx 配置。打开这个文件进行编辑。

  1. sudo nano /etc/nginx/conf.d/your_domain.conf

 

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

你的域名配置文件位于/etc/nginx/conf.d/your_domain.conf。
server {
...
    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
...
}

这个配置使服务器能够在根目录下回应请求。假设我们的服务器在your_domain上可用,通过 web 浏览器访问 https://your_domain/ 会将请求发送到位于本地主机的监听端口 3000 的 hello.js。

你可以在同一个服务器块中添加额外的位置块,以便让其他应用程序在同一服务器上获得访问权限。例如,如果你还在3001端口上运行另一个Node.js应用程序,你可以添加这个位置块来通过https://你的域名/app2访问它。

/etc/nginx/conf.d/your_domain.conf — 可选项
server {
...
    location /app2 {
        proxy_pass http://localhost:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
...
}

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

请确保您在打字时没有引入任何语法错误。

  1. sudo nginx -t

 

重启Nginx:

  1. sudo systemctl restart nginx

 

假设您的Node.js应用程序正在运行,且应用程序和Nginx的配置正确,您现在应该能够通过Nginx反向代理访问您的应用程序。尝试通过访问服务器的URL(公共IP地址或域名)来验证。

结论

恭喜!您现在已经在一个Rocky Linux 9服务器上使用Nginx反向代理运行您的Node.js应用程序。这个反向代理设置足够灵活,可以让您的用户访问您想分享的其他应用程序或静态网络内容。

接下来,您可能想了解如何使用Docker构建Node.js应用程序。

广告
将在 10 秒后关闭
bannerAds