dockerを用いたRubyOnRailsの開発環境構築

# Dockerfileについて
Dockerfileはdockerの新しいイメージを作成するために用いられるファイルです。

```dockerfile:Dockerfile
FROM ruby:2.3.6
RUN apt-get update -qq && apt-get install -y build-essential nodejs
RUN mkdir /app
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle install
COPY . /app
```

上記のFROM命令はruby2.3.6をベースとしたイメージ作成することを指しています。
後ほどImageをビルドする事によって、Dockerfileに記載されたコンテナ仮想環境の雛形が形成されます。

# Gemfile Gemfile.lockについて

```ruby:Gemfile
source 'https://rubygems.org'
gem 'rails', '5.0.0.1'
```
sourceにはgemのダウンロード元のURLを記載しておいきます。
そして、インストールするgemにはrailsの5.0.0.1を指定しています。

この、Gemfileがあるディレクトリで```bundle install```を実行するとGemfileに記載されているgemがインストールされる仕組みになっています。

次に、Gemfile.lockに関してですが、これは通常直接編集するものではなく、Gemfileを元に```bundle install```を行いgemがインストールされ、インストールされたgemがGemfile.lockに記載されます。

# docker-compose.ymlについて
docker-compose.ymlはdockerで複数のコンテナを設定に従ってまとめて起動するために使用します。
今回はrailsを実行するコンテナとmysqlサーバーを実行するコンテナの二つを起動する定義を記載する。

```yml:docker-compose.yml
version: '3'
services:
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/app
    ports:
      - 3000:3000
    depends_on:
      - db
    tty: true
    stdin_open: true
  db:
    image: mysql:5.7
    volumes:
      - db-volume:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
    ports:
      - "13306:3306"
volumes:
  db-volume:
```

# 開発環境構築

```terminal:ターミナル
mbp:railsqiita ippeikamimura$ ls -l
total 24
-rwxr-xr-x@ 1 ippeikamimura  staff  205  4  7 23:23 Dockerfile
-rwxr-xr-x@ 1 ippeikamimura  staff   53  4  7 23:28 Gemfile
-rwxr-xr-x@ 1 ippeikamimura  staff    0  2 13 08:33 Gemfile.lock
-rwxr-xr-x@ 1 ippeikamimura  staff  365  4  7 23:43 docker-compose.yml
```
上記の様に、自分の作業ディレクトリで４つの必要ファイルがあることを確認。
Dockerfile,Gemfile,docker-compose.ymlの設定ができたら下記のコマンドを実行.

```terminal:ターミナル
mbp:railsqiita ippeikamimura$ docker-compose run web rails new . --force --database=mysql
```
```docker-compose run web```は、docker-compose.ymlに定義したwebサービスのコンテナで後ろのコマンドを実行するコマンドです。すなわち、railsのコンテナ上で後ろのコマンドを実行する事を意味しています。

```rails new . --force --database=mysql```は```rails new .```で実行時のディレクトリ上に、新しいrailsプロジェクトファイルを作成します。

```rails nwe .```としているので、コンテナの作業ディレクトリである/app上にRailsのプロジェクトファイルが作成されます。ホストPCの現在のディレクトリは、/appにマウントされているため、コンテナでrailsのプロジェクトファイルが作成されると、ホストPCの現在のディレクトリにファイルが作成される。


```terminal:ターミナル
--force
```
は、既存ディレクトリの上書きを意味するオプション。

```terminal:ターミナル
--database=mysql
```
は、MySQLを使用する設定を入れるオプション。

```terminal:ターミナル
mbp:railsqiita ippeikamimura$ ls -l
total 64
-rwxr-xr-x@  1 ippeikamimura  staff   205  4  7 23:23 Dockerfile
-rwxr-xr-x@  1 ippeikamimura  staff  1748  4 11 14:44 Gemfile
-rwxr-xr-x@  1 ippeikamimura  staff  4459  4 11 14:44 Gemfile.lock
-rw-r--r--   1 ippeikamimura  staff   374  4 11 14:44 README.md
-rw-r--r--   1 ippeikamimura  staff   227  4 11 14:44 Rakefile
drwxr-xr-x  10 ippeikamimura  staff   320  4 11 14:44 app
drwxr-xr-x   8 ippeikamimura  staff   256  4 11 14:44 bin
drwxr-xr-x  14 ippeikamimura  staff   448  4 11 14:44 config
-rw-r--r--   1 ippeikamimura  staff   130  4 11 14:44 config.ru
drwxr-xr-x   3 ippeikamimura  staff    96  4 11 14:44 db
-rwxr-xr-x@  1 ippeikamimura  staff   365  4  7 23:43 docker-compose.yml
drwxr-xr-x   4 ippeikamimura  staff   128  4 11 14:44 lib
drwxr-xr-x   3 ippeikamimura  staff    96  4 11 14:44 log
drwxr-xr-x   9 ippeikamimura  staff   288  4 11 14:44 public
drwxr-xr-x   9 ippeikamimura  staff   288  4 11 14:44 test
drwxr-xr-x   4 ippeikamimura  staff   128  4 11 14:44 tmp
drwxr-xr-x   3 ippeikamimura  staff    96  4 11 14:44 vendor
```
実行が完了すると上記のrailsプロジェクトのファイルが作成されます。

次に、Gemfileに追記された、gemのインストールや作成されたファイルをコンテナ内に取り込むためにもう一度　buildを実行。

```terminal:ターミナル
mbp:railsqiita ippeikamimura$ docker-compose build
```
buildが完了したらrailsで使用するデータベースの設定ファイルを編集します。
ファイルはconfig/database.ymlになります。

```yml:config/database.yml
# MySQL. Versions 5.0 and up are supported.
#
# Install the MySQL driver
#   gem install mysql2
#
# Ensure the MySQL gem is defined in your Gemfile
#   gem 'mysql2'
#
# And be sure to use new-style password hashing:
#   http://dev.mysql.com/doc/refman/5.7/en/old-client.html
#
default: &default
  adapter: mysql2
  encoding: utf8
  pool: 5
  username: root
  password: password
  host: db

development:
  <<: *default
  database: app_development

# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
  <<: *default
  database: app_test

# As with config/secrets.yml, you never want to store sensitive information,
# like your database password, in your source code. If your source code is
# ever seen by anyone, they now have access to your database.
#
# Instead, provide the password as a unix environment variable when you boot
# the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database
# for a full rundown on how to provide these environment variables in a
# production deployment.
#
# On Heroku and other platform providers, you may have a full connection URL
# available as an environment variable. For example:
#
#   DATABASE_URL="mysql2://myuser:mypass@localhost/somedatabase"
#
# You can use this database configuration with:
#
#   production:
#     url: <%= ENV['DATABASE_URL'] %>
#
production:
  <<: *default
  database: app_production
  username: app
  password: <%= ENV['APP_DATABASE_PASSWORD'] %>
```
defaultのpasswordとhostをdocker-compose.ymlで設定した値に設定しなくてはいけませんん。
具体的には、passwordは、MYSQL_ROOT_PASSWORD環境変数の"password"
hostは、MySQLサーバのコンテナのサービス名である"db"。

設定が終わったら次のコマンドを実行します。

```terminal:ターミナル
mbp:railsqiita ippeikamimura$ docker-compose up -d
```
docker-compose up -dコマンドは、現在のディレクトリにあるdocker-compose.ymlに基いてコンテナ（仮想環境）を起動するコマンドです。

コンテナが起動しているかどうかは以下のコマンドで確認んができます。

```terminal:ターミナル
mbp:railsqiita ippeikamimura$ docker-compose ps
      Name                    Command               State           Ports
----------------------------------------------------------------------------------
railsqiita_db_1    docker-entrypoint.sh mysqld      Up      3306/tcp
railsqiita_web_1   bundle exec rails s -p 300 ...   Up      0.0.0.0:3000->3000/tcp
```
docker-compose psコマンドは、docker-compose.ymlに記述してあるサービスのコンテナ状況を表示。

しかし、起動はしましたがまだ開発環境用のデータベースが構築されていない状態なので次のコマンドで作る。

```terminal:ターミナル
mbp:railsqiita ippeikamimura$ docker-compose run web bundle exec rake db:create
```

```bundle exec```というのはGemfileで指定された環境で実行するという意味らしい。

```rake db:create```はDBがまだ存在しない場合に新規に作成してくれる。

これでrailsサーバーにアクセス可能な状態になったので、ブラウザで```localhost:3000```にアクセスすると、

<img width="1680" alt="スクリーンショット 2018-04-11 15.29.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/248142/241a478b-f098-5a4f-7134-6363115a1b26.png">

以上の様な画面が表示されれば無事に起動している。

# その他コマンド
```terminal:環境の停止
$ docker-compose stop
```
```terminal:環境の削除
$ docker-compose down
```
```terminal:Gemのインストール
$ docker-compose build
```