Express Tutorial Part 7: Deploying to production

2018-05-15 17:26 更新
先决条件: 完成之前的所有教程主题,包括 Express教程第6部分:使用表单
目的: 了解在何处以及如何将Express应用程序部署到生产环境。

概述

一旦您的网站完成(或"足够"开始公开测试),您将需要将其托管在比您的个人开发计算机更公开和可访问的地方。

到目前为止,您一直在开发环境中使用Express / Node作为网络服务器将网站共享到本地浏览器/网络, 运行您的网站与(不安全)开发设置,暴露调试和其他私人信息。 在您可以外部托管网站之前,您首先必须:

  • Choose an environment for hosting the Express app.
  • Make a few changes to your project settings.
  • Set up a production-level infrastructure for serving your website.

本教程为您选择托管网站的选项提供了一些指导,简要概述了您的Express应用程序准备投入生产需要做什么,以及如何将LocalLibrary网站安装到 ="https://www.heroku.com/"class ="external"> Heroku 云托管服务。

什么是生产环境?

生产环境是由服务器计算机提供的环境,您将在其中运行您的网站以供外部使用。 环境包括:

  • Computer hardware on which the website runs.
  • Operating system (e.g. Linux or Windows).
  • Programming language runtime and framework libraries on top of which your website is written.
  • Web server infrastructure, possibly incuding a web server, reverse proxy, load balancer, etc.
  • Databases on which your website is dependent.

服务器计算机可以位于您的场所并通过快速链接连接到Internet,但是使用托管在"云中"的计算机是更常见的。 这实际上意味着你的代码在托管公司的数据中心的一些远程计算机(或可能是一个"虚拟"计算机)上运行。 远程服务器通常将以某个价格提供一些保证级别的计算资源(例如CPU,RAM,存储器存储器等)和互联网连接。

这种可远程访问的计算/联网硬件被称为基础设施即服务(IaaS)。 许多IaaS供应商提供了预安装特定操作系统的选项,必须在其上安装生产环境的其他组件。 其他供应商允许您选择更多功能齐全的环境,可能包括完整的节点设置。

注意:预建环境可以简化网站设置,因为它们会减少配置,但可用选项可能会限制您访问不熟悉的服务器(或其他组件),并且可能基于旧版本 版本的操作系统。 通常最好自己安装组件,以便获得所需的组件,当需要升级系统的某些部分时,您可以从哪里开始!

其他托管提供商将Express作为平台即服务( PaaS )产品的一部分提供支持。 当使用这种托管时,您不需要担心大多数生产环境(服务器,负载平衡器等),因为主机平台会为您处理这些环境。 这使得部署很容易,因为您只需要专注于您的Web应用程序,而不是任何其他服务器基础设施。

一些开发人员将选择IaaS通过PaaS提供的更大的灵活性,而另一些开发人员将会喜欢减少维护开销和更轻松地扩展PaaS。 当您开始使用时,在PaaS系统上设置您的网站要容易得多,因此这是我们将在本教程中做的。

提示:如果您选择了一个Node / Express-friendly托管服务提供商,他们应该提供有关如何使用不同配置的网络服务器,应用服务器,逆向代理等设置快捷网站的说明。例如, 数字海洋节点社区docs "中的各种配置的许多分步指南 >。

选择托管服务提供商

有许多托管服务提供商已知可以使用 Node (和 Express )来积极支持或工作良好。 这些供应商以不同的价格提供不同类型的环境(IaaS,PaaS)以及不同级别的计算和网络资源。

提示:有很多托管解决方案,其服务和定价可能会随时间而变化。 虽然我们在下面介绍几个选项,值得在选择主机提供商之前执行自己的互联网搜索。

选择主机时需要考虑的事项:

  • How busy your site is likely to be and the cost of data and computing resources required to meet that demand.
  • Level of support for scaling horizontally (adding more machines) and vertically (upgrading to more powerful machines) and the costs of doing so.
  • Where the supplier has data centres, and hence where access is likely to be fastest.
  • The host's historical uptime and downtime performance.
  • Tools provided for managing the site — are they easy to use and are they secure (e.g. SFTP vs FTP).
  • Inbuilt frameworks for monitoring your server.
  • Known limitations. Some hosts will deliberately block certain services (e.g. email). Others offer only a certain number of hours of "live time" in some price tiers, or only offer a small amount of storage.
  • Additional benefits. Some providers will offer free domain names and support for SSL certificates that you would otherwise have to pay for.
  • Whether the "free" tier you're relying on expires over time, and whether the cost of migrating to a more expensive tier means you would have been better off using some other service in the first place!

当你开始的好消息是,有相当多的网站提供"免费"的计算环境,尽管有一些条件。 例如, Heroku 提供了一个免费但资源有限的"永久"PaaS 环境,而 亚马逊网络服务 https://azure.microsoft.com/en-us/pricing/details/app-service/"class ="external"> Microsoft Azure 在您首次加入时提供免费赠送金额。 许多提供商还具有提供更有用的计算能力和较少限制的"基本"层。 数字海洋是一个流行的托管服务提供商的示例,提供相对便宜的基本计算层(每月5美元 写入时的下限)。

请注意:请记住,价格不是唯一的选择条件。 如果你的网站是成功的,可能会证明可扩展性是最重要的考虑。

让您的网站准备发布

发布网站时要考虑的主要因素是网络安全和性能。 最低限度,您将希望删除开发过程中包含在错误页面上的堆栈跟踪,清理日志记录,并设置适当的标头以避免许多常见的安全威胁。

在以下小节中,我们概述了您应该对应用进行的最重要的更改。

提示:Express文档中还提供了其他有用的提示 - 请参阅 >生产最佳做法:性能和可靠性生产最佳实践:安全 / a>。

将NODE_ENV设置为"production"

我们可以通过将 NODE_ENV 环境变量设置为生产(默认情况下设置为" development ")来删除错误页面中的堆栈跟踪。 除了生成较少详细的错误消息,将变量设置为 缓存视图模板和从CSS扩展生成的CSS文件。 测试表明将 NODE_ENV 设置为生产可以将应用性能提高三倍!

可以通过使用导出或环境文件或使用OS初始化系统进行此更改。

注意:这实际上是您在环境设置中所做的更改,而不是您的应用,但重要的是足以在此处注释! 我们将展示如何为我们的主机示例设置如下。

适当记录

记录呼叫可能会对高流量网站产生影响。 在生产环境中,您可能需要记录网站活动(例如跟踪流量或记录API调用),但您应该尝试最小化为调试目的添加的日志量。

减少生产中"调试"日志记录的一种方法是使用类似于调试的模块, 通过设置环境变量来控制执行什么日志记录。 例如,下面的代码片段显示了如何设置"作者"日志记录。 调试变量使用名称"author"声明,并且将自动显示来自此对象的所有日志的前缀"author"。

var debug = require('debug')('author');

// Display Author update form on GET
exports.author_update_get = function(req, res, next) {   
    
    req.sanitize('id').escape().trim();
    Author.findById(req.params.id, function(err, author) {
        if (err) {
            debug('update error:' + err);
            return next(err); }
        //On success
        res.render('author_form', { title: 'Update Author', author: author });
        
    });
};

然后,您可以通过在 DEBUG 环境变量中将它们指定为逗号分隔列表来启用特定的一组日志。 您可以设置显示作者和书籍日志的变量,如图所示(也支持通配符)。

#Windows
set DEBUG=author,book

#Linux
export DEBUG="author,book" 

挑战:调用 debug 可以替换以前使用 console.log() console.error / code>。 使用调试代码中的 console.log() a>模块。 通过设置DEBUG变量并在开发环境中打开和关闭日志记录,并观察其对日志记录的影响。

如果您需要记录网站活动,您可以使用日志库,如 Winston Bunyan 。 有关此主题的详情,请参阅:生产最佳做法:性能和可靠性

对响应使用gzip / deflate压缩

Web服务器通常可以压缩发送回客户端的HTTP响应,从而显着减少客户端获取和加载页面所需的时间。 所使用的压缩方法将取决于客户端在请求中支持哪些解压缩方法(如果不支持压缩方法,则将以未压缩的方式发送响应)。

您可以使用压缩中间件将其添加到您的网站。 通过在项目的根目录运行以下命令将其安装到您的项目。

npm install compression --save

打开 ./ app.js 并需要如图所示的压缩库。 使用 use()方法将压缩库添加到中间件链(这应该出现在任何你想要压缩的路由之前 - 在这种情况下,所有的路由!)

var catalog = require('./routes/catalog'); //Import routes for "catalog" area of site
var compression = require('compression');

// Create the Express application object
var app = express();

...

app.use(compression()); //Compress all routes

app.use(express.static(path.join(__dirname, 'public')));

app.use('/', index);
app.use('/users', users);
app.use('/catalog', catalog);  // Add catalog routes to middleware chain.

...

注意:对于正在投放的高流量网站,您不会使用此中间件。 相反,您将使用一个反向代理,如 Nginx

使用头盔来防范众所周知的漏洞

头盔是一个中间件软件包,可以通过设置适当的网址来帮助保护您的应用免受某些着名的网络漏洞 HTTP标头(请参阅文档,了解其设置的标头/防护的漏洞的详细信息)。

通过在项目的根目录运行以下命令将其安装到您的项目。

npm install helmet --save

打开 ./ app.js 并需要头盔库,如图所示。 然后使用 use()方法将模块添加到中间件链。

var compression = require('compression');
var helmet = require('helmet');

// Create the Express application object
var app = express();

app.use(helmet());
...

请注意:上述命令会添加可用标头的子集,这对大多数网站都有意义。 您可以按照 npm 上的说明,根据需要添加/停用特定标题。

示例:在Heroku上安装LocalLibrary

本部分提供了如何在 Heroku PaaS云上安装 LocalLibrary 的实际演示。

为什么选择Heroku?

Heroku是最长时间运行和流行的基于云的PaaS服务之一。 它最初仅支持Ruby应用程序,但现在可以用于托管来自许多编程环境的应用程序,包括Node(因此Express)!

我们选择使用Heroku有几个原因:

  • Heroku has a free tier that is really free (albeit with some limitations).
  • As a PaaS, Heroku takes care of a lot of the web infrastructure for us. This makes it much easier to get started, because you don't worry about servers, load balancers, reverse proxies, restarting your website on a crash, or any of the other web infrastructure that Heroku provides for us under the hood.
  • While it does have some limitations, these will not affect this particular application. For example:
    • Heroku provides only short-lived storage so user-uploaded files cannot safely be stored on Heroku itself.
    • The free tier will sleep an inactive web app if there are no requests within a half hour period. The site may then take several seconds to respond when it is woken up.
    • The free tier limits the time that your site is running to a certain amount of hours every month (not including the time that the site is "asleep"). This is fine for a low use/demonstration site, but will not be suitable if 100% uptime is required.
    • Other limitations are listed in Limits (Heroku docs).
  • Mostly it just works, and if you end up loving it and want to upgrade, scaling your app is very easy.

虽然Heroku是主办此演示的完美,它可能不是完美的您的真正的网站。 Heroku使事情容易建立和扩展,以更低的灵活性为代价,并且潜在地,一旦你走出免费层,更昂贵。

Heroku如何工作?

Heroku在一个或多个" Dynos "中运行网站,这些网站是孤立的,虚拟化的Unix容器,提供 运行应用程序所需的环境。 动态链接是完全隔离的,并且具有一个临时的文件系统(一个短暂的文件系统,每次重新启动时被清除/清空)。 dynos在默认情况下唯一共享的是应用程序配置变量。 Heroku内部使用负载均衡器将网络流量分发到所有"网络"动态。 由于它们之间没有共享,Heroku可以通过添加更多的dynos来水平扩展应用程序(当然,您可能还需要扩展数据库以接受其他连接)。

由于文件系统是临时的,因此您无法直接安装应用程序所需的服务(例如数据库,队列,缓存系统,存储,电子邮件服务等)。 相反,Heroku Web应用程序使用由Heroku或第三方提供的独立"附加组件"的后勤服务。 一旦附加到您的Web应用程序,附加服务通过环境变量在您的Web应用程序中访问。

为了执行您的应用程序,Heroku需要能够设置适当的环境和依赖关系,并且还了解如何启动它。 对于Node应用程序,需要的所有信息都从 package.json 文件中获取。

开发人员使用特殊的客户端应用程序/终端与Heroku交互,这很像Unix bash脚本。 这允许您上传存储在git存储库中的代码,检查正在运行的进程,查看日志,设置配置变量,以及更多!

为了让我们的应用程序在Heroku上工作,我们需要将Express Web应用程序放入git存储库,并对package.json进行一些小的更改。 一旦我们完成,我们可以设置一个Heroku帐户,获得Heroku客户端,并使用它来安装我们的网站。

这是您开始使用所需的全部概述(请参阅带有节点的Heroku入门 .js 以获得更全面的指南)。

在Github中创建应用程序存储库

Heroku与 git 源代码版本控制系统紧密集成,使用它来上传/同步对实时系统所做的任何更改。 它通过添加一个名为 heroku 的新Heroku"远程"存储库来指向Heroku云上的源代码库。 在开发过程中,您可以使用git将更改存储在"主"存储库中。 当您想部署您的网站时,您将更改同步到Heroku存储库。

注意:如果您习惯于遵循良好的软件开发实践,您可能已经在使用git或其他一些SCM系统。 如果你已经有一个git存储库,那么你可以跳过这一步。

有很多方法可以使用git,但最简单的方法之一是首先在 GitHub 上设置帐户 ,在那里创建存储库,然后在本地同步它:

  1. Visit https://github.com/ and create an account.
  2. Once you are logged in, click the + link in the top toolbar and select New repository.
  3. Fill in all the fields on this form. While these are not compulsory, they are strongly recommended.
    • Enter a new repository name (e.g. express-local-library), and description (e.g. "Local Library website written in Express (Node)".
    • Choose Node in the Add .gitignore selection list.
    • Choose your preferred license in the Add license selection list.
    • Check Initialize this repository with a README.
  4. Press Create repository.
  5. Click the green "Clone or download" button on your new repo page.
  6. Copy the URL value from the text field inside the dialog box that appears (it should be something like: https://github.com/<your_git_user_id>/express-local-library.git).

现在创建了存储库("repo"),我们将要在我们的本地计算机上克隆它:

  1. Install git for your local computer (you can find versions for different platforms here).
  2. Open a command prompt/terminal and clone your repository using the URL you copied above:
    git clone https://github.com/<your_git_user_id>/express-local-library.git
    
    This will create the repository below the current point.
  3. Navigate into the new repo.
    cd express-local-library

最后一步是在应用程序中复制,然后使用git将文件添加到您的repo中:

  1. Copy your Express application into this folder (excluding /node_modules, which contains dependency files that you should fetch from NPM as needed).
  2. Open a command prompt/terminal and use the add command to add all files to git.
  3. git add -A
    
  4. Use the status command to check all files that you are about to add are correct (you want to include source files, not binaries, temporary files etc.). It should look a bit like the listing below.
    > git status
    On branch master
    Your branch is up-to-date with 'origin/master'.
    Changes to be committed:
      (use "git reset HEAD <file>..." to unstage)
    
            new file:   ...
  5. When you're satisfied commit the files to your local repository:
    git commit -m "First version of application moved into github"
  6. Then synchronise your local repository to the Github website, using the following:
    git push origin master

当此操作完成后,您应该可以返回到Github上您创建repo的页面,刷新页面,并看到您的整个应用程序现在已上传。 当文件更改时,您可以使用add / commit / push循环继续更新存储库。

提示:这是备份您的"vanilla"项目的好方法,虽然我们将在以下部分进行的一些更改可能有助于在任何平台上部署 或发展)其他可能不。

最好的方法是使用 git 来管理您的修订版本。 使用 git ,你不仅可以回到一个特定的旧版本,但你可以保持在一个单独的"分支"从生产变化和樱桃选择任何变化在生产和开发分支之间移动。 学习Git 是非常值得的努力, 但超出了本主题的范围。

最简单的方法是将档案复制到其他位置。 使用最好匹配你的git知识的方法!

更新Heroku的应用程序

本部分介绍了您需要对我们的 LocalLibrary 应用程序进行的更改,以使其在Heroku上运行。

Set node version 

package.json 包含了解您的应用程序依赖关系以及应启动哪个文件来启动您的网站所需的一切。 Heroku检测到此文件的存在,并将使用它来调配应用程序环境。

在我们当前的 package.json 中缺少的唯一有用的信息是节点的版本。 我们可以通过输入命令找到我们用于开发的节点的版本:

>node --version
v6.9.1

打开 package.json ,并将此信息添加为 engines> 节点部分(使用系统的版本号)。

{
  "name": "express-locallibrary-tutorial",
  "version": "0.0.0",
  "engines": {
    "node": "6.9.1"
  },
  "private": true,
  ...

Database configuration

到目前为止,在本教程中,我们使用了一个硬编码到 app.js 中的单个数据库。 通常,我们希望能够有一个不同的数据库用于生产和开发,所以接下来我们将修改LocalLibrary网站,以从操作系统环境(如果已定义)获取数据库URI,否则使用我们的开发数据库 。

打开 app.js ,找到设置mongoDB连接变量的行。 它看起来像这样:

var mongoDB = 'mongodb://your_user_id:your_password@ds119748.mlab.com:19748/local_library';

使用 process.env.MONGODB_URI 的代码替换该行,以获取来自名为 MONGODB_URI 的环境变量的连接字符串(如果已设置) 而不是下面的占位符。)

var mongoDB = process.env.MONGODB_URI || 'mongodb://your_user_id:your_password@ds119748.mlab.com:19748/local_library';

Get dependencies and re-test

在我们继续之前,让我们再次测试网站,并确保它不受我们的任何更改的影响。

首先,我们需要获取我们的依赖(你会记得我们没有将 node_modules 文件夹复制到我们的git树中)。 您可以通过在项目根目录下的终端中运行以下命令来实现此目的:

npm install

现在运行网站(请参阅相关命令的测试路由),并检查网站是否仍按预期运行。

Save changes to Github

接下来让我们保存我们对Github的所有更改。 在终端(在我们的仓库里面),输入以下命令:

git add -A
git commit -m "Added files and changes required for deployment to heroku"
git push origin master

我们现在应该可以开始在Heroku上部署 LocalLibrary

获取Heroku帐户

要开始使用Heroku,您需要先创建一个帐户(如果您已经有帐户并安装了Heroku客户端,请先跳过创建和上传网站):

  • Go to www.heroku.com and click the SIGN UP FOR FREE button.
  • Enter your details and then press CREATE FREE ACCOUNT. You'll be asked to check your account for a sign-up email.
  • Click the account activation link in the signup email. You'll be taken back to your account on the web browser.
  • Enter your password and click SET PASSWORD AND LOGIN.
  • You'll then be logged in and taken to the Heroku dashboard: https://dashboard.heroku.com/apps.

安装客户端

按照 Heroku此处的说明

客户端安装后,您将能够运行命令。 例如获得客户端的帮助:

heroku help

创建并上传网站

要创建应用程序,我们在存储库的根目录中运行"create"命令。 这会在我们的本地git环境中创建一个名为 heroku 的git远程("指向远程存储库的指针")。

heroku create

注意:如果您愿意,可以在"创建"后指定值来命名远程。 如果你不这样,你会得到一个随机的名字。 该名称在默认URL中使用。

然后我们可以将我们的应用程序推送到Heroku存储库,如下所示。 这将上传的应用程序,获取所有的依赖,打包在一个动态,并启动网站。

git push heroku master

如果我们幸运,该应用程序现在"运行"在网站上。 要打开浏览器并运行新网站,请使用命令:

heroku open

注意:网站将使用我们的开发数据库运行。 创建一些书和其他对象,并检查网站是否按照您的期望行为。 在下一节中,我们将它设置为使用我们的新数据库。

设置配置变量

您将记得前一节中的内容,我们需要将NODE_ENV设置为"production",以提高性能并生成较少详细的错误消息。 我们通过输入以下命令来执行此操作:

>heroku config:set NODE_ENV='production'
Setting NODE_ENV and restarting limitless-tor-18923... done, v13
NODE_ENV: production

我们还应使用单独的数据库进行生产,并在 MONGODB_URI 环境变量中设置其URI。 您可以完全设置新的数据库和数据库用户,因为我们原来 ,并获取其URI。 您可以设置URI如图所示(显然,使用您自己的URI!)

>heroku config:set MONGODB_URI='mongodb://your_user:your_password@ds139278.mlab.com:39278/local_library_production'
Setting MONGODB_URI and restarting limitless-tor-18923... done, v13
MONGODB_URI: mongodb://your_user:your_password@ds139278.mlab.com:39278/local_library_production

您可以随时使用 heroku config 命令检查配置变量 - 立即尝试:

>heroku config
=== limitless-tor-18923 Config Vars
MONGODB_URI: mongodb://your_user:your_password@ds139278.mlab.com:39278/local_library_production
NODE_ENV:    production

Heroku会在更新变量时重新启动您的应用程序。 如果你现在检查主页,它应该显示零值的对象计数,因为上面的更改意味着我们现在使用一个新的(空)数据库。

管理插件

Heroku使用独立的附加组件为应用程序提供后备服务,例如电子邮件或数据库服务。 我们不在本网站使用任何插件,但他们是与Heroku合作的重要组成部分,因此您可能想查看主题 add-ons"class ="external">管理加载项(Heroku docs)。

调试

Heroku客户端提供了一些调试工具:

heroku logs  # Show current logs
heroku logs --tail # Show current logs and keep updating with any new results
heroku ps   #Display dyno status

    概要

    这是本教程关于在生产中设置快速应用程序的结束,以及关于使用Express的一系列教程。 我们希望你发现它们有用。 您可以在此处查看源代码的全面翻译版本

    也可以看看

    以上内容是否对您有帮助:
    在线笔记
    App下载
    App下载

    扫描二维码

    下载编程狮App

    公众号
    微信公众号

    编程狮公众号