VagrantでNode.jsとRedisを入れた仮想環境を構築

# 概要

先日、社内ハッカソンにて `socket.io` を利用したゲーム（[Rising Sun](http://rising.yudo.jp/)）を制作しました。
その際、 `Vagrant` を利用してローカル開発用の仮想環境を準備しましたので、
今回の制作で実施した手順を記載していきたいと思います。

`CentOS6.6` に、 `Node.js` と `Redis` を導入しています。
また、 `Node.js` は システムワイドに導入した `Nodebrew` 経由でインストールしています。

# 手順

## Vagrantfile作成

[Discover Vagrant Boxes](https://atlas.hashicorp.com/boxes/search) にて、使用するBoxを検索します。
今回は `chef/centos-6.6` を利用します。

```shell-session
cd /path/to/workspace
vagrant init chef/centos-6.6
```

## Shell Provision

`Chef` や `Ansible` などでサーバーの構築を記述することもできますが、
今回は短期間で準備するため、シェルスクリプトで行いました。
コマンドラインでの導入手順をそのまま記述すれば良いため、素早く作りやすいです。

以下、 `Nodebrew` と `Redis` の導入手順を確認した後、シェルスクリプトを作成します。

### Nodebrew

[ドキュメント](https://github.com/hokaccha/nodebrew#install)を参考に、ファイルを落としてきます。

```shell-session
cd /usr/local/src
wget git.io/nodebrew
```

デフォルトでは `$HOME/.nodebrew` にインストールされますが、
システムワイドにインストールするため、環境変数を設定した後に `setup` を実行します。

```shell-session
export NODEBREW_ROOT=/usr/local/nodebrew
perl nodebrew setup
```

`Nodebrew` へのパスを通すため、 `/etc/profile.d/nodebrew.sh` を設置します。

```shell-session
sudo cat << '_EOT_' > /etc/profile.d/nodebrew.sh
export PATH=/usr/local/nodebrew/current/bin:$PATH
export NODEBREW_ROOT=/usr/local/nodebrew
_EOT_
```

`Nodebrew` を操作するユーザーグループに権限を付与します。
今回は `vagrant` グループを指定しています。

```shell-session
sudo chgrp -R vagrant /usr/local/nodebrew
sudo chmod -R g+rwx /usr/local/nodebrew
```

パスを読み込み、 `Nodebrew` のアップデートを実行します。

```shell-session
source /etc/profile.d/nodebrew.sh
nodebrew selfupdate
```

`Node.js` をインストールします。

```shell-session
nodebrew install-binary stable
nodebrew use stable
```

### Redis

`remi` リポジトリより導入します。

```shell-session
sudo yum -y install redis --enablerepo=remi
```

自動起動の設定を行い、起動します。

```shell-session
sudo chkconfig redis on
sudo service redis start
```

### Shell Script

前述の手順に加えて、リポジトリ・ツールの導入なども行います。
最終的にシェルスクリプトは以下のような形になります。
`provision.sh` として、 Vagrantfile と同じディレクトリに配置しています。

```bash:provision.sh
#!/bin/sh

# Import repository
sudo rpm --import http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6
sudo rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
sudo rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi
sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm

# Update server
sudo yum -y update

# Install tools
sudo yum -y install gcc-c++
sudo yum -y install perl

# Install Nodebrew
cd /usr/local/src
wget git.io/nodebrew
export NODEBREW_ROOT=/usr/local/nodebrew
perl nodebrew setup
sudo cat << '_EOT_' > /etc/profile.d/nodebrew.sh
export PATH=/usr/local/nodebrew/current/bin:$PATH
export NODEBREW_ROOT=/usr/local/nodebrew
_EOT_
sudo chgrp -R vagrant /usr/local/nodebrew
sudo chmod -R g+rwx /usr/local/nodebrew
source /etc/profile.d/nodebrew.sh
nodebrew selfupdate

# Install Node.js
nodebrew install-binary stable
nodebrew use stable

# Install Redis
sudo yum -y install redis --enablerepo=remi
sudo chkconfig redis on
sudo service redis start
```

### Vagrantfile


今回はプライベートIPを `192.168.33.11` としています。
Vagrantfile は以下のような形になります。

```ruby
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "chef/centos-6.6"
  config.vm.network "private_network", ip: "192.168.33.11"

  config.vm.provision :shell, path: 'provision.sh'
end
```

`vagrant up` で新規に立ち上げると `provision.sh` の環境構築処理が始まります。


# 開発

デフォルトでは `/vagrant` がホストOSと共有のディレクトリになっていますので、
ホストOS側で Vagrantfile があるディレクトリに `Node.js` のサーバー側コードを設置し、
ゲストOS側で起動して開発を行いました。

今回の設定ですと、サーバー側が8080番ポートで待ち受けている場合、
`http://192.168.33.11:8080` でアクセスできます。

# 課題

* サーバーコードの更新があった場合、ゲストOS側で毎回再起動していました…。  
  できれば、変更を検知して自動的に反映するようにしたいですね。
* 立ち上げ時の環境構築処理で少なからず時間がかかってしまいます…。  
  `Docker` の利用で解決できそうですね。