Node.js Express アプリケーションの Elastic Beanstalk へのデプロイ - AWS Elastic Beanstalk

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

Node.js Express アプリケーションの Elastic Beanstalk へのデプロイ

このセクションでは、Elastic Beanstalk コマンドラインインターフェイス (EB CLI) を使用して Elastic Beanstalk にサンプルアプリケーションをデプロイした後、Express フレームワークを使用するようにアプリケーションを更新する手順を説明します。

前提条件

このチュートリアルでは、次の前提条件が必要です。

  • Node.js ランタイム

  • デフォルトの Node.js パッケージマネージャーソフトウェア、npm

  • Express コマンドラインジェネレーター

  • Elastic Beanstalk コマンドラインインターフェイス(EB CLI)

最初の 3 つのリストされたコンポーネントのインストールとローカル開発環境の設定の詳細については、「Elastic Beanstalk 用の Node.js 開発環境の設定」を参照してください。このチュートリアルでは、AWS SDK for Node.js をインストールする必要はありません。これは、参照トピックでも言及されています。

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 コマンドラインインターフェイス (EB CLI) を使用します。

アプリケーションの 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 インスタンス – 選択したプラットフォームでウェブ・アプリケーションを実行するよう設定された Amazon Elastic Compute Cloud (Amazon EC2) 仮想マシン。

      各プラットフォームは、それぞれ特定の言語バージョン、フレームワーク、ウェブコンテナ、またはそれらの組み合わせをサポートするための、特定のソフトウェア、設定ファイル、スクリプトを実行します。ほとんどのプラットフォームでは、Apache または NGINX のいずれかをウェブアプリケーションの前にリバースプロキシとして配置します。そのプロキシがリクエストをアプリケーションに転送し、静的アセットを提供し、アクセスログとエラーログを生成します。

    • インスタンスセキュリティグループ – ポート 80 上のインバウンドトラフィックを許可するよう設定された Amazon EC2 セキュリティグループ。このリソースでは、ロードバランサーからの HTTP トラフィックが、ウェブ・アプリケーションを実行している EC2 インスタンスに達することができます。デフォルトでは、トラフィックは他のポート上で許可されません。

    • ロードバランサー – アプリケーションを実行するインスタンスにリクエストを分散するよう設定された Elastic Load Balancing ロードバランサー。ロードバランサーにより、インスタンスを直接インターネットに公開する必要もなくなります。

    • ロードバランサーセキュリティグループ – ポート 80 上のインバウンドトラフィックを許可するよう設定された Amazon EC2 セキュリティグループ。このリソースでは、インターネットからの HTTP トラフィックが、ロードバランサーに達することができます。デフォルトでは、トラフィックは他のポート上で許可されません。

    • Auto Scaling グループ – インスタンスが終了されたか利用不可になった場合にそのインスタンスを置き換えるよう設定された Auto Scaling グループ。

    • Amazon S3 バケット – Elastic Beanstalk の使用時に作成されるソースコード、ログ、その他のアーティファクトの保存場所。

    • Amazon CloudWatch アラーム – 環境内のインスタンスの負荷をモニタリングする 2 つの CloudWatch アラーム。負荷が高すぎる、または低すぎる場合にトリガーされます。アラームがトリガーされると、Auto Scaling グループはレスポンスとしてスケールアップまたはダウンを行います。

    • AWS CloudFormation スタック – 環境内でリソースを起動して、設定の変更を伝達するために、Elastic Beanstalk は AWS CloudFormation を使用します。リソースは、AWS CloudFormation コンソールに表示できるテンプレートで定義されます。

    • ドメイン名 – ウェブ・アプリケーションまでのルートとなるドメイン名であり、subdomain.region.elasticbeanstalk.com の形式です。

      ドメインセキュリティ

      Elastic Beanstalk アプリケーションのセキュリティを強化するため、elasticbeanstalk.com ドメインはパブリックサフィックスリスト (PSL) に登録されています。

      Elastic Beanstalk アプリケーションのデフォルトドメイン名に機密性のある Cookie を設定する必要がある場合は、セキュリティ強化のため __Host- プレフィックスの付いた Cookie の使用をお勧めします。このプラクティスは、クロスサイトリクエストフォージェリ (CSRF) 攻撃からドメインを防御します。詳細については、Mozilla 開発者ネットワークの「Set-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. (オプション) ウェブアプリサーバーが起動することを確認します。

    ~/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. 次の内容を含む 2 つ目の設定ファイルを .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 を更新して新しく 3 つの行を含めます。

    まず、次の行を追加して、このルートに require を追加します。

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

    ファイルは次のスニペットのようになります。

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

    その後、次の 2 つの行を nodejs-example-express-rds/app.jsvar 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.jadenodejs-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. 数分後、環境が更新されます。環境が緑色で示されていて準備が完了したら、ブラウザを再表示し、URL の最後に hikes を追加して (http://node-express-env-syypntcz2q.elasticbeanstalk.com/hikes など)、正しく動作することを確認します。

    タイトルが [My Hiking ログ] のウェブ・ページが表示されます。

これで、Express フレームワークを使用するウェブアプリケーションが作成されました。次のセクションでは、Amazon Relational Database Service (RDS) を使用してハイキングログを保存するようにアプリケーションを変更します。

Amazon RDS を使用するようにアプリケーションを更新する

この次のステップでは、Amazon RDS for MySQL を使用するようにアプリケーションを更新します。

RDS for MySQL を使用するようにアプリケーションを更新するには
  1. Elastic Beanstalk 環境に結合された RDS for MySQL データベースを作成するには、この章で後述する「データベースの追加」トピックの手順に従ってください。データベースインスタンスの追加には約 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 を更新してデータベースに接続し、テーブルを作成し、単一のデフォルトのハイキングログを挿入します。このアプリがデプロイされるたびに、前の hikes テーブルが削除され、再作成されます。

    /** * 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. ...