如何在Debian8上设置用于生产的Node.js应用程序

来自菜鸟教程
跳转至:导航、​搜索

介绍

Node.js 是一个开源 JavaScript 运行时环境,用于轻松构建服务器端和网络应用程序。 该平台在 Linux、OS X、FreeBSD 和 Windows 上运行。 Node.js 应用程序可以在命令行中运行,但我们将专注于将它们作为服务运行,以便它们在重启或故障时自动重启,并且可以安全地用于生产环境。

在本教程中,我们将介绍在单个 Debian 8 服务器上设置生产就绪的 Node.js 环境。 该服务器将运行由 PM2 管理的 Node.js 应用程序,并通过 Nginx 反向代理为用户提供对应用程序的安全访问。

先决条件

本指南假定您有一个 Debian 8 服务器,配置有具有 sudo 权限的非 root 用户,如 Debian 8 初始服务器设置指南中所述。

它还假设您有一个域名,指向服务器的公共 IP 地址。

让我们开始在您的服务器上安装 Node.js 运行时。

安装 Node.js

我们将使用 NodeSource 包档案安装最新的 LTS 版本的 Node.js。

首先,您需要安装 NodeSource PPA 才能访问其内容。 确保您位于主目录中,并使用 curl 检索 Node.js 6.x 档案的安装脚本:

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

您可以使用 nano(或您喜欢的文本编辑器)检查此脚本的内容:

nano nodesource_setup.sh

并在 sudo 下运行脚本:

sudo bash nodesource_setup.sh

PPA 将添加到您的配置中,并且您的本地包缓存将自动更新。 从 nodesource 运行安装脚本后,您可以按照与上面相同的方式安装 Node.js 包:

sudo apt-get install nodejs

nodejs 软件包包含 nodejs 二进制文件以及 npm,因此您无需单独安装 npm。 但是,为了使某些 npm 包能够工作(例如那些需要从源代码编译代码的包),您需要安装 build-essential 包:

sudo apt-get install build-essential

Node.js 运行时现已安装,并准备好运行应用程序! 让我们编写一个 Node.js 应用程序。

创建 Node.js 应用程序

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

你好世界代码

首先,创建并打开您的 Node.js 应用程序进行编辑。 在本教程中,我们将使用 nano 编辑一个名为 hello.js 的示例应用程序:

cd ~
nano hello.js

将以下代码插入文件中。 如果您愿意,您可以在两个位置替换突出显示的端口 8080(请务必使用非管理员端口,即 1024 或更高):

你好.js

#!/usr/bin/env nodejs
var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(8080, 'localhost');
console.log('Server running at http://localhost:8080/');

现在保存并退出。

此 Node.js 应用程序仅侦听指定的地址 (localhost) 和端口 (8080),并返回带有 200 HTTP 成功代码的“Hello World”。 由于我们正在侦听 localhost,远程客户端将无法连接到我们的应用程序。

测试申请

要使我们能够测试应用程序,请将 hello.js 标记为可执行文件:

chmod +x ./hello.js

并像这样运行它:

./hello.js
OutputServer running at http://localhost:8080/

注意: 以这种方式运行 Node.js 应用程序将阻止其他命令,直到应用程序被按 Ctrl-C 杀死。


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

curl http://localhost:8080

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

OutputHello World

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

一旦你确定它工作正常,按下 Ctrl+C 来终止应用程序(如果你还没有)。

安装 PM2

现在我们将安装 PM2,它是 Node.js 应用程序的进程管理器。 PM2 提供了一种简单的方法来管理和守护应用程序(将它们作为服务在后台运行)。

我们将使用 npm,一个用于安装 Node.js 的 Node 模块的包管理器,在我们的服务器上安装 PM2。 使用此命令安装 PM2:

sudo npm install -g pm2

-g 选项告诉 npm 安装模块 globally,以便它在系统范围内可用。

使用 PM2 管理应用程序

PM2 简单易用。 我们将介绍 PM2 的一些基本用途。

开始申请

您要做的第一件事是使用 pm2 start 命令在后台运行您的应用程序 hello.js

pm2 start hello.js

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

Output[PM2] Spawning PM2 daemon
[PM2] PM2 Successfully daemonized
[PM2] Starting hello.js in fork_mode (1 instance)
[PM2] Done.
┌──────────┬────┬──────┬──────┬────────┬─────────┬────────┬─────────────┬──────────┐
│ App name │ id │ mode │ pid  │ status │ restart │ uptime │ memory      │ watching │
├──────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────────────┼──────────┤
│ hello    │ 0  │ fork │ 3524 │ online │ 0       │ 0s     │ 21.566 MB   │ disabled │
└──────────┴────┴──────┴──────┴────────┴─────────┴────────┴─────────────┴──────────┘
 Use `pm2 show <id|name>` to get more details about an app

如您所见,PM2 自动分配了一个 App 名称(基于文件名,没有 .js 扩展名)和一个 PM2 id。 PM2 还维护其他信息,例如进程的PID、当前状态和内存使用情况。

如果应用程序崩溃或被杀死,在 PM2 下运行的应用程序将自动重新启动,但需要采取额外的步骤来使应用程序在系统启动(启动或重新启动)时启动。 幸运的是,PM2 提供了一种简单的方法来执行此操作,即 startup 子命令。

startup 子命令生成并配置启动脚本以在服务器启动时启动 PM2 及其托管进程。 您还必须指定您正在运行的平台,即 ubuntu,在我们的例子中:

pm2 startup systemd

结果输出的最后一行将包含一个您必须以超级用户权限运行的命令:

Output[PM2] You have to run this command as root. Execute the following command:
sudo env PATH=$PATH:/usr/bin /usr/local/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy

运行生成的命令(类似于上面突出显示的输出,但使用您的用户名而不是 sammy)将 PM2 设置为在启动时启动(使用您自己输出中的命令):

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

这将创建一个 systemd unit,它会在启动时为您的用户运行 pm2。 这个 pm2 实例依次运行 hello.js。 您可以使用 systemctl 检查 systemd 单元的状态:

systemctl status pm2

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

其他 PM2 用途(可选)

PM2 提供了许多子命令,允许您管理或查找有关应用程序的信息。 请注意,不带任何参数运行 pm2 将显示一个帮助页面,包括示例用法,它比本教程的这一部分更详细地介绍了 PM2 的用法。

使用此命令停止应用程序(指定 PM2 App nameid):

pm2 stop app_name_or_id

使用此命令重新启动应用程序(指定 PM2 App nameid):

pm2 restart app_name_or_id

当前由 PM2 管理的应用程序列表也可以使用 list 子命令查找:

pm2 list

可以使用 info 子命令找到有关特定应用程序的更多信息(指定 PM2 App nameid):

pm2 info example

PM2 过程监视器可以使用 monit 子命令启动。 这将显示应用程序状态、CPU 和内存使用情况:

pm2 monit

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

将 Nginx 设置为反向代理服务器

现在您的应用程序正在运行,并且正在侦听 localhost,您需要为您的用户设置一种访问它的方式。 为此,我们将设置一个 Nginx Web 服务器作为反向代理。 本教程将从头开始设置 Nginx 服务器。 如果您已经有 Nginx 服务器设置,您只需将 location 块复制到您选择的服务器块中(确保该位置不与您的任何 Web 服务器的现有内容冲突)。

首先,使用 apt-get 安装 Nginx:

sudo apt-get install nginx

现在打开默认服务器块配置文件进行编辑:

sudo nano /etc/nginx/sites-available/default

删除文件中的所有内容并插入以下配置。 请务必将您自己的域名替换为 server_name 指令。 此外,如果您的应用程序设置为侦听不同的端口,请更改端口 (8080):

/etc/nginx/sites-available/default

server {
    listen 80;

    server_name example.com;

    location / {
        proxy_pass http://localhost:8080;
        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 浏览器访问 http://example.com/ 会将请求发送到 hello.js,监听 localhost 的端口 8080

您可以将额外的 location 块添加到同一服务器块,以提供对同一服务器上其他应用程序的访问。 例如,如果您还在端口 8081 上运行另一个 Node.js 应用程序,则可以添加此位置块以允许通过 http://example.com/app2 访问它:

Nginx 配置 - 其他位置

    location /app2 {
        proxy_pass http://localhost:8081;
        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

接下来,如果您启用了防火墙,则允许通过防火墙访问 Nginx。

如果您使用的是 ufw,则可以使用以下命令:

sudo ufw allow 'Nginx Full'

使用 ufw,您可以随时使用以下命令检查状态:

sudo ufw status

如果您使用 IPTables 代替,您可以使用以下命令允许到 Nginx 的流量:

sudo iptables -I INPUT -p tcp -m tcp --dport 80 -j ACCEPT

您始终可以通过运行以下命令来检查 IPTables 的状态:

sudo iptables -S

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

从这里开始,您应该继续阅读 如何在 Debian 8 上使用 Let's Encrypt 保护 Nginx 来保护您的设置。

结论

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