前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。
简介
Node.js 是一个用于构建服务器端和网络应用程序的开源 JavaScript 运行环境。该平台可在 Linux、macOS、FreeBSD 和 Windows 上运行。虽然你可以在命令行上运行 Node.js 应用程序,但本教程将专注于将它们作为服务运行。这意味着它们将在重新启动或失败时重新启动,并且可以安全地在生产环境中使用。
在本教程中,你将在单个 Ubuntu 18.04 服务器上设置一个适用于生产的 Node.js 环境。该服务器将运行由 PM2 管理的 Node.js 应用程序,并通过 Nginx 反向代理为用户提供安全访问该应用程序。Nginx 服务器将使用由 Let’s Encrypt 提供的免费证书提供 HTTPS。
先决条件
本指南假设你已经具备以下条件:
- 一个 Ubuntu 18.04 服务器设置,如《Ubuntu 18.04 服务器初始设置指南》中所述。你应该拥有一个具有 sudo 权限的非 root 用户和一个活跃的防火墙。
- 一个指向服务器公共 IP 的域名。本教程将始终使用域名 example.com。
- 已安装 Nginx,如《在 Ubuntu 18.04 上安装 Nginx》中所述。
- 已配置 Nginx 使用 Let’s Encrypt 证书进行 SSL。《在 Ubuntu 18.04 上使用 Let’s Encrypt 保护 Nginx》将指导你完成该过程。
完成先决条件后,你将拥有一个服务器,在 https://example.com/
上为你的域名提供默认占位页面。
步骤 1 — 安装 Node.js
让我们从安装最新的 LTS 版本的 Node.js 开始,使用 NodeSource 软件包存档。
首先,安装 NodeSource PPA 以获取其内容。确保你在你的主目录中,并使用 curl
检索 Node.js 8.x 存档的安装脚本:
cd ~
curl -sL https://deb.nodesource.com/setup_8.x -o nodesource_setup.sh
你可以使用 nano
或你喜欢的文本编辑器检查此脚本的内容:
nano nodesource_setup.sh
检查完脚本后,在 sudo
下运行它:
sudo bash nodesource_setup.sh
PPA 将被添加到你的配置中,并且你的本地软件包缓存将自动更新。在 Nodesource 运行设置脚本后,你可以安装 Node.js 软件包:
sudo apt install nodejs
要检查这些初始步骤后安装的 Node.js 版本,输入:
nodejs -v
v8.11.3
nodejs
软件包包含 nodejs
二进制文件以及 npm
,一个用于 Node 模块的包管理器,因此你无需单独安装 npm
。
npm
使用你的主目录中的配置文件来跟踪更新。第一次运行 npm
时将创建该文件。执行此命令以验证 npm
已安装并创建配置文件:
npm -v
5.6.0
为了使一些需要从源代码编译的 npm
包工作(例如那些需要编译代码的包),你需要安装 build-essential
软件包:
sudo apt install build-essential
现在,你已经具备了处理需要从源代码编译的 npm
包所需的工具。
安装了 Node.js 运行时环境后,让我们继续编写一个 Node.js 应用程序。
步骤 2 — 创建一个 Node.js 应用程序
让我们编写一个返回 “Hello World” 的 Hello World 应用程序,以响应任何 HTTP 请求。这个示例应用程序将帮助你设置 Node.js。你可以用自己的应用程序替换它,只需确保修改你的应用程序以侦听适当的 IP 地址和端口。
首先,让我们创建一个名为 hello.js
的示例应用程序:
cd ~
nano hello.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}/`);
});
保存文件并退出编辑器。
这个 Node.js 应用程序侦听指定的地址(localhost
)和端口(3000
),并以 200
HTTP 成功代码返回 “Hello World!”。由于我们在 localhost
上侦听,远程客户端将无法连接到我们的应用程序。
要测试你的应用程序,输入:
node hello.js
你将看到以下输出:
Server running at http://localhost:3000/
要测试应用程序,在服务器上的另一个终端会话中,使用 curl
连接到 localhost
:
[environment second]
curl http://localhost:3000
如果你看到以下输出,则表示应用程序正常工作并侦听在正确的地址和端口上:
[environment second]
Hello World!
如果你没有看到预期的输出,请确保你的 Node.js 应用程序正在运行并配置为侦听正确的地址和端口。
一旦确定它正常工作,通过按 CTRL+C
杀死应用程序(如果你还没有这样做)。
步骤 3 — 安装 PM2
接下来让我们安装 PM2,一个用于 Node.js 应用程序的进程管理器。PM2 可以将应用程序守护化,使其作为服务在后台运行。
使用 npm
在服务器上安装最新版本的 PM2:
sudo npm install pm2@latest -g
-g
选项告诉 npm
在全局范围内安装该模块,以便系统范围内可用。
首先使用 pm2 start
命令在后台运行你的应用程序 hello.js
:
pm2 start hello.js
这也会将你的应用程序添加到 PM2 的进程列表中,每次启动应用程序时都会输出该列表:
[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.
┌──────────┬────┬──────┬──────┬────────┬─────────┬────────┬─────┬───────────┬───────┬──────────┐
│ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ user │ watching │
├──────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────┼───────────┼───────┼──────────┤
│ hello │ 0 │ fork │ 1338 │ online │ 0 │ 0s │ 0% │ 23.0 MB │ sammy │ disabled │
└──────────┴────┴──────┴──────┴────────┴─────────┴────────┴─────┴───────────┴───────┴──────────┘
Use `pm2 show <id|name>` to get more details about an app
如你所见,PM2 自动分配了一个 App name
(基于文件名,不包括 .js
扩展名)和一个 PM2 id
。PM2 还维护其他信息,如进程的 PID
、当前状态和内存使用情况。
在 PM2 下运行的应用程序如果崩溃或被终止,将会自动重新启动,但我们可以采取额外的步骤,使用 startup
子命令使应用程序在系统启动时启动。该子命令生成并配置一个启动脚本,在服务器启动时启动 PM2 及其管理的进程:
pm2 startup systemd
结果输出的最后一行将包括一个需要以超级用户权限运行的命令,以设置 PM2 在启动时启动:
[PM2] Init System found: systemd
[PM2] To setup the Startup Script, copy/paste the following command:
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy
用输出中的命令运行,将你的用户名替换为 sammy
:
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy
作为额外步骤,我们可以保存 PM2 进程列表及其对应的环境:
pm2 save
现在你已经创建了一个在启动时为你的用户运行 pm2
的 systemd unit。这个 pm2
实例又运行着 hello.js
。
使用 systemctl
启动服务:
sudo systemctl start pm2-sammy
检查 systemd unit 的状态:
systemctl status pm2-sammy
有关 systemd 的详细概述,请参阅《Systemd Essentials: Working with Services, Units, and the Journal》。
除了我们已经介绍的内容,PM2 还提供许多子命令,允许你管理或查找关于你的应用程序的信息。
使用以下命令停止一个应用程序(指定 PM2 的 App name
或 id
):
pm2 stop app_name_or_id
重新启动一个应用程序:
pm2 restart app_name_or_id
列出当前由 PM2 管理的应用程序:
pm2 list
使用应用程序的 App name
获取有关特定应用程序的信息:
pm2 info app_name
使用 monit
子命令可以查看 PM2 进程监视器。这会显示应用程序的状态、CPU 和内存使用情况:
pm2 monit
请注意,运行 pm2
而不带任何参数也会显示一个带有示例用法的帮助页面。
现在你的 Node.js 应用程序正在运行并由 PM2 管理,让我们设置反向代理。
步骤 4 —— 设置 Nginx 作为反向代理服务器
您的应用程序正在运行并在 localhost
上监听,但您需要设置一种方式让用户访问它。我们将设置 Nginx web 服务器作为反向代理来实现这一目的。
在先决条件教程中,您在 /etc/nginx/sites-available/example.com
文件中设置了您的 Nginx 配置。打开此文件进行编辑:
sudo nano /etc/nginx/sites-available/example.com
在 server
块内,您应该有一个现有的 location /
块。用以下配置替换该块的内容。如果您的应用程序设置为监听不同的端口,请将突出显示的部分更新为正确的端口号:
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;
}
...
}
这将配置服务器以响应其根目录的请求。假设我们的服务器可在 example.com
上访问,通过 web 浏览器访问 https://example.com/
将会将请求发送到在 localhost
上监听端口 3000
的 hello.js
。
您可以向同一服务器块添加额外的 location
块,以提供对同一服务器上其他应用程序的访问。例如,如果您还在端口 3001
上运行另一个 Node.js 应用程序,您可以添加此位置块,以允许通过 https://example.com/app2
访问它:
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;
}
...
}
添加完应用程序的位置块后,保存文件并退出编辑器。
通过输入以下命令,确保您没有引入任何语法错误:
sudo nginx -t
重新启动 Nginx:
sudo systemctl restart nginx
假设您的 Node.js 应用程序正在运行,并且您的应用程序和 Nginx 配置是正确的,现在您应该能够通过 Nginx 反向代理访问您的应用程序。尝试通过访问服务器的 URL(其公共 IP 地址或域名)来测试。
结论
恭喜!您现在已经在 Ubuntu 18.04 服务器上将您的 Node.js 应用程序运行在 Nginx 反向代理后面。这种反向代理设置足够灵活,可以让您的用户访问其他应用程序或您想要共享的静态 web 内容。
标签:Node,http,PM2,pm2,应用程序,js,18.04 From: https://blog.csdn.net/rubys007/article/details/143496490