超初心者がDocker for MacでRuby + Rails + Mysqlの開発環境を構築

# はじめに
Dockerの知識が全くない超初心者がDockerでRailsの開発環境を作成できたので、嬉しさのあまり手順を忘れないよう記録しておきます。
<br>
わからなければ以下のサイトを参考にすれば良さそう！

- [Docker ドキュメント日本語化プロジェクト](http://docs.docker.jp/index.html)
- [Dockerfile リファレンス](http://docs.docker.jp/engine/reference/builder.html)
- [Compose ファイル・リファレンス](http://docs.docker.jp/compose/compose-file.html)


<br>
# Docker for Macのインストール

[Docker for Mac](https://docs.docker.com/docker-for-mac/)からインストーラをダウンロード。

私は「**Get Docker for Mac (stable)**」を選択しました。
ダウンロードした「Docker.dmg」を起動して、アプリケーションディレクトリに移動。
Dockerアプリをクリックして、OKボタン連打してたらできました。

<br>
# Dockerの起動
なんか勝手に起動してた。

**【Dockerの確認】**

```
$ docker --version
Docker version 1.13.0, build 49bf474
```

<br>
# Dockerイメージのダウンロード

今回使用するRubyとMySQLの２つのイメージをダウンロードします。


```
$ docker pull ruby:2.4.0
$ docker pull mysql:5.7
```

ダウンロードの際は、最新のバージョンでも「latest」とせずにバージョン指定した方がいいと思います。
<br>

**【ダウンロードしたイメージの確認】**

```
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ruby                2.4.0               3b80506f9634        7 days ago          676 MB
mysql               5.7                 f3694c67abdb        8 days ago          400 MB
```

最初「latest」でダウンロードしたら、Tagの部分が「latest」と表示されてバージョンがわからなくなった。


<br>
# Railsアプリケーション用のディレクトリを作成
このディレクトリで今後作業を行なっていく事になります。

```
$ mkdir ~/works/app_name
$ cd ~/works/app_name
```

<br>

# Dockerfileの作成
イメージを作る際の命令をまとめて記載できるらしい。

```
$ vi Dockerfile
```
<br>
Dockerfileに以下を記載

```
FROM ruby:2.4.0
ENV LANG C.UTF-8
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN gem install bundler
WORKDIR /tmp
ADD Gemfile Gemfile
ADD Gemfile.lock Gemfile.lock
RUN bundle install
ENV APP_HOME /app_name
RUN mkdir -p $APP_HOME
WORKDIR $APP_HOME
ADD . $APP_HOME
```
それぞれのコマンドの意味は[Dockerfile リファレンス](http://docs.docker.jp/engine/reference/builder.html)で確認できます。


<br>
# Gemfileの作成

```
$ vi Gemfile
```

現時点では、railsをインストールするだけのコマンドでOK！！

```
source 'https://rubygems.org'
gem 'rails'
```

<br>
# 空のGemfile.lockの作成
Dockerfile の構築には、空の Gemfile.lock が必要だそう。
なので、touchで作成

```
$ touch Gemfile.lock
```

<br>
# docker-compose.ymlの作成
複数のコンテナをうまいことするために定義するファイル。
今回「Rubyコンテナ」「MySQLコンテナ」２つのコンテナを作成するので必要。


```
$ vi docker-compose.yml
```

以下の内容を記載

```
version: '2'
services:
  db:
    image: mysql:5.7
    environment:
      - MYSQL_ROOT_PASSWORD=password
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/app_name
    ports:
      - "3000:3000"
    depends_on:
      - db
```


今回「db」と「web」という２つのサービスを定義しました。

詳しいことは[Compose ファイル・リファレンス](http://docs.docker.jp/compose/compose-file.html)で確認できます。

<br>
# コンテナにRailsアプリを作成

「docker-compose run」コマンドで「web」コンテナに「rails new」を行う。

```
$ docker-compose run web rails new . --force --database=mysql --skip-bundle
```

実行後、app_nameディレクトリの中にRailsのファイル群が作成されていると思います。



<br>
# Gemfileの変更

therubyracer の行のコメントを外す

```
gem 'therubyracer', platforms: :ruby
```

Gemfileの変更を適用するためには以下のコマンドを実行

```
$ docker-compose build
```

<br>
# config/database.ymlの設定

```
default: &default
  adapter: mysql2
  encoding: utf8
  pool: 5
  username: root
  password: password
  host: db
...
```

注意点は２つ

- passwordをdocker-compose.ymlの「MYSQL_ROOT_PASSWORD」と同じにする
- hostをdocker-compose.ymlの「depends_on」と同じにする

<br>
# コンテナの実行 & ブラウザ確認

コンテナを実行して、Rails Serverを起動します。
以下コマンドを実行したら、勝手にRails Serverも起動してくれます。

```
$ docker-compose up
```

**【コンテナの確認】**

```
$docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                    PORTS                    NAMES
6ae573faa39d        appname_web         "bundle exec rails..."   About an hour ago   Up About an hour          0.0.0.0:3000->3000/tcp   appname_web_1
8e5ba954f054        mysql:5.7           "docker-entrypoint..."   About an hour ago   Up About an hour          3306/tcp                 appname_db_1
```

<br>
最初はデータベースがないみたいなこと（Unknown database 'app_name_development'）を言われるので、別タブを開いて

```
$ docker-compose run web rake db:create
```

とすればOK!!!

あとは、ブラウザからlocalhost:3000を叩いたら...

<br>
# Railsアプリケーションを作成方法
コントローラーを作成。

```
$ docker-compose run web rails g controller welcome index
```

ローカルにcontrollerが作成されているはず。

基本的にRailsコマンドの最初に「docker-compose run web」をつけてやればコンテナ上で実行され、Mac側にも反映されます。

あとHOST側（自分のMacの方）の~/works/app_name/config/routes.rbに以下を記載。

```
root 'welcome#index'
```

この状態でlocalhost:3000を叩けば反映されているはずです。

あとはローカルでプログラムを書いていけば、勝手にコンテナ側に反映されるので開発できるのではないでしょうか！！！

<br>
# コンテナの停止と起動

今回の場合「Ctrl + c」でwebコンテナもMySQLコンテナも停止します。

```
$docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                       PORTS               NAMES
6ae573faa39d        appname_web         "bundle exec rails..."   About an hour ago   Exited (137) 5 seconds ago                       appname_web_1
8e5ba954f054        mysql:5.7           "docker-entrypoint..."   2 hours ago         Exited (137) 5 seconds ago                       appname_db_1
```

StatusがExitedになってたら止まってます。

<br>
起動は

```
$ docker-compose up
```
<br>
# コンテナとイメージの削除
コンテナの削除

```
$ docker rm {CONTAINER ID}
```

<br>
イメージの削除

```
$ docker rmi {IMAGE ID}
```

イメージの上にコンテナが作成されるので、コンテナから先に削除する方が良いそうです。

Gemfile変更後の「docker-compose build」で作成した後に見受けられる\<none\>というイメージを削除するのによく使用します。

<br>
# 注意点
- Gemfileを変更したら、buildでイメージ作成してから、コンテナ実行すること

```
$ docker-compose build
$ docker-compose up
```

この際、イメージに\<none\>ってのができます。
なんか邪魔なのでいつも削除してます。


<br>
# 最後に
私はDockerに関して全く知識はありません。
それでも、一応ですが開発環境の構築ができたので、それがもう嬉しくて嬉しくて。
勢いだけで書いてしまったので、わかりにくい点も多数あるとは思いますが、ご容赦ください。
あとはここにApacheを組み込みたいのですが、やり方が全くわからず。。

以上です。