vagrant shareでrails sを公開する


関係者に開発中の画面を見てもらうために、今までは開発環境を作ってそこにデプロイしていたのですが、その環境のためにお金もかかるしデプロイの時間もかかるので、Vagrant Shareを使って、自身の開発環境を見てもらうことにしました。

今回はそこまでにやったことを書いていこうと思います。

## Vagrantの導入

[Vagrant Download](https://www.vagrantup.com/downloads.html)から、ダウンロードしてインストールしてください。

私の場合はMacなのでMac版をダウンロードしました。

# VM用の準備

## Vagrantfileの作成

Vagrant用のディレクトリを作って、そこにVagrantfileを作ります。
Vagrantfileは、Vagrantで作るOSのイメージの設定ファイルです。

```Bash
mkdir -p ~/vm/vagrant_get_started
cd ~/vm/vagrant_get_started
vagrant init
```

## Vagrantfileの編集

では、編集していきます。

### OSの選択

今回はUbuntuをインストールすることにしました。boxに、元になるOSイメージを設定します。

```rb:Vagrantfile
Vagrant.configure(2) do |config|
  # …(略)
  config.vm.box = "ubuntu/trusty64"
  # …(略)
end
```

### forwarded_portの設定

この設定は、Vagrantで起動したOSの指定ポートをホストOSのポートに転送する設定です。
今回の設定では、仮想環境のポート3000番をホストOSの3000番ポートに転送します。
仮想環境上で`rails s`しても、今まで変わらず http://localhost:3000 でアクセスできるようにしています。

```rb:Vagrantfile
Vagrant.configure(2) do |config|
  # …(略)
  config.vm.network :forwarded_port, host: 3000, guest: 3000
  # …(略)
end
```

### synced_folderの設定

これは、ホストOSのフォルダと仮想環境のフォルダを同期するための設定です。
今回はnfsを使ってホストOSのフォルダを仮想環境の特定のフォルダで同期します。nfsが一番速いそうです。

```rb:Vagrantfile
Vagrant.configure(2) do |config|
  # …(略)
  config.vm.network "private_network", ip: "192.168.33.10"
  # …(略)
  config.vm.synced_folder "~/RubyMineProjects/FooProject/", "/home/vagrant/FooProject", nfs: true
  # …(略)
end  
```

ホストOSと仮想環境が通信できないといけないので、ホストOSとの通信用に固定IPを設定します。vagrant initした時に書き出された設定をコメントアウトするだけで基本的には大丈夫だと思います。

そして、同期するフォルダを指定しています。

### メモリの量の調整

デフォルトの設定だとメモリが少なすぎるのか、railsの起動が怪しかったので、固定でメモリを割り当てました。

```rb:Vagrantfile
Vagrant.configure(2) do |config|
  # …(略)
  config.vm.provider "virtualbox" do |vb|
    vb.memory = "2048"
  end
  # …(略)
end
```

### provisionの設定

起動する仮想環境の初期化に使う処理をshell scriptに分割して定義しました。

```rb:Vagrantfile
Vagrant.configure(2) do |config|
  # …(略)
  config.vm.provision :shell, path: "bootstrap.sh"
  config.vm.provision :shell, path: "install_rvm.sh"
  config.vm.provision :shell, path: "install_ruby.sh", args: '2.2.1'
  config.vm.provision :shell, path: "install_postgresql.sh", args: '9.3 database_name'
  # …(略)
end
```

これらをそれぞれ説明していきます。

#### bootstrap.sh

apt-getでインストールする処理をまとめようと思って、ここに定義しました。
最初はお試しで色々書いていたけれど、結局gitのみに落ち着きました。

```Bash:bootstrap.sh
#!/usr/bin/env bash

apt-get update
apt-get install -y git
```

#### install_rvm.sh

vagrantユーザー用としてrvmをインストールしたいので、`su - vagrant`でユーザーを変更してから実行しています。

```Bash:install_rvm.sh
#!/usr/bin/env bash

su - vagrant -c "curl -sSL https://get.rvm.io | bash -s $1"
```

#### install_ruby.sh

Vagrantfileで渡した引数のバージョンのRubyをインストールしています。
今回は現時点の最新である2.2.1を入れています。

```Bash:install_ruby.sh
#!/usr/bin/env bash

su - vagrant -c "rvm install $1"
su - vagrant -c "rvm use $1 --default"
```


#### install_postgresql.sh

Vagrantfileで渡した引数のバージョンのpostgresqlのインストールとデータベースの作成を行っています。
あとあと便利なので、vagrantユーザーをDB操作のためにスーパーユーザーに変更しています。

```Bash:install_postgresql.sh
#!/usr/bin/env bash

apt-get install -y postgresql-$1 postgresql-contrib-$1 libpq-dev
su - postgres -c "createuser --superuser vagrant"

# Railsプロジェクトで使うユーザーを新たに作成し、スーパーユーザーにしておく
# 必要であれば適当に修正
# su - vagrant -c "psql postgres -c \"CREATE USER foo WITH PASSWORD 'password'\""
# su - vagrant -c "psql postgres -c \"ALTER ROLE foo WITH SUPERUSER\""

su - vagrant -c "createdb -E UTF-8 -T template0 $2"
```

これで、起動してみましょう。

## 仮想環境を起動

```Bash:~/vm/vagrant_get_startedにて
vagrant up
```

これで、色々とインストールしながらUbuntuが起動します。

## 仮想環境で作業

仮想環境にSSH接続します。

```Bash
vagrant ssh
```

### bundle install と rake db:migrate

SSHでログイン後、synced_folderに設定しておいたRailsプロジェクトのフォルダ(ここではFooProject)に移動して、
bundle installとrake db:migrateをやっておきます。
rake db:migrateをする場合はconfig/database.ymlを編集しておいてください。

```Bash
cd FooProject
bundle install
bin/rake db:migrate
```

### railsをdevelopmentで起動

では、仮想環境でrailsを起動します。外部からアクセスできるように`-b 0.0.0.0`を忘れずに。

```Bash
bin/rails s -b 0.0.0.0
```

ホストOSで http://localhost:3000 にアクセスしてみて、railsアプリが起動していることを確認しましょう。

## vagrant shareを行う

では、この環境をvagrant shareを使って見られるようにしましょう。
`vagrant login` などは事前に済ませておいてください。

```Bash
vagrant share --http 3000
```

すると、以下のようなログがでてきます。

> ==> default: Detecting network information for machine...
    default: Local machine address: 192.168.33.10
    default: Local HTTP port: 3000
    default: Local HTTPS port: disabled
==> default: Checking authentication and authorization...
==> default: Creating Vagrant Share session...
    default: Share will be at: sparkling-badger-3831
==> default: Your Vagrant Share is running! Name: sparkling-badger-3831
==> default: URL: http://sparkling-badger-3831.vagrantshare.com

この例では、  http://sparkling-badger-3831.vagrantshare.com で見られるようになりました。
確認してみてください。確認作業が終わったら、Ctrl + Cで終了させましょう。

お疲れ様でした。