將 Node.js 快速應用程序部署到 Elastic Beanstalk - AWS Elastic Beanstalk

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

將 Node.js 快速應用程序部署到 Elastic Beanstalk

本節將引導您使用 Elastic Beanstalk 命令列介面 (EBCLI) 將範例應用程式部署至 Elastic Beanstalk,然後更新應用程式以使用 Express 架構。

必要條件

本教學課程需要下列先決條件:

  • Node.js 執行階段

  • 預設的 Node.js 套件管理工具軟體 npm

  • Express 命令列產生器

  • Elastic Beanstalk 命令列介面 (EB) CLI

有關安裝所列出之前三個元件和設定本機開發環境的詳細資訊,請參閱 為 Elastic Beanstalk 設置 Node.js 開發環境。在本教學課程中,您不需要安裝 Node.js,這也在參考的主題中提到。 AWS SDK

如需有關安裝和配置 EB 的詳細資訊CLI,請參閱安裝 Elastic Beanstalk 指令列介面設定 EB CLI

建立 Elastic Beanstalk 環境

應用程式目錄

對於應用程式原始碼套件,本教學課程使用的是名為 nodejs-example-express-rds 的目錄。為本教學課程建立 nodejs-example-express-rds 目錄。

~$ mkdir nodejs-example-express-rds
注意

本章中的每個教學課程皆會使用其自身的應用程式原始碼套件目錄。目錄名稱與教學課程所使用的範例應用程式名稱相符。

將您目前的工作目錄變更為 nodejs-example-express-rds

~$ cd nodejs-example-express-rds

現在,來設定執行 Node.js 平台和範例應用程式的 Elastic Beanstalk 環境。我們將使用 Elastic Beanstalk 命令行界面(E CLI B)。

為您的應用程式設定 EB CLI 儲存庫,並建立執行 Node.js 平台的 Elastic Beanstalk 環境
  1. 使用 eb init 命令建立一個儲存庫。

    ~/nodejs-example-express-rds$ eb init --platform node.js --region <region>

    此命令會在名為 .elasticbeanstalk 的資料夾內建立組態檔案,其中會指定應用程式使用的環境設定,並以目前資料夾為名建立 Elastic Beanstalk 應用程式。

  2. 使用 eb create 命令建立執行範例應用程式的環境。

    ~/nodejs-example-express-rds$ eb create --sample nodejs-example-express-rds

    本命令會使用 Node.js 平台的預設設定和下列資源,建立負載平衡的環境:

    • EC2執行個 — 設定為在您選擇的平台上執行 Web 應用程式的 Amazon 彈性運算雲端 (AmazonEC2) 虛擬機器。

      每個平台會執行特定的一套軟體、設定檔和指令碼,來支援特定的語言版本、架構、Web 容器或其組合。大多數平台使用 Apache 或NGINX作為位於 Web 應用程序前面的反向代理,將請求轉發給它,提供靜態資產以及生成訪問和錯誤日誌。

    • 執行個體安全群組 — 設定為允許連接埠 80 上輸入流量的 Amazon EC2 安全群組。此資源可讓負載平衡器的HTTP流量到達EC2執行 Web 應用程式的執行個體。在預設情況下,不允許傳輸資料從其他通訊埠傳送。

    • 負載平衡器 - Elastic Load Balancing 負載平衡器,可設定將請求分配到執行您應用程式的執行個體。負載平衡器也讓您的執行個體不需直接連接到網際網路。

    • 負載平衡器安全群組 — 設定為允許連接埠 80 上輸入流量的 Amazon EC2 安全群組。此資源可讓來自網際網路的HTTP流量到達負載平衡器。在預設情況下,不允許傳輸資料從其他通訊埠傳送。

    • Auto Scaling 群組 - Auto Scaling 群組,設為在執行個體終止或無法使用時,取代該執行個體。

    • Amazon S3 儲存貯體 - 儲存位置,用來儲存當您使用 Elastic Beanstalk 時所建立的原始程式碼、日誌和其他成品。

    • Amazon CloudWatch 警示 — 監控環境中執行個體負載的兩個 CloudWatch 警示,並在負載過高或過低時觸發警示。當警示觸發時,您的 Auto Scaling 群組會擴展或縮減以進行回應。

    • AWS CloudFormation 堆疊 — Elastic Beanstalk 用 AWS CloudFormation 來啟動環境中的資源並傳播組態變更。資源定義於範本中,您可在 AWS CloudFormation 主控台中檢視此範本。

    • 域名稱 — 在表單中路由到 Web 應用程式的網域名稱 subdomain.region. 彈性無線網站.

      注意

      為了增強 Elastic Beanstalk 應用程式的安全性,在公用尾碼清單 () 中註冊了彈性豆莖網域。PSL為了加強安全性,如果您需要在 Elastic Beanstalk 應用程式的預設網域名稱中設定敏感性 Cookie,我們建議您使用具 __Host- 前置詞的 Cookie。這種做法將有助於保護您的網域免受跨網站要求偽造嘗試的影響 ()。CSRF如需更多資訊,請參閱 Mozilla 開發人員網路中的設定 Cookie 頁面。

  3. 當環境建立完成時,請使用eb open指令在預設瀏覽器URL中開啟環境。

    ~/nodejs-example-express-rds$ eb open

您現在已使用範例應用程式建立 Node.js Elastic Beanstalk 環境。您可以使用自己的應用程式對其進行更新。接下來,我們會更新範例應用程式,以使用 Express 架構。

更新應用程式以使用 Express

使用範例應用程式建立環境後,您可使用自己的應用程式對其進行更新。在此程序中,我們先執行 expressnpm install 命令,以便在應用程式目錄中設定 Express 架構。然後,我們使用 EB CLI 來更新您的 Elastic Beanstalk 環境與更新的應用程序。

欲更新您的應用程式以使用 Express
  1. 執行 express 命令。這會產生 package.jsonapp.js 以及幾個目錄。

    ~/nodejs-example-express-rds$ express

    當提示您是否要繼續時,請輸入 y

    注意

    如果 express 命令無法使用,您可能未依先前先決條件章節中的所述內容安裝 Express 命令列產生器。或者,您可能需要設定本機電腦的目錄路徑設定,才可執行 express 命令。如需有關設定開發環境的詳細步驟,請參閱先決條件章節,以繼續進行本教學課程。

  2. 設定本機依存項目。

    ~/nodejs-example-express-rds$ npm install
  3. (選用) 確認 Web 應用程式伺服器已啟動。

    ~/nodejs-example-express-rds$ npm start

    您應該會看到類似下列的輸出:

    > nodejs@0.0.0 start /home/local/user/node-express > node ./bin/www

    依預設,伺服器將會在連接埠 3000 上執行。要對其進行測試,請curl http://localhost:3000在其他終端機上運行,或在本地計算機上打開瀏覽器並輸入URL地址http://localhost:3000

    Ctrl+C 來停止伺服器。

  4. 使用 eb deploy 命令將變更部署至您的 Elastic Beanstalk 環境。

    ~/nodejs-example-express-rds$ eb deploy
  5. 一旦環境為綠色並準備就緒,請重新整理URL以驗證其正常運作。您應看到顯示 Welcome to Express 的網頁。

接著,我們會更新 Express 應用程式以提供靜態檔案,並新增新的頁面。

欲設定靜態檔案並新增新的頁面至您的 Express 應用程式
  1. 使用下列內容,在 .ebextensions 資料夾中新增第二個組態檔案:

    nodejs-example-express-rds/.ebextensions/staticfiles.config

    option_settings: aws:elasticbeanstalk:environment:proxy:staticfiles: /stylesheets: public/stylesheets

    此設定會將代理伺服器設定為在應用程式 public 路徑的 /public 資料夾內提供檔案。從代理伺服器靜態提供檔案,能夠減少應用程式負載。如需詳細資訊,請參閱本章先前所述的靜態檔案

  2. (選用) 若要確認靜態映射的設定是否正確,請在 nodejs-example-express-rds/app.js 中註解靜態映射設定。這會從節點應用程式中移除映射。

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

    即使在註解此行後,上一個步驟 staticfiles.config 檔案中的靜態檔案映射應仍可成功載入樣式表。若要確認靜態檔案映射是透過代理靜態檔案組態 (而非 Express 應用程式) 載入,請移除 option_settings: 後的值。將其從靜態檔案組態和節點應用程式移除之後,樣式表將無法載入。

    完成測試時,請記得重設 nodejs-example-express-rds/app.jsstaticfiles.config 的內容。

  3. 新增 nodejs-example-express-rds/routes/hike.js。輸入下列內容:

    exports.index = function(req, res) { res.render('hike', {title: 'My Hiking Log'}); }; exports.add_hike = function(req, res) { };
  4. 更新 nodejs-example-express-rds/app.js 以納入三個新的行。

    首先,新增下列行來為此路由添加 require

    var hike = require('./routes/hike');

    您的檔案看起來如下列程式碼片段:

    var express = require('express'); var path = require('path'); var hike = require('./routes/hike');

    然後,請在 nodejs-example-express-rds/app.js 後將下列兩行新增至 var app = express();

    app.get('/hikes', hike.index); app.post('/add_hike', hike.add_hike);

    您的檔案看起來如下列程式碼片段:

    var app = express(); app.get('/hikes', hike.index); app.post('/add_hike', hike.add_hike);
  5. nodejs-example-express-rds/views/index.jade 複製至 nodejs-example-express-rds/views/hike.jade

    ~/nodejs-example-express-rds$ cp views/index.jade views/hike.jade
  6. 使用 eb deploy 命令部署變更。

    ~/nodejs-example-express-rds$ eb deploy
  7. 您的環境將在幾分鐘後更新。在您的環境為綠色並準備就緒後,請通過刷新瀏覽器並hikes在URL(例如http://node-express-env-syypntcz2q.elasticbeanstalk.com/hikes)末尾附加來驗證其工作。

    您應看到標題為 My Hiking Log (My Hiking Log) 的網頁。

現在,您已建立使用 Express 架構的 Web 應用程式。在下一節中,我們將修改應用程式以使用 Amazon Relational Database Service (RDS) 來儲存遠足日誌。

更新應用程序以使用 Amazon RDS

在下一步中,我們更新應用程序以使用 Amazon RDS 為我的SQL.

若要更新您的應用程式以用RDS於 [我的] SQL
  1. 若要RDS為我的SQL資料庫建立結合至 Elastic Beanstalk 環境的資料庫,請遵循本章稍後所包含的新增資料庫主題中的指示進行操作。新增資料庫執行個體約需要 10 分鐘。

  2. 使用下列內容更新 package.json 中的相依性區段:

    "dependencies": { "async": "^3.2.4", "express": "4.18.2", "jade": "1.11.0", "mysql": "2.18.1", "node-uuid": "^1.4.8", "body-parser": "^1.20.1", "method-override": "^3.0.0", "morgan": "^1.10.0", "errorhandler": "^1.5.1" }
  3. 執行 npm install

    ~/nodejs-example-express-rds$ npm install
  4. 更新 app.js,以便連接至資料庫、建立資料表,並插入單一預設增長日誌。每次部署此應用程式時,其會捨棄先前的增長資料表,並重新建立。

    /** * Module dependencies. */ const express = require('express') , routes = require('./routes') , hike = require('./routes/hike') , http = require('http') , path = require('path') , mysql = require('mysql') , async = require('async') , bodyParser = require('body-parser') , methodOverride = require('method-override') , morgan = require('morgan') , errorhandler = require('errorhandler'); const { connect } = require('http2'); const app = express() app.set('views', __dirname + '/views') app.set('view engine', 'jade') app.use(methodOverride()) app.use(bodyParser.json()) app.use(bodyParser.urlencoded({ extended: true })) app.use(express.static(path.join(__dirname, 'public'))) app.set('connection', mysql.createConnection({ host: process.env.RDS_HOSTNAME, user: process.env.RDS_USERNAME, password: process.env.RDS_PASSWORD, port: process.env.RDS_PORT})); function init() { app.get('/', routes.index); app.get('/hikes', hike.index); app.post('/add_hike', hike.add_hike); } const client = app.get('connection'); async.series([ function connect(callback) { client.connect(callback); console.log('Connected!'); }, function clear(callback) { client.query('DROP DATABASE IF EXISTS mynode_db', callback); }, function create_db(callback) { client.query('CREATE DATABASE mynode_db', callback); }, function use_db(callback) { client.query('USE mynode_db', callback); }, function create_table(callback) { client.query('CREATE TABLE HIKES (' + 'ID VARCHAR(40), ' + 'HIKE_DATE DATE, ' + 'NAME VARCHAR(40), ' + 'DISTANCE VARCHAR(40), ' + 'LOCATION VARCHAR(40), ' + 'WEATHER VARCHAR(40), ' + 'PRIMARY KEY(ID))', callback); }, function insert_default(callback) { const hike = {HIKE_DATE: new Date(), NAME: 'Hazard Stevens', LOCATION: 'Mt Rainier', DISTANCE: '4,027m vertical', WEATHER:'Bad', ID: '12345'}; client.query('INSERT INTO HIKES set ?', hike, callback); } ], function (err, results) { if (err) { console.log('Exception initializing database.'); throw err; } else { console.log('Database initialization complete.'); init(); } }); module.exports = app
  5. 將下列內容新增至 routes/hike.js。這將使路線能夠將新的遠足日誌插入到HIKES數據庫中。

    const uuid = require('node-uuid'); exports.index = function(req, res) { res.app.get('connection').query( 'SELECT * FROM HIKES', function(err, rows) { if (err) { res.send(err); } else { console.log(JSON.stringify(rows)); res.render('hike', {title: 'My Hiking Log', hikes: rows}); }}); }; exports.add_hike = function(req, res){ const input = req.body.hike; const hike = { HIKE_DATE: new Date(), ID: uuid.v4(), NAME: input.NAME, LOCATION: input.LOCATION, DISTANCE: input.DISTANCE, WEATHER: input.WEATHER}; console.log('Request to log hike:' + JSON.stringify(hike)); req.app.get('connection').query('INSERT INTO HIKES set ?', hike, function(err) { if (err) { res.send(err); } else { res.redirect('/hikes'); } }); };
  6. routes/index.js 的內容取代為:

    /* * GET home page. */ exports.index = function(req, res){ res.render('index', { title: 'Express' }); };
  7. 將以下 Jade 範本新增至 views/hike.jade,以提供用於新增增長日誌的使用者介面。

    extends layout block content h1= title p Welcome to #{title} form(action="/add_hike", method="post") table(border="1") tr td Your Name td input(name="hike[NAME]", type="textbox") tr td Location td input(name="hike[LOCATION]", type="textbox") tr td Distance td input(name="hike[DISTANCE]", type="textbox") tr td Weather td input(name="hike[WEATHER]", type="radio", value="Good") | Good input(name="hike[WEATHER]", type="radio", value="Bad") | Bad input(name="hike[WEATHER]", type="radio", value="Seattle", checked) | Seattle tr td(colspan="2") input(type="submit", value="Record Hike") div h3 Hikes table(border="1") tr td Date td Name td Location td Distance td Weather each hike in hikes tr td #{hike.HIKE_DATE.toDateString()} td #{hike.NAME} td #{hike.LOCATION} td #{hike.DISTANCE} td #{hike.WEATHER}
  8. 使用 eb deploy 命令部署變更。

    ~/nodejs-example-express-rds$ eb deploy

清除

如果您已完成使用 Elastic Beanstalk,您可終止環境。

使用 eb terminate 命令來終止您的環境及其中的所有資源。

~/nodejs-example-express-rds$ eb terminate The environment "nodejs-example-express-rds-env" and all associated instances will be terminated. To confirm, type the environment name: nodejs-example-express-rds-env INFO: terminateEnvironment is starting. ...