20200601のNode.jsに関する記事は4件です。

Node.jsアプリケーションをElastic Beanstalkにデプロイする

以下の記事を参考に進めます。

Express アプリケーションを Elastic Beanstalk にデプロイする - AWS Elastic Beanstalk

検証環境

MacOS 10.15.4です。
ebコマンドさえ実行できれば、他のOSでも問題ありません。

EB CLI のインストール

brew update
brew install awsebcli
eb --version
> EB CLI 3.18.1 (Python 3.8.2)

eb init コマンドを使用してリポジトリを作成

mkdir node-express
cd node-express
eb init --platform node.js --region ap-northeast-1
> You have not yet set up your credentials or your credentials are incorrect 
> You must provide your credentials.
(aws-access-id): 
(aws-secret-key): 

IAMユーザーを未作成の場合はIAMユーザーを作成します。

IAMユーザの作成

スクリーンショット 2020-05-26 21.13.14.png

スクリーンショット 2020-05-26 21.15.09.png

これを先ほど聞かれたアクセスID、アクセスキーに入力する。

(aws-access-id): 
(aws-secret-key): 

eb create コマンドを使用して、サンプルアプリケーションを実行する環境を作成

以下のコマンドで、Node.jsと以下のリソースで負荷分散環境を作成します。

eb create --sample node-express-env

出力結果は以下の通り。

Environment details for: node-express-env
  Application name: node-express
  Region: ap-northeast-1
  Deployed Version: Sample Application
  Environment ID: e-8ipq7n7qmh
  Platform: arn:aws:elasticbeanstalk:ap-northeast-1::platform/Node.js running on 64bit Amazon Linux/4.14.3
  Tier: WebServer-Standard-1.0
  CNAME: UNKNOWN
  Updated: 2020-05-26 12:19:11.692000+00:00
Printing Status:
INFO    createEnvironment is starting.
INFO    Using elasticbeanstalk-ap-northeast-1-421146132732 as Amazon S3 storage bucket for environment data.
INFO    Created security group named: sg-01af1a0ddcfd9d7ca
INFO    Created load balancer named: awseb-e-8-AWSEBLoa-2E65Q23TKP6X
INFO    Created security group named: awseb-e-8ipq7n7qmh-stack-AWSEBSecurityGroup-T1U98MDMFMSA
INFO    Created Auto Scaling launch configuration named: awseb-e-8ipq7n7qmh-stack-AWSEBAutoScalingLaunchConfiguration-19I5UVFLE902H
INFO    Created Auto Scaling group named: awseb-e-8ipq7n7qmh-stack-AWSEBAutoScalingGroup-QY68AJ6H91M9
INFO    Waiting for EC2 instances to launch. This may take a few minutes.
INFO    Created Auto Scaling group policy named: arn:aws:autoscaling:ap-northeast-1:421146132732:scalingPolicy:45a700e3-bae8-437c-8d5b-d40e0c980cfd:autoScalingGroupName/awseb-e-8ipq7n7qmh-stack-AWSEBAutoScalingGroup-QY68AJ6H91M9:policyName/awseb-e-8ipq7n7qmh-stack-AWSEBAutoScalingScaleDownPolicy-18EMVJIJ45S9Z
INFO    Created Auto Scaling group policy named: arn:aws:autoscaling:ap-northeast-1:421146132732:scalingPolicy:178550d0-fc58-4642-a2bd-73013ffc9612:autoScalingGroupName/awseb-e-8ipq7n7qmh-stack-AWSEBAutoScalingGroup-QY68AJ6H91M9:policyName/awseb-e-8ipq7n7qmh-stack-AWSEBAutoScalingScaleUpPolicy-FTL8NRNS0CWG
INFO    Created CloudWatch alarm named: awseb-e-8ipq7n7qmh-stack-AWSEBCloudwatchAlarmLow-J8O5Z6ANTH8O
INFO    Created CloudWatch alarm named: awseb-e-8ipq7n7qmh-stack-AWSEBCloudwatchAlarmHigh-92OFURDBRAE5
INFO    Application available at node-express-env.eba-giwvvptw.ap-northeast-1.elasticbeanstalk.com.
INFO    Successfully launched environment: node-express-env
リソース 説明
EC2 インスタンス 説明省略
インスタンスセキュリティグループ ポート 80 上のインバウンドトラフィックを許可するように設定された Amazon EC2 セキュリティグループ
ロードバランサー 説明省略
ロードバランサーセキュリティグループ ポート 80 上のインバウンドトラフィックを許可するように設定された Amazon EC2 セキュリティグループ。
Auto Scaling グループ インスタンスが終了されたか利用不可になった場合にそのインスタンスを置き換えるように設定された Auto Scaling グループ
Amazon S3 バケット Elastic Beanstalk の使用時に作成されるソースコード、ログ、その他のアーティファクトの保存場所
Amazon CloudWatch アラーム 環境内のインスタンスの負荷をモニタリングし、負荷が高すぎたり低すぎたりするとトリガーする 2 つの CloudWatch アラーム
AWS CloudFormation スタック Elastic Beanstalk はAWS CloudFormation を使用して環境内のリソースを起動し、設定の変更を伝達します
ドメイン名 ウェブアプリケーションまでのルートとなるドメイン名であり、subdomain.region.elasticbeanstalk.com の形式です。

作成した環境を開く

eb open

サイトの表示が確認できた。
ちなみにこの時点でのディレクトリ構成は以下の通り、config.ymlがあるだけ。

.
├── .elasticbeanstalk
│   └── config.yml
└── .gitignore
.elasticbeanstalk/config.yml
branch-defaults:
  default:
    environment: node-express-env
    group_suffix: null
global:
  application_name: node-express
  branch: null
  default_ec2_keyname: null
  default_platform: Node.js
  default_region: ap-northeast-1
  include_git_submodules: true
  instance_profile: null
  platform_name: null
  platform_version: null
  profile: eb-cli
  repository: null
  sc: null
  workspace_type: Application

express環境の作成&デプロイ

npm install -g express-generator
express && npm install
.ebextensions/nodecommand.config
option_settings:
  aws:elasticbeanstalk:container:nodejs:
    NodeCommand: "npm start"
eb deploy

数分後、環境が更新されます。環境が緑色で示されていて準備完了したら、URLを再表示して正しく動作することを確認します。

別環境を作成する

  • マネコンから新規作成
  • マネコンから既存の環境をクローン
  • eb createで作成

開発環境にデプロイして、その後はAWSのマネコンから本番へデプロイなどもできます。
今回はeb createで作成しました。

eb create node-express-production

これによりマネコンにnode-express-productionが作成されています。
git commitのメッセージを確認&選択して、デプロイをクリック。

スクリーンショット 2020-06-01 21.40.38.png

node-express-productionを選択すると、無事本番環境にも反映されます。

スクリーンショット 2020-06-01 21.40.57.png

環境変数を設定する

設定から環境変数を設定することができます。

スクリーンショット 2020-06-01 22.08.51.png

各環境の読み込み方法については以下のリンクを参照

https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/environments-cfg-softwaresettings.html#environments-cfg-softwaresettings-accessing

参考リンク

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

IBM CloudでCloud Foundryアプリケーションをデプロイをする

こんにちは。Cloud IaaS超初心者です。
先日IBM Cloud のCloud Foundryを使用してアプリケーションをデプロイしようとした時に少し詰まったので備忘録として残しておきます。

まずはコンソール上でCloud Foundryアプリケーションを作る。
1. 「カタログ」->「Cloud Foundry」を検索
2. 「パブリックアプリケーション」を選択
3. リージョン「シドニー」(東京はない)、ランタイム「SDK for Node.js」、あとはドメイン名やホスト名などよしなに。

作成すると、コンソール上から「Cloud Foundryアプリケーション」として確認できる。

次にCLIからあらかじめ作成したプロジェクトをデプロイしてみる。
ログインとCLIコマンドインストール

ibmcloud login
ibmcloud cf install

targetを対話的に設定、、と思ったらここで問題発生。

~/Desktop/cloudfoundry/test $ ibmcloud target --cf
失敗
Cloud Foundry インスタンスを取得できませんでした:
Cloud Foundry パブリック・インスタンスと Cloud Foundry Enterprise Environment のどちらも見つかりませんでした。

なんでやねん。と思いながらいろいろ調べてみると、ログイン後に出てくるこいつに不信感を抱く。

~/Desktop/cloudfoundry/test $ ibmcloud login
API エンドポイント: https://cloud.ibm.com
認証中です...
OK

アカウントを選択:
1. ・・・
数値を入力してください> 1
ターゲットのアカウント ・・・'s Account (・・・)


地域を選択します (または Enter キーを押してスキップします):
1. au-syd
2. in-che
3. jp-osa
4. jp-tok
5. kr-seo
6. eu-de
7. eu-gb
8. us-south
9. us-south-test
10. us-east
数値を入力してください> 4
ターゲットの地域 jp-tok


API エンドポイント:      https://cloud.ibm.com   
地域:                    jp-tok   
ユーザー:                XXX   
アカウント:              XXX   
リソース・グループ:      リソース・グループがターゲットになっていません。'ibmcloud target -g RESOURCE_GROUP' を使用してください   
CF API エンドポイント:      
組織:                       
スペース:                   

とりあえずCF APIエンドポイントというのが空なのはよくなさそうなので設定してみる。今回はcloud foundryアプリ作成時に設定したリージョンであるシドニーをエンドポイントとする。

~/Desktop/cloudfoundry/test $ ibmcloud target --cf-api https://api.au-syd.cf.cloud.ibm.com
失敗
Cloud Foundry インスタンスを取得できませんでした:
Cloud Foundry インスタンス (API エンドポイント: https://api.au-syd.cf.cloud.ibm.com) は、地域 'jp-tok' 内のパブリック・インスタンスとしても、Cloud Foundry Enterprise Environment としても、見つかりませんでした。

な・ん・で、、、、、?と思ったがよく読んでみたら察し。「地域 'jp-tok' 内の」?!

自分のユーザ情報もう一度確認。

~/Desktop/cloudfoundry/test $ ibmcloud target 
API エンドポイント:      https://cloud.ibm.com   
地域:                    jp-tok   
ユーザー:                XXX  
アカウント:              XXX   
リソース・グループ:      リソース・グループがターゲットになっていません。'ibmcloud target -g RESOURCE_GROUP' を使用してください   
CF API エンドポイント:      
組織:                       
スペース:      

わたし「地域、jp-tokになっとるやないかい」
つい反射的に東京を選択していました。うっかりうっかり。
てことで気を取り直して

~/Desktop/cloudfoundry/test $ ibmcloud target -r au-syd
地域 au-syd
 に切り替えました


API エンドポイント:      https://cloud.ibm.com   
地域:                    au-syd   
ユーザー:                XXX  
アカウント:              XXX   
リソース・グループ:      リソース・グループがターゲットになっていません。'ibmcloud target -g RESOURCE_GROUP' を使用してください   
CF API エンドポイント:      
組織:                       
スペース:  

~/Desktop/cloudfoundry/test $ ibmcloud target --cf-api https://api.au-syd.cf.cloud.ibm.com
ターゲットの Cloud Foundry (https://api.au-syd.cf.cloud.ibm.com)



API エンドポイント:      https://cloud.ibm.com   
地域:                    au-syd   
ユーザー:                XXX   
アカウント:              XXX   
リソース・グループ:      リソース・グループがターゲットになっていません。'ibmcloud target -g RESOURCE_GROUP' を使用してください   
CF API エンドポイント:   https://api.au-syd.cf.cloud.ibm.com (API バージョン: 2.147.0)   
組織:                       
スペース:                   

キターーー
リージョンを適切にしたことでCF APIエンドポイントの登録ができ、無事にtargetコマンドも動きました。
あとはpushをするだけでデプロイができます。便利〜。
めでたしめでたし。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[LINE BOT]FizzBuzz体験BOT

目次

  • はじめに
  • サンプルコード
  • サンプル画像と使用例
  • おわりに
  • 参考にしたサイト

はじめに

今回は、LINE BOTでFizzBuzzをやってみた。
なお、当LINE BOTを作成する際に、この記事をベースにした。

サンプルコード

'use strict';

// 使用パッケージ群
const express = require('express'); // Node.jsで利用できるWebアプリケーションフレームワーク
const line = require('@line/bot-sdk'); // ボットサーバへのリクエストが当LineBOTからきたものかどうかを検証してくれる(要は署名検証)
const PORT = process.env.PORT || 3000;  //Node.jsアプリケーションを使用するポートを設定
// LineBOT用定数群
const config = {
    channelSecret: 'YourChannelSecret',
    channelAccessToken: 'YourChannelAccessToken'
};

const app = express();

app.post('/webhook', line.middleware(config), (req, res) =>
{
    console.log(req.body.events);
    Promise
        .all(req.body.events.map(handleEvent))
        .then((result) => res.json(result));
});

const client = new line.Client(config);

async function handleEvent(event)
{
    if (event.type !== 'message' || event.message.type !== 'text')
    {
        return client.replyMessage(event.replyToken, {
            type: 'text',
            text: "数字を入力してください。"
        });
    } else
    {
        if ((event.message.text % 3 === 0) && (event.message.text % 5 === 0))
        {
            // LineBOTに返信されるメッセージを設定
            return client.replyMessage(event.replyToken, {
                type: 'text',
                text: 'FizzBuzz' // LineBOTに返信されるメッセージ
            });
        } else if (event.message.text % 3 === 0)
        {
            return client.replyMessage(event.replyToken, {
                type: 'text',
                text: 'Fizz'
            });
        } else if (event.message.text % 5 === 0)
        {
            return client.replyMessage(event.replyToken, {
                type: 'text',
                text: 'Buzz'
            });
        } else
        {
            return client.replyMessage(event.replyToken, {
                type: 'text',
                text: event.message.text
            });
        }
    }
};

app.listen(PORT);
console.log(`Server running at ${PORT}`);

サンプル画像と使用例

こんな感じになります。
コメント 2020-06-01 131340.png

おわりに

次は、VercelでLINE BOTを動かす 2020年5月版を参考に、Vercelを介してLINE BOTを動かしてみようと思う。

参考にしたサイト

  • 使用したパッケージ群について

Node.jsのフレームワーク「Express」とは【初心者向け】
LINE BOTをHeroku + Node.jsでやるまで

  • webhook について

Webhookって何?を子どもでもわかるように描いてみた

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Express.jsにPassport.jsで、任意のフォルダ配下のみをBasic認証する

概要

ExpressフレームワークにBasic認証を適用する方法について記載します。

任意のフォルダのみにBasic認証を適用するものとし、そのフォルダにVue-CLIによるSPA(=Single Page Application)を置くことを目的とします。

方針

最小限のBasic認証を認証する場合はExpress.jsプロジェクトにて提供されるbasic-auth-connectライブラリでもよいのですが、他の認証への差し替えの容易性を考慮して、Passport.js を用いることとします。

認証を要求する領域と、不要とする領域を共存させたいので、任意のフォルダ配下のみをBasic認証の対象とします。

ついでに、Vue CLIで作成したSPAを任意フォルダへ配置するものとします。

なお、ユーザー名は「user」でパスワードは「pass」とします。本サンプルコードは動作確認が目的なので、パスワード管理はガバガバです。

(補足)Express3とExpress4の違い(basic-auth-coonect)

Express.jsでBasic認証を、で検索すると「express.basicAuth()」での実装例が時々ひっかかります。これは、Express3での記法とのことです。現在のExpress4では、「var basicAuth = require('basic-auth-connect');」とする仕組みに変わっています。

ref. https://qiita.com/zaru/items/51b415c80245920837ff

前提条件

AzureのWebアプリ(PaaS)を利用して公開する前提で、Express.jsを構築します。
具体的には、次のページの手順に従って作成します。

作成し終えたファイル一式は以下のようになります(※Mocha.jsでのテストを前提としてtestフォルダも作成しているが、この記事では使わない)。

ref. https://github.com/hoshimado/tdd-vuejs-book/tree/master/appendix/b-azure-express-mocha

先ずは、全体をBasic認証の対象とする方法

Passport.jsの必要なモジュールを次のようにインストールします。

npm install passport passport-http --save 

続いて、app.jsを次のように変更します。

// +++ ここから +++
var passport = require('passport');
var passportHttp = require('passport-http');
passport.use(new passportHttp.BasicStrategy(
    function (username, password, done) {
        if(username=='user' && password=='pass'){
            // ユーザー名とパスワードが有効なら true を返却する。
            return done(null,true);
        }else{
            // 無効なら、false を返却する(とUnauthorizedを画面表示)
            return done(null, false);
        }
    }
));
app.use('/', passport.authenticate('basic',{session: false}) );
// --- ここまで ---
app.use(express.static(path.join(__dirname, 'public'))); // この行の前に、↑を追加する。

この状態で、サーバーを「npm run dev」で起動すると、全体に対してBasic認証が設定されます。

次に、任意のフォルダ配下のみをBasic認証の対象とする方法

先の節で追加した部分を元に戻します。

本サンプルでは「/auth/byvue」へのアクセスに対してのみ、Basic認証を掛けるものとします。

任意のフォルダ配下のみにBasic認証を掛けるには「ルーティング設定で対象フォルダに対してpassport.authenticate()のミドルウェアを指定し、認証成功時にexpress.static()で静的ファイルを表示する(か、次のルーティングへ渡す)」ようにします。

具体的には、例えば次のようにします。(※本サンプルでは、対象を静的ファイルとします)。

  1. app.jsで、publicフォルダ配下の静的ファイルを処理している1行をコメントアウト
  2. 制御用のファイルroutes/auth.jsを作成して、対象パスへのアクセスをそちらへルーティング
app.js
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');

var app = express();

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
// app.use(express.static(path.join(__dirname, 'public'))); // ★コメントアウトする


//app.use('/', indexRouter); // ★利用していないので、ここもコメントアウトする
app.use('/auth', require('./routes/auth')); // ★追加する
app.use('/users', usersRouter);

module.exports = app;
  1. 作成したファイルroutes/auth.jsに次を記述
  2. auth/byvueフォルダと、auth/simplyフォルダ配下に適当な表示用htmlファイルを置く
auth.js
var express = require('express');
var path = require('path');
var router = express.Router();


var passport = require('passport');
var passportHttp = require('passport-http');
passport.use(new passportHttp.BasicStrategy(
    function (username, password, done) {
        if(username=='user' && password=='pass'){
            return done(null,true);
        }else{
            return done(null, false);
        }
    }
));


router.use('/byvue', passport.authenticate('basic',{session: false}), express.static(path.join(__dirname, '../auth/byvue')) ); // ★ここにだけBasic認証を掛ける
router.use('/', express.static(path.join(__dirname, '../auth')) ); // ★それ以外はそのまま表示する。

module.exports = router;

上記までを終えたら、「npm run dev」でhttpサーバーを起動します。

下記へアクセスすると、Basic認証を求められます。
(※本サンプルでは、express.static()でマッピングするフォルダを実際のパスに合わせてますが、異なるフォルダをマッピングしてももちろん構いません。)

http://localhost:3000/auth/byvue/

それ以外の、例えば下記へアクセスすると、Basic認証無しで表示されます。

http://localhost:3000/auth/simply/

もちろん、下記へのアクセスもBasic認証無し、となります。

http://localhost:3000/auth/

http://localhost:3000/

Basic認証については以上です。

オマケとして、任意フォルダ配下へVue CLIでBuildしたファイルを配置する方法

オマケです(当方にとっては、こっちが目的だったので)。

上記の「auth/byvue」のフォルダに、Vue CLIで作成したファイルを配置するには、次のようにします。本サンプルではExpress用のsrcフォルダと同じ階層にVue CLIのプロジェクトをcli-vueという名称で作成したと仮定します。

  1. cli-vueフォルダ直下に、vue.config.jsファイルを次のように配置する(ファイル名は固定)
  2. 「npm run build」でビルドする
vue.config.js
module.exports = {
    // options...
    outputDir : '../src/auth/byvue',
    publicPath : './'
}

ここで、それぞれのオプションは以下を意味します。

  • outputDir : ビルドしたファイルの出力先フォルダパス。このフォルダは毎回「削除→再作成」されることに注意。
  • publicPath : ビルドしたhtmlファイルの「基底URL」(HTMLのbaseタグ)。デフォルトでは絶対パスの「/」。
    • 今回のサンプルでは「サブフォルダ」に配置したかったので、「相対パス(./)」で扱うように設定

ref. https://cli.vuejs.org/config/#publicpath

上記までを終えたら、「npm run dev」でhttpサーバーを起動します。

下記へアクセスすると、Basic認証を経たのちにVue CLIで作成されたページが表示されます。

http://localhost:3000/auth/byvue/

以上ー。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む