在软件开发的生命周期中,生产部署是一个至关重要的阶段。尽管开发阶段可能需要花费数天甚至数周的时间,但人们往往期望生产部署能够像执行几个命令那样简单。然而,实际情况远比这复杂。本教程将涵盖在Ubuntu上设置Node.js和 MongoDB 所需的一切知识,并在过程中讨论一些最佳实践。
多年来,JavaScript 已经从仅在浏览器上运行的语言发展成为一个多用途的工具。现在,它被积极用于运行服务器、渲染服务器端代码、驱动数据库等。使用Node.js和 Express 构建的 JavaScript 服务器非常受欢迎,是开始全栈 JavaScript 解决方案的流行选择。流行的 JavaScript 技术栈包括 MEAN(MongoDB, Express.js, Angular, Node.js)和 MERN(将 Angular 替换为 React 的 MEAN 技术栈)。
无论选择哪种技术栈,最初在类似生产的环境中设置 Node.js/Express 和 MongoDB 可能会遇到挑战。因此,将尝试在 Ubuntu 16.04 LTS 上配置 Node.js 和 MongoDB,以便可以在运行于 AWS 或 DigitalOcean 的服务器上复制这些步骤。但在开始之前,请确保已经安装了 Ubuntu 16.04,并且已经更新、配置了一个非 root 用户。
应该安装Node.js的长期支持版本,截至本教程撰写时,这是 v8.x.x 版本。将从 NodeSource 下载 Node.js 包存档和设置脚本。请确保位于主目录,然后按照以下步骤下载脚本:
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
PPA 将更新为 nodejs 仓库。现在可以通过运行以下命令来安装 nodejs:
sudo apt-get install -y nodejs
nodejs 包包括了 node.js 和 npm。然而,可能需要安装额外的开发工具,以使某些 npm 包能够工作。
sudo apt-get install build-essential
尽管可以直接从Ubuntu仓库安装 MongoDB,但那里提供的 mongodb 包并不是由 MongoDB 团队官方维护的。相反,应该按照以下步骤安装 MongoDB 社区版:
以下是需要遵循的步骤来安装 MongoDB 后端:
导入Ubuntu的包管理系统使用的 MongoDB 的 GPG 密钥。
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10
创建一个 /etc/apt/sources.list.d/mongodb.list 文件。
echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | sudo tee /etc/apt/sources.list.d/mongodb.list
更新仓库,然后安装最新版本的MongoDB。
sudo apt-get update
sudo apt-get install mongodb-10gen
如果使用 AWS,EC2 实例可以配置 EBS 用于存储。为了最佳性能,官方文档建议使用单独的卷来存储数据、日志和日志文件。使用 EBS 推荐用于维护 MongoDB 备份,可以随时恢复它们。
已经列出了需要遵循的步骤来使用 EBS 卷。
# 创建 EBS 文件系统
sudo mkfs -t ext4 /dev/xvdb
# 创建挂载点的目录。
# mkdir
mkdir /database
# 为了在启动时挂载卷,添加一个 fstab 条目
echo '/dev/xvdb /database ext4 defaults,auto,noatime,noexec 0 0' | sudo tee -a /etc/fstab
# 挂载数据库
sudo mount /dev/xvdb /database
# 创建数据、日志目录。
# 将它们放在一个单独的卷下
cd /database
mkdir data journal log
# 将这些目录的所有权设置为 mongodb
sudo chown -R mongodb:mongodb /database
接下来,需要配置 MongoDB 使用 dbpath 和 logpath。为此,需要编辑文件 /etc/mongodb.conf 并添加以下内容:
dbpath = /database/data
logpath = /database/log/mongodb.log
通过运行以下命令启动 mongod 服务:
sudo service mongod start
要创建一个新应用程序,首先创建一个新目录,然后运行 npm init 来为应用程序创建一个 package.json。
mkdir demo_app && cd demo_app
npm init
将入口点设置为 index.js。
需要安装 Express.js 用于服务器,以及 mongoose 驱动用于 node。使用 npm 安装依赖项。
npm install express mongoose --save
可以通过设置可执行权限然后运行它来验证应用程序是否工作。
现在编辑 index.js 文件如下:
const express = require('express');
const mongoose = require('mongoose');
const app = express();
app.get('/', (req, res) => res.send('App is running successfully on port 3000'));
app.listen(3000, () => console.log('Example app listening on port 3000!'));
var db = mongoose.connect('mongodb://localhost:27017/dbname', function(error){
if(error) console.log(error);
console.log("connection successful");
});
可以通过设置可执行权限然后运行它来验证应用程序是否工作。
chmod +x ./index.js
./index.js
应该得到以下输出:
App is running successfully on port 3000.
在生产环境中运行应用程序时,应用程序可能会失败、遇到错误然后崩溃。拥有一个进程管理器可以帮助避免这样的情况。尽管有许多其他进程管理器,如 foreverjs、systemd 和 Strongloop,但 PM2 脱颖而出。它提供了关于运行时性能和资源消耗的额外洞察。
如果还没有安装 PM2,请全局安装它。
sudo npm install -g pm2
pm2 start index.js 命令应该启动应用程序并将其添加到 PM2 的进程列表中。应该在命令行中看到类似这样的输出:
[PM2] Init System found: systemd
[PM2] You have to run this command as root. Execute the following command:
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u --hp /home/
替换最后一行中的所有 mjm 实例为用户名,然后运行命令。
该命令将创建一个 systemd 配置文件,在启动时执行 pm2。可以通过运行以下命令来检查 pm2 配置文件的状态:
systemctl status pm2-
目前运行在本地主机上。要使应用程序对外界可访问,需要使用服务器作为反向代理。Nginx 作为最受欢迎的 Web 服务器应用程序之一,绝对适合这个目的。假设已经安装了 nginx。如果没有,请参考 nginx 文档获取指导。
完成这些步骤后,打开 nginx 配置文件。该文件可能位于 /usr/local/nginx/conf、/etc/nginx 或 /usr/local/etc/nginx,具体取决于设置。
打开文件并在 server 块中,寻找 location 块。用以下代码替换其内容:
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;
}
如果已经用 nginx 服务器配置了域名,一切都应该直接工作。
验证配置文件在语法上是否正确。
sudo nginx -t
现在,重启 nginx。
sudo systemctl restart nginx
可以免费使用 Let's Encrypt 为网站添加加密,它提供免费的 SSL/TLS 证书。这已经在 James Johnes 的另一篇教程中介绍过了,标题是《如何在 Nginx 中安装 Let's Encrypt 并自动续期》。
如果严格按照步骤操作,那么示例 node.js 应用程序应该已经运行起来了。