Ruby on Railsの開発環境をVagrantで構築する

[Ruby on Rails Tutorial](http://railstutorial.jp/ "Ruby on Rails Tutorial")を進めるための開発環境を構築することが目的です。

Vagrantを使う理由は、単純に勉強してみたいというのと、手軽に開発環境を作り直したりできると便利かなーと思ったためです。

基本的には以下の記事に沿って作業するのですが、筆者が初心者のため、分からない点は備忘録として追記していく流れです。
[Vagrant + VirtualBoxでつくるRails 5の環境構築](http://qiita.com/GenTamura84/items/0f97c117df6b1b6e8c0f "Vagrant + VirtualBoxでつくるRails 5の環境構築")

バージョンは以下の通りです。

- OS X El Capitan 10.11.6
- Vagrant 1.8.1
- Rails 4.2.2
- Ruby 2.3.１
- rbenv 1.0.0
- Node.js 4.5.0
- PostgreSQL 9.2.15

# VagrantとVirtualBoxのインストール

それぞれ以下からインストールします。

- [Vagrantをインストール](https://www.vagrantup.com/downloads.html "Vagrant")

- [VirtualBoxをインストール]
(https://www.virtualbox.org/wiki/Downloads "VirtualBox")

# Vagrantのセットアップ

作業ディレクトリを作成したら、移動してVagrantの初期化を行います。

```bash
$ cd your_workspace
$ vagrant init
```
`vagrant init`によりVagrantfileという仮想マシンの定義ファイルが生成されます。Vagrantfileに使用するOSやメモリを設定すると、それに従って仮想マシンが作成されます。今回は以下のように設定します。

```rb:Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
  # centos7を使用
  config.vm.box = "centos/7"
  # ホストマシンの3000番ポートをゲストOSの2000番ポートへフォワード¬
  config.vm.network "forwarded_port", guest: 2000, host: 3000
  config.vm.provider "virtualbox" do |vb|
   # VirtualBoxのGUI上の名前を設定
   vb.name = "centos7"
   # メモリは2048MBに設定
   vb.memory = "2048"
  end
end
```

`config.vm.box`にはBOXファイル名を指定します。BOXファイルとは仮想マシン起動の際にベースとなるイメージファイルです。以下から公式で配布されているBOXを検索し、利用することができます。ubuntu/trusty64のダウンロード数が多いようですが、今回はCentOS7を選択します。

[BOXの検索](https://atlas.hashicorp.com/boxes/search)

Vagrantの設定が終わったら、以下のコマンドでVirtualBox上に仮想マシンを作成します。

```bash
$ vagrant up
```

VirtualBox上に「centos7」という仮想マシンが新たに作成されると思います。仮想マシンにsshでログインします。


```bash
$ vagrant ssh
```

# Rubyのインストール

まずはパッケージをアップデートし、必要なパッケージをインストールします。

```bash
$ sudo yum -y update
$ sudo yum -y install git-all openssl-devel readline-devel sqlite gcc gcc-c++
```

次にrbenvでRubyをセットアップします。rbenvとはrubyのバージョン管理ツールで、複数のバージョンを開発環境に保持しながらプロジェクトごとに切り替えることができます。まだ開発経験が浅いので想像ではありますが、プロジェクトでバージョンを切り替えるシーンはありそうですし、便利なのかなーと。

```bash
$ git clone git://github.com/sstephenson/rbenv.git ~/.rbenv
$ git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
$ echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(rbenv init -)"' >> ~/.bashrc
$ echo 'gem: --no-ri --no-rdoc' > ~/.gemrc
$ exec $SHELL
```

上記では２つのリポジトリをcloneしています。rbenv本体とrubyのビルドに必要なruby-buildです。cloneが終わったらそれぞれパスを通します。
`echo 'eval "$(rbenv init -)"' >> ~/.bashrc`ではターミナル実行時に`rbenv init`を実行するよう指示しています。具体的に何をしているかは割愛しますが、rbenvを使うために必要です。
`echo 'gem: --no-ri --no-rdoc' > ~/.gemrc`は、rubyのモジュール群であるgemをインストールする際に不要なドキュメントのインストールを省略する設定であり、gemインストールの時間を短縮できるようです。
最後に`exec $SHELL`でシェルを再起動させます。

続けてRubyとBundlerをインストールします。Bundlerは先ほど少し出てきた、Gemというrubyのモジュール群の管理ツールです。

```bash
$ rbenv install 2.3.１
$ rbenv global 2.3.１
$ gem install bundler
```

# Node.jsのインストール

Railsのアプリケーションを動作させるにはNode.jsが必要ということでインストールします。どこで使われているのか具体的によくわかっていませんが・・・。

```bash
$ sudo rpm -Uvh https://rpm.nodesource.com/pub_4.x/el/7/x86_64/nodesource-release-el7-1.noarch.rpm
$ sudo yum -y install nodejs
```

# PostgreSQLのインストール

PostgreSQLをインストールします。

```bash
$ sudo rpm -ivh http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/pgdg-centos93-9.3-1.noarch.rpm
$ sudo yum -y install postgresql93-server postgresql-devel postgresql93-contrib
```

次にPostgreSQLのデータベースクラスタを新しく作成し、postgresqlをサービスに登録しておきます。データベースクラスタとは、1つのサーバで管理されるデータベースの集合です。また管理ユーザー(postgres)にパスワードを設定しておきます。

```bash
$ su -
$ /usr/pgsql-9.3/bin/postgresql93-setup initdb
$ systemctl start postgresql-9.3.service
$ systemctl enable postgresql-9.3.service
$ passwd postgres
Changing password for user postgres.
New password:  #パスワードを適当に設定する
Retype new password: 
$ exit
```

上記で設定したパスワードを入力して管理ユーザーとしてログインし、vagrantユーザーを追加します。

```bash
$ su - postgres
$ createuser vagrant -s
$ psql
postgres=# \password vagrant # vagrantユーザにパスワードを設定
Enter new password: # 何も入力せずにEnter
Enter it again: # 何も入力せずにEnter
postgres=# \q # psqlプロンプト終了
$ exit
```

# Railsプロジェクトの作成

ようやくRailsプロジェクトの作成です。作業ディレクトリを作成し、プロジェクトごとにGemをBundlerで管理していきます。

```bash
$ cd /vagrant
$ mkdir hello_app
$ cd hello_app
$ bundle init
```

`bundle init`により、Gemfileというファイルが生成されます。この中に使用するGemとバージョンを指定することで管理することが可能となります。以下のように指定します。

```bash:Gemfile
# A sample Gemfile
source "https://rubygems.org"

gem "rails", "4.2.2"
```

RailsをプロジェクトのGemとしてインストールします。インストール先は--pathで指定が可能です。vagrant環境の場合、ホストOSとの共有フォルダ内にインストールするとテスト等のコマンドの実行が遅くなるため、共有フォルダ外にインストールするとよいです。下は一例。

```bash
$ bundle install --path ~/bundler/hello_app/vendor/bundle
```

準備ができたので、以下のように`rails new`コマンドでアプリケーションを作成します。`bundle exec`は、このRailsプロジェクトのGemfileで指定された環境で実行するということです。途中でGemfileを上書きするか聞かれるので「Y」を入力します。

```bash
$ bundle exec rails new . --database=postgresql --skip-spring
...
Overwrite /vagrant/blog/Gemfile? (enter "h" for help) [Ynaqdh] Y
...
$ bin/rake db:create
```

`bin/rake db:create`で以下のようなエラーが出ました。

```bash
could not connect to server: No such file or directory
	Is the server running locally and accepting
	connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
```

詳しい意味はわかりませんが、`/var/run/postgresql`以下にファイルがないと言われています。以下のようにシンボリックリンクを作成すると解消しました。

```bash
$ sudo mkdir /var/run/postgresql
$ sudo ln -s /tmp/.s.PGSQL.5432 /var/run/postgresql/.s.PGSQL.5432
```

最後にローカルWebサーバーを立ち上げて、Mac側から接続します。以下のコマンドでサーバーを起動することができます。`-b`オプションではバインディングするIPアドレスを指定しており、0.0.0.0は、どのIPアドレスからでもOKということです。また`-p`オプションでポート番号を指定しています。

```bash
$ bin/rails server -b 0.0.0.0 -p 2000
```

ブラウザで`http://localhost:3000`を開き、以下のように表示がされれば成功です。

<img width="912" alt="rails.png" src="https://qiita-image-store.s3.amazonaws.com/0/121234/af308de6-0748-0ce0-2613-da0be41deeea.png">

# 今後の予定

[Ruby on Rails Tutorial](http://railstutorial.jp/ "Ruby on Rails Tutorial")の3章以降の学習記録をまとめていきたいなあと思っています。