如何在Ubuntu 18.04上配置Node.js生产环境应用

介绍

Node.js是一个开源JavaScript运行环境,用于构建服务器端和网络应用程序。该平台可在Linux,macOS,FreeBSD和Windows上运行。虽然您可以在命令行运行Node.js应用程序,但本教程将重点介绍如何将它们应用于服务器中运行。这意味着它们将在重启故障时再次重新启动,并且可以安全地用于生产环境中。

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

准备

本教程需要您具有以下内容:

  • Ubuntu 18.04服务器设置。您应该拥有一个具有sudo权限和防火墙开着的非root用户。
  • 一个域名指向你服务器的公网IP。本教程将始终使用域名example.com
  • 安装了Nginx。
  • Nginx使用 Let's Encrypt 证书配置SSL。
  • 端口允许连接3000。您可以通过运行sudo ufw allow 3000启用此功能。

完成这些准备之后,您将有一台服务器在https://example.com上提供默认的Nginx占位符页面。

第一步,安装Node.js.

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

首先,安装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

注意:从NodeSource PPA安装时,会调用Node.js可执行文件nodejs,而不是node。

该nodejs软件包共包含了nodejs二进制文件以及npmNode模块的软件包管理器,因此您无需单独安装npm。

npm使用主目录中的配置文件来跟踪更新。它将在您第一次运行时创建npm。执行此命令以验证npm是否已安装并创建配置文件:

$ npm -v
5.6.0

为了使某些npm软件包能够工作(例如,需要从源代码编译代码),您还需要安装build-essential软件包:

$ sudo apt install build-essential

现在,您拥有工作必要的工具与从源代码编译npm软件包。安装Node.js运行后,我们继续编写Node.js应用程序。

第二步,创建Node.js应用程序

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

首先,让我们创建一个名为hello.js的示例应用程序:

$ cd ~
$ nano hello.js

将以下代码插入到文件中:

〜/ 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)和port(3000),并使用200HTTP代码成功返回“Hello World!”。由于我们正在侦听localhost,因此远程客户端将无法连接到我们的应用程序。

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

$ node hello.js

您将看到以下输出结果:

Server running at http://localhost:3000/

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

要测试应用程序,打开你的服务器上的另一个终端会话,并用curl连接到本地主机

$ curl http://localhost:3000

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

Hello World!

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

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

第三步,安装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

您现在已经创建了一个systemd 单元,在启动时为您的用户运行pm2。

反过来,这个pm2将实例地运行hello.js。 您可以使用systemctl检查systemd单元的状态:

$ systemctl status pm2-sammy

除了我们所介绍的内容之外,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运行和管理,让我们一起设置反向代理。

第四步,将Nginx设置为反向代理服务器

您的应用程序正在运行并正在侦听localhost,但您需要为用户设置一种访问它的方法。为此,我们将Nginx

Web服务器设置为反向代理。

在准备教程中,您可以在文件中设置Nginx配置。打开此文件进行编辑:/etc/nginx/sites-available/example.com

$ sudo nano /etc/nginx/sites-available/example.com

在server块中,您应该有一个现有的location/块。请使用以下运行命令替换该块的内容。如果您的应用程序设置为侦听其他端口,请将突出显示的部分更新为正确的端口号:

/etc/nginx/sites-available/example.com
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/会将请求发送到hello.js,在localhost上侦听端口3000。

您可以将一个其他location块添加到同一服务器块,以提供对同一服务器上其他应用程序的访问。

例如,如果您还在端口3001上运行另一个Node.js应用程序,则可以添加此位置块以允许通过http://example.com/app2访问它:

/etc/nginx/sites-available/example.com - Optional
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地址或域名)来尝试。

结论

现在,您的Node.js应用程序已成功在Ubuntu 18.04服务器上的Nginx反向代理运行。此反向代理设置足够灵活,可让您的用户访问您要共享的其他应用程序或静态Web内容。关于Nginx, 腾讯云开发者手册提供Nginx中文文档, 同时腾讯云实验室也提供了基于CentOS搭建Nodejs环境基于CentOS搭建Nginx静态网站.


参考文献:《How To Set Up a Node.js Application for Production on Ubuntu 18.04》

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏一枝花算不算浪漫

[常见问题]Project facet Java versin 1.8 is not support.

37370
来自专栏闵开慧

eclipse中执行程序显示找不到主类

eclipse中执行程序显示找不到主类 这种情况一般出现在工程中已编译有class文件的java文件,而后面新建的java则不会出现问题。这种情况说明工程bin...

36250
来自专栏技术专栏

Zookeeper 在linux&mac下 安装配置

详情参考 http://zookeeper.apache.org/doc/r3.4.5/zookeeperStarted.html

44120
来自专栏JavaEdge

Error running Tomcat8: Address localhost:1099 is already in use

这明显是1099端口已经被占用,解决办法如下: 第一步,命令提示符号,执行命令:

17310
来自专栏黑泽君的专栏

linux基本命令学习01

============================================================================= Un...

15210
来自专栏大大的微笑

Redis初步了解

①. 到这里下载自己需要的版本 ,http://download.redis.io/releases/,我的版本是2.8.7 ②. 解压下载的安装包到自己想要存...

26460
来自专栏前端小叙

内网映射到外网方法收集

一、nat123 二、ngrok 官网服务器被墙了 不能使用,显示reconnecting,可以使用自己搭建的服务器来试  三、花生壳 四、frp  htt...

484100
来自专栏云计算教程系列

如何在Debian 9上设置Node.js生产应用程序

Node.js是一个开源JavaScript运行时环境,用于构建服务器端和网络应用程序。该平台可在Linux,macOS,FreeBSD和Windows上运行。...

18540
来自专栏北京马哥教育

Linux中find命令用法全汇总,看完就没有不会用的!

Linux 查找命令是Linux系统中最重要和最常用的命令之一。查找用于根据与参数匹配的文件指定的条件来搜索和查找文件和目录列表的命令。查找可以在各种条件下使用...

28340
来自专栏xcywt

《Linux命令行与shell脚本编程大全》第十五章 呈现数据

15.1 理解输入和输出 现在知道两种显示脚本输出的方法 1)在显示器屏幕上显示 2)将输出文件重定向到文件中 15.1.1 标准文件描述符 Linux系统将每...

22860

扫码关注云+社区

领取腾讯云代金券