如何在 Ubuntu 14.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 网络服务器的服务器,它将充当您的应用程序的反向代理。用户将访问此服务器的公共 IP 地址以访问您的 Node.js 应用程序。
本教程可以使用单个服务器,但您必须在此过程中进行一些更改。只要使用本地主机 IP 地址,即 127.0.0.1
,只要使用应用服务器的私有 IP 地址即可。
以下是按照本教程进行设置后的示意图:

在你开始本指南之前,你应该有一个普通的非根用户,在你的两台服务器上都配置了 sudo
权限——这是你应该登录到你的服务器的用户。您可以按照我们的 Ubuntu 14.04 初始服务器设置指南中的步骤 1-4 了解如何配置普通用户帐户。
如果您希望能够通过域名而不是其公共 IP 地址访问您的 Web 服务器,请购买域名,然后按照以下教程操作:
- 如何使用 DigitalOcean 设置主机名
- 如何从通用域注册商指向 DigitalOcean 名称服务器
让我们开始在应用服务器上安装 Node.js 运行时。
安装 Node.js
我们将在应用服务器上安装最新的 Node.js LTS 版本。
在应用服务器上,让我们使用以下命令更新 apt-get 包列表:
- sudo apt-get update
然后使用apt-get
安装git
包,npm
依赖:
- sudo apt-get install git
转到相应的页面并复制该链接。
切换到您的主目录并使用 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
现在我们准备好将 node
和 npm
二进制文件移动到我们的安装位置。我们将使用以下命令将其移动到 /opt/node
中:
- sudo mv node /opt/
此时,您可能想让 root
成为文件的所有者:
- sudo chown -R root: /opt/node
最后,让我们在默认路径中创建 node
和 npm
二进制文件的符号链接。我们将使用这些命令将链接放在 /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 的请求提供服务,所以我们将利用我们的应用程序服务器的专用网络接口进行服务器间通信。查找您的应用服务器的私有网络地址。
如果您使用 DigitalOcean Droplet 作为您的服务器,您可以通过 Metadata 服务查找服务器的私有 IP 地址。在应用服务器上,现在使用 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
将以下代码插入文件中,并确保用应用服务器的私有 IP 地址替换两个突出显示的 APP_PRIVATE_IP_ADDRESS
项。如果需要,您还可以在两个位置替换突出显示的端口 8080
(请务必使用非管理端口,即 1024 或更高):
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”。这意味着该应用程序只能从同一私有服务器上的服务器访问网络,例如我们的网络服务器。
测试应用程序(可选)
如果您想测试您的应用程序是否正常工作,请在应用程序服务器上运行此 node
命令:
- node hello.js
注意:以这种方式运行 Node.js 应用程序将阻止其他命令,直到通过按 CTRL+C
终止应用程序。
为了测试应用程序,打开另一个终端会话并连接到您的 Web 服务器。因为 Web 服务器位于同一专用网络上,所以它应该能够使用 curl
访问应用服务器的专用 IP 地址。请务必将 APP_PRIVATE_IP_ADDRESS
替换为应用服务器的私有 IP 地址,如果您更改了端口,请替换为:
- curl http://APP_PRIVATE_IP_ADDRESS:8080
如果您看到以下输出,则应用程序正常运行并侦听正确的 IP 地址和端口:
Output:Hello World
如果您没有看到正确的输出,请确保您的 Node.js 应用程序正在运行,并且配置为侦听正确的 IP 地址和端口。
在应用程序服务器上,确保通过按 CTRL+C
终止应用程序(如果您尚未终止)。
安装 PM2
现在我们将安装 PM2,它是 Node.js 应用程序的进程管理器。 PM2 提供了一种简单的方法来管理和守护应用程序(将它们作为服务运行)。
我们将使用 Node Packaged Modules (NPM),它基本上是与 Node.js 一起安装的 Node 模块的包管理器,用于在我们的应用程序服务器上安装 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 name
或 id
):
- pm2 stop example
使用此命令重新启动应用程序(指定 PM2 App name
或 id
):
- pm2 restart example
当前由 PM2 管理的应用程序列表也可以使用 list
子命令查找:
- pm2 list
可以使用 info
子命令(指定 PM2 App name 或 id)找到有关特定应用程序的更多信息:
- pm2 info example
可以使用 monit
子命令启动 PM2 进程监视器。这会显示应用程序状态、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_PRIVATE_IP_ADDRESS的应用服务器私有 IP 地址替换为您自己的域名代码>。此外,如果您的应用程序设置为侦听不同的端口,请更改端口 (8080
):
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
可用,通过网络浏览器访问 http://example.com/
会将请求发送到端口上应用程序服务器的私有 IP 地址8080
,将由 Node.js 应用程序接收和回复。
您可以将其他 location
块添加到同一服务器块,以提供对同一 Web 服务器上其他应用程序的访问。例如,如果您还在端口 8081
上的应用服务器上运行另一个 Node.js 应用程序,您可以添加此位置块以允许通过 http://example.com 访问它/app2
:
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) 支持。