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

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

介绍

Node.js 是一个开源的 Javascript 运行时环境,用于轻松构建服务器端和网络应用程序。 该平台在 Linux、OS X、FreeBSD 和 Windows 上运行,其应用程序是用 JavaScript 编写的。 Node.js 应用程序可以在命令行运行,但我们将教你如何将它们作为服务运行,因此它们会在重启或失败时自动重启,因此你可以在生产环境中使用它们。

在本教程中,我们将介绍如何设置由两台 Ubuntu 14.04 服务器组成的生产就绪 Node.js 环境; 一台服务器将运行由 PM2 管理的 Node.js 应用程序,而另一台服务器将通过 Nginx 反向代理向应用程序服务器提供用户对应用程序的访问。

本教程的 CentOS 版本可以在 这里 找到。

先决条件

本指南使用两台 Ubuntu 14.04 服务器 和私有网络 (在同一个数据中心)。 我们将使用以下名称来称呼它们:

  • app:我们将安装 Node.js 运行时、您的 Node.js 应用程序和 PM2 的服务器
  • web:我们将安装 Nginx Web 服务器的服务器,它将充当您应用程序的反向代理。 用户将访问此服务器的公共 IP 地址以访问您的 Node.js 应用程序。

本教程可以使用单个服务器,但您必须在此过程中进行一些更改。 只需使用 localhost IP 地址,即 127.0.0.1,只要使用 app 服务器的私有 IP 地址。

这是遵循本教程后您的设置的图表:

在开始本指南之前,您应该在两台服务器上配置具有 sudo 权限的常规非 root 用户——这是您应该登录到服务器的用户。 您可以按照我们的 Ubuntu 14.04 初始服务器设置指南中的步骤 1-4 来了解如何配置普通用户帐户。

如果您希望能够通过域名而不是其公共 IP 地址访问您的 web 服务器,请购买域名,然后按照以下教程操作:

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

安装 Node.js

我们将在 app 服务器上安装最新的 LTS 版本的 Node.js。

app 服务器上,让我们使用以下命令更新 apt-get 软件包列表:

sudo apt-get update

然后使用apt-get安装git包,npm依赖:

sudo apt-get install git

转到 Node.js 下载页面 并找到 Linux 二进制文件 (.tar.xz) 下载链接。 右键单击它,然后将其链接地址复制到剪贴板。 在撰写本文时,最新的 LTS 版本是 4.2.3。 如果您喜欢安装最新的稳定版 Node.js,请转到 相应页面 并复制该链接。

切换到您的主目录并使用 wget 下载 Node.js 源代码。 将下载链接粘贴到突出显示的部分:

cd ~
wget https://nodejs.org/dist/v4.2.3/node-v4.2.3-linux-x64.tar.gz

现在使用以下命令将您刚刚下载的 tar 存档解压缩到 node 目录中:

mkdir node
tar xvf node-v*.tar.?z --strip-components=1 -C ./node

如果您想删除下载的 Node.js 存档,因为我们不再需要它,请切换到您的主目录并使用以下 rm 命令:

cd ~
rm -rf node-v*

接下来,我们将配置 npm 的全局 prefix,其中 npm 将创建指向已安装 Node 包的符号链接,指向默认路径中的某个位置。 我们将使用以下命令将其设置为 /usr/local

mkdir node/etc
echo 'prefix=/usr/local' > node/etc/npmrc

现在我们准备将 nodenpm 二进制文件移动到我们的安装位置。 我们将使用以下命令将其移动到 /opt/node 中:

sudo mv node /opt/

此时,您可能希望使 root 成为文件的所有者:

sudo chown -R root: /opt/node

最后,让我们在默认路径中创建 nodenpm 二进制文件的符号链接。 我们将使用以下命令将链接放在 /usr/local/bin 中:

sudo ln -s /opt/node/bin/node /usr/local/bin/node
sudo ln -s /opt/node/bin/npm /usr/local/bin/npm

通过使用以下命令检查其版本来验证是否已安装 Node:

node -v

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

创建 Node.js 应用程序

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

因为我们希望我们的 Node.js 应用程序服务来自我们的反向代理服务器 web 的请求,我们将利用我们的 app 服务器的专用网络接口进行服务器间通信。 查找您的 app 服务器的私有网络地址。

如果您使用 DigitalOcean droplet 作为服务器,您可以通过 Metadata 服务查找服务器的私有 IP 地址。 在 app 服务器上,现在使用 curl 命令检索 IP 地址:

curl -w "\n" http://169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address 

您需要复制输出(私有 IP 地址),因为它将用于配置我们的 Node.js 应用程序。

你好世界代码

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

cd ~
vi hello.js

将以下代码插入文件中,并确保将 app 服务器的私有 IP 地址替换为突出显示的 APP_PRIVATE_IP_ADDRESS 项。 如果您愿意,您也可以在两个位置替换突出显示的端口 8080(请务必使用非管理员端口,即 1024 或更高):

你好.js

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

现在保存并退出。

这个 Node.js 应用程序只监听指定的 IP 地址和端口,并返回带有 200 HTTP 成功代码的“Hello World”。 这意味着应用程序只能从同一专用网络上的服务器访问,例如我们的 web 服务器。

测试应用程序(可选)

如果您想测试您的应用程序是否工作,请在 app 服务器上运行此 node 命令:

node hello.js

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

为了测试应用程序,打开另一个终端会话并连接到您的 web 服务器。 因为web服务器在同一个私网,所以应该可以使用curl访问app服务器的私网IP地址。 请务必在 app 服务器的私有 IP 地址中替换 APP_PRIVATE_IP_ADDRESS,如果您更改了端口,请务必替换:

curl http://APP_PRIVATE_IP_ADDRESS:8080

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

Output:Hello World

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

app 服务器上,请务必通过按 CTRL+C 来终止应用程序(如果您还没有)。

安装 PM2

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

我们将使用 Node Packaged Modules (NPM),它基本上是与 Node.js 一起安装的 Node 模块的包管理器,在我们的 app 服务器上安装 PM2。 使用此命令安装 PM2:

sudo npm install pm2 -g

使用 PM2 管理应用程序

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

开始申请

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

pm2 start hello.js

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

Output:┌──────────┬────┬──────┬──────┬────────┬───────────┬────────┬────────────┬──────────┐
│ App name │ id │ mode │ PID  │ status │ restarted │ uptime │     memory │ watching │
├──────────┼────┼──────┼──────┼────────┼───────────┼────────┼────────────┼──────────┤
│ hello    │ 0  │ fork │ 5871 │ online │         0 │ 0s     │ 9.012 MB   │ disabled │
└──────────┴────┴──────┴──────┴────────┴───────────┴────────┴────────────┴──────────┘

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

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

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

pm2 startup ubuntu

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

Output:[PM2] You have to run this command as root
[PM2] Execute the following command :
[PM2] sudo su -c "env PATH=$PATH:/opt/node/bin pm2 startup ubuntu -u sammy --hp /home/sammy"

运行生成的命令(类似于上面突出显示的输出)以将 PM2 设置为在启动时启动(使用您自己输出中的命令):

 sudo su -c "env PATH=$PATH:/opt/node/bin pm2 startup ubuntu -u sammy --hp /home/sammy"

其他 PM2 用途(可选)

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

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

pm2 stop example

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

pm2 restart example

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

pm2 list

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

pm2 info example

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

pm2 monit

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

设置反向代理服务器

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

web 服务器上,让我们使用以下命令更新 apt-get 软件包列表:

sudo apt-get update

然后使用 apt-get 安装 Nginx:

sudo apt-get install nginx

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

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

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

/etc/nginx/sites-available/default

server {
    listen 80;

    server_name example.com;

    location / {
        proxy_pass http://APP_PRIVATE_IP_ADDRESS: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;
    }
}

这将 web 服务器配置为响应其根的请求。 假设我们的服务器在 example.com 可用,通过 Web 浏览器访问 http://example.com/ 会将请求发送到端口 8080 上的应用程序服务器的私有 IP 地址,该地址将被接收并回复通过 Node.js 应用程序。

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

Nginx 配置 - 其他位置

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

为应用程序添加完位置块后,保存并退出。

web 服务器上,重启 Nginx:

sudo service nginx restart

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

结论

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

此外,如果您希望对 Web 服务器和用户之间的传输进行加密,这里有一个教程可以帮助您设置 HTTPS (TLS/SSL) 支持