AWS EC2でNodeを動作させる

# 1. はじめに

WebSocketアプリケーション開発の準備として、EC2上でNode.jsによってシンプルなHTTPサーバを動作させるまでを解説します。

### リアルタイムWebアプリケーション制作のために必要な技術と環境

　インターネットを介して、グローバルなネットワーク上で、ユーザ同士がインタラクションを行うことができるシステムを構築したい場合いくつかの手法が考えられますが、リアルタイム性を考慮するならば、WebSocketの通信技術を用いるのが最適です。
その場合、サーバとなるコンピュータを用意し、WebSocket通信を管理するサーバプログラムを作成し動作させなければなりませんが、個人でサーバを立てて管理するには多くの手間がかかります。ここではそのようなコストを考慮しないようにするため、仮想クラウドサーバーサービスである Amazon EC2 を利用します。また、WebSocketサーバプログラムの開発には学習コストも比較的低く、コードも軽量で済むJavaScriptを用いて行い、それをNode.jsで動作させることとします。



##### WebSocketとは
コンピュータ・ネットワーク用の通信規格の一つであり、ウェブサーバとウェブブラウザとの間の通信を想定した双方向通信用の技術規格です。
WebSocketは、まずクライアントからのリクエスト時にサーバとの接続を確立します。
接続が確立している間は、専用の軽量なプロトコルでデータのやり取りを行うので、効率的に双方向の通信が実現できます。

>WebSocketを研究してみた(ワークフロー活用事例ナビ)
https://www.atled.jp/jireinavi/develop/websocket/

##### Node.jsとは
Node.js は、サーバーサイドで実行されるJavaScriptアプリケーションのための実行環境です。規模が大きく、高速なネットワークを手軽に構築すること、をコンセプトとしています。
Chrome V8 JavaScriptエンジンで動作し、シングルスレッド、イベンド駆動、ノンブロッキングI/Oといった特徴を持っており、同時に多くのクライアントとの接続と処理を可能とし、WebSocketを使用するようなリアルタイムなアプリケーションの作成に向いています。

>Node.js公式サイト
https://nodejs.org/en/

##### AWSとは
「Amazon Web Services」
Amazon.comが提供しているクラウドサービス。仮想マシン、ストレージサービスなど様々なサービスが公開されており、一度アカウントを作成すれば、そのどれも簡単かつすぐに利用することができます。

>公式サイト(日本語)
https://aws.amazon.com/jp/

##### EC2とは
「Amazon Elastic Computing Cloud」
AWSの一つで、AmazonのWebサーバの計算リソースを仮想マシンとして利用できるサービスです。

>Amazon EC2とは
http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/concepts.html

# 2. AWSアカウントの作成
公式サイトに作成までの流れが詳しく説明してありますので、そちらをご覧ください。
>AWS アカウント作成の流れ
http://aws.amazon.com/jp/register-flow/

# 3. EC2インスタンスの作成
### ① EC2を選択
AWSマネジメントコンソール画面より、EC2を選択
![ec2node_000-02.png](https://qiita-image-store.s3.amazonaws.com/0/35267/625a74f6-699c-5821-62b0-fa3ad2e7d55b.png)

### ② インスタンスの作成ボタンを押す
![ec2node_001-02.png](https://qiita-image-store.s3.amazonaws.com/0/35267/911f6ee3-5fc4-8b70-92c4-ab8ee6cdb2d8.png)

### ③ ステップ1: Amazon マシンイメージ (AMI)の選択
Amazon Linux AMI を選択し、次の手順へ
![ec2node_002-02.png](https://qiita-image-store.s3.amazonaws.com/0/35267/e01dcc72-356f-6702-8f18-c0bd9e8ce580.png)

### ④ ステップ2: インスタンスタイプの選択
テストであれば一番上のものを選択し、次の手順へ
![003-01.png](https://qiita-image-store.s3.amazonaws.com/0/35267/7be2e18a-5fad-b697-db6f-e024529aeac4.png)


### ⑤ ステップ3: インスタンスの詳細の設定
**自動割り当てパブリック IP** を **サブネット設定を使用（有効）** にしておく
次の手順へ
![004-01.png](https://qiita-image-store.s3.amazonaws.com/0/35267/69f51143-e5a9-ba39-cb8c-cc22c11c8f43.png)


### ⑥ ステップ4: ストレージの追加
テストであれば何もせず次へ
![005-01.png](https://qiita-image-store.s3.amazonaws.com/0/35267/70d47699-69f8-4531-b840-363214f312d4.png)


### ⑦ ステップ5: インスタンスのタグ付け
インスタンスを管理する時に便利になるタグを定義できます。 
値に、わかりやすいインスタンスの名前を設定しましょう。
![006-01.png](https://qiita-image-store.s3.amazonaws.com/0/35267/a59fd574-6793-bd09-f426-6485ce7590ac.png)

### ⑧ ステップ6: セキュリティグループの設定
WebSocketサーバにアクセスする時に使用するポートをルールに追加します.

ポート3000番を使用することにしましょう.

**ルールの追加** ボタンを押し、
タイプ : カスタム TCP ルール,
プロトコル : TCP,
ポート範囲 : 3000,
送信元 : 任意の場所
とし、**確認と作成**ボタンを押します。

![007-01.png](https://qiita-image-store.s3.amazonaws.com/0/35267/bb3ee6a7-6a38-95fa-cdad-a84043d0dc6a.png)

### ⑨ ステップ7: インスタンス作成の確認
各項目に間違いがなければ、**作成**ボタンを押します.
![008-01.png](https://qiita-image-store.s3.amazonaws.com/0/35267/ca6f2198-d659-5af0-4c6b-21a350d6c1bf.png)


### 10 キーペアの割り当て
キーペアはSSHでEC2にアクセスする際に使用します.
**新しいキーペアの作成**を選択し、**キーペア名**にわかりやすい名前を設定します。
**キーペアのダウンロード**を押すと、**[キーペア名].pem**というプライベートキーファイルがダウンロードされるので、ローカルコンピュータ内の安全な場所に置いておいてください。

キーペアの割り当てが終わったら、**インスタンスの作成**ボタンを押してください。

![009-01.png](https://qiita-image-store.s3.amazonaws.com/0/35267/5752844f-00aa-b310-7a34-288090701b26.png)

インスタンスの作成ボタンを押すと、インスタンスの作成が始まります。
しばらく時間がかかります。
インスタンスの作成が完了したかは、インスタンスの状態から確認できます。
*pending* が *running* になったらインスタンスの作成が完了です。

![011-01.png](https://qiita-image-store.s3.amazonaws.com/0/35267/c2a9d4ae-461d-6e75-79c3-eafcfbdcf428.png)


# 4. EC2インスタンスへの接続
EC2サーバには、SSHで接続し操作を行います。

※SSHとは
Secure Shell (SSH)
暗号や認証技術を利用して、安全にリモートコンピュータと通信するためのプロトコルです。パスワードなどの認証部分を含むすべてのネットワーク上の通信が暗号化されます。

Macの場合、
ターミナルを開きます。
先ほどダウンロードしたキーペアが置かれたディレクトリへ **cd** コマンドを利用して移動します。

```shell-session
$ cd [*.pemが置かれているディレクトリのパス]
```

sshが機能するには、キーが公開されていない必要があります。
**chmod** コマンドを使用して、アクセス権を変更します。
>chmod [Linuxコマンド]
http://www.k4.dion.ne.jp/~mms/unix/linux_com/chmod.html

```shell-session
$ chmod 400 [keypair_name].pem
```

インスタンスを作成すると、Amazon Linuxの場合、デフォルトで**ec2-user**というユーザが作成されます。EC2を作成して最初のリモートログインは ec2-user から行います。
-i オプションで キーペアファイルを指定、
ユーザ名にはEC2デフォルトのec2-userを、
IPアドレスは、インスタンスのパブリックIPを指定

```shell-session
$ ssh -i "[keypair_name].pem" ec2-user@[public_ip_address]
```

初めてのログインだと、以下のメッセージが出るので、**yes**とタイプしてください。

```shell-session
Are you sure you want to continue connecting (yes/no)?
```

接続に成功すると、以下のテキストが表示されます。

```
Warning: Permanently added 'xxx.xxx.xxx.xxx' (RSA) to the list of known hosts.

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2015.09-release-notes/
[ec2-user@ip-***-**-**-** ~]$ 
```

Windowsの場合、
コマンドプロンプトで同様の操作を行ってください。

# 5. EC2インスタンスにNode.jsのインストールする

ここで行う作業は主に、
1. Gitのインストール
2. nvmのインストール
3. Node.jsのインストール
です。

##### Gitとは
Git（ギット）とは、分散型バージョン管理システムの一つで、もともとLinuxのソースコードを効果的に管理するために開発されました。
nvmをインストールする際に使用するので、インストールしておきます。
>サルでもわかるGit入門
http://www.backlog.jp/git-guide/

##### nvmとは
NVM (Node Version Manager)
複数のNode.jsのバージョンを管理することができるようになるbashスクリプトです。
Node.jsは頻繁にアップデートが行われ、古いバージョンで作成したコードが新しいものだと動作しなくなってしまったりすることがあります。そのようなときに、すばやくNode.jsのバージョンを切り替えることができ、開発がしやすくなります。


引き続きターミナル上で作業を行います。

### ⓪ 準備


#### ⑴ yumコマンドでシステムのアップデート


```shell-session
$ sudo yum update
```

#### ⑵ g++コンパイラのインストール
後々追加するNodeモジュールのコンパイルなどに使います。

```shell-session
$ sudo yum -y install gcc-c++
```

### ① Gitのインストール

```shell-session
$ sudo yum -y install git
```

### ② nvmのインストール
#### ⑴ nvmのダウンロード
GitHubから nvmをクローンします。

```shell-session
$ git clone https://github.com/creationix/nvm.git ~/.nvm
```

nvmへのパスを通します。

```shell-session
$ source ~/.nvm/nvm.sh
```

#### ⑵ nvmコマンドへのパスの設定
このままではログアウトすると、nvmへのパスがリセットされnvmコマンドが使用できなくなり、その度に、パスを設定しなおさなくてはなりません。そこで、Linuxにログインしたときに実行される**.bash_profile**に設定を書き込みます。

ユーザのホームディレクトリにある **.bash_profile** (/home/ec2-user/.bash_profile) を**viエディタ**で開きます。

```shell-session
$ vi .bash_profile
```
**iキー**を押して、挿入モードにします。
>viエディタの使い方
http://net-newbie.com/linux/commands/vi.html

以下のテキストを追記します。

```vim
# nvm
if [[ -s ~/.nvm/nvm.sh ]] ; then
        source ~/.nvm/nvm.sh ;
fi
```

追記が完了したら、**escキー**を押し、**:wq**と入力してreturnキーを押し、変更を保存して閉じます。

`exit`でログアウトしてから、`ssh`接続しなおし設定を反映させた上で、`nvm`コマンドが使用できるか確認しましょう。


### ③ Node.jsをインストールする

#### ⑴ インストール可能な Node.js のバージョン一覧を表示します

```shell-session
$ nvm ls-remote
```

すると、

```shell-session
        v0.1.14
        v0.1.15
        v0.1.16
        ...
        v5.0.0
    ...
```

というように、インストール可能なNodeの一覧が表示されます。

最新の安定版(LTS)バージョンの確認は[Node.js公式のDownloadページ](https://nodejs.org/en/download/)から行えます。

#### ⑵ Node.js のインストール

```shell-session
$ nvm install 5.0.0
```

#### ⑶ 使用するバージョンの指定

インストールしたバージョンをnvmで指定します

```shell-session
$ nvm use v5.0.0

```

確認のため、以下のコマンドを打ち、

```shell-session
$ node -v
v5.0.0
```

と表示されたら成功です。

# 6. Nodeを実行する

テストとして、NodeによるシンプルなHTTPサーバを立ててみます。

### ① ディレクトリを作成し、その下に移動
デフォルトだと、/home/ec2-user の下に作られます。

```shell-session
$ mkdir nodetest
$ cd nodetest
```

### ② jsファイルを作成し、編集
http-server-simple.jsというファイルを作成します。

```shell-session
$ touch http-server-simple.js
$ vi http-server-simple.js
```

### ③ コードを記述
**i**で挿入モードにしてコードを記述。完了したら、**:wq**で保存して閉じる。

```js:http-server-simple.js
// httpモジュールの読み込み
var http = require('http');
// httpサーバの作成
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(3000); // ポート3000番でコネクションの受け入れを行う
// 実行時、コンソールに表示されるメッセージ
console.log('Server running at http://[your_public_ip]:3000/');
```

### ④ コードを実行
```shell-session
$ node http-server-simple.js
Server running at http://[your_public_ip]:3000/
```
Server running at ... というメッセージがコンソールに表示されたら成功です。エラーメッセージが表示された場合、コードの記述に間違いがある可能性があります。エラーメッセージに従って、コードの修正を行ってください。

`コマンドが見つかりません。`と表示される場合は、nvmで使用するnodeのバージョンが指定されていないのかも知れません。`$ nvm use vx.x.x`でバージョンの指定を行ってください。

### ⑤ ブラウザからアクセスする
ChromeやSafariなどのブラウザで、
`http://[your_ip_address]:3000/`
とアドレスバーに打ちこんで、アクセスしてみてください。
`Hello World`
と表示されたら成功です。