dockerでrails+mysql環境を作ってみよう！

#dockerでrails+mysql環境を作ってみよう！

＊dockerとrubyはインストール済という前提です。


##GemfileとGemfile.lockを用意します。

今回はrailsバージョン6.0.0以上をインストールします。

```Gemfile:Gemfile
source 'https://rubygems.org'
gem 'rails', '6.0.0'
```

Gemfile.lockの中身は空です。




##Dockerfileを作成します。

```dockerfile:Dockerfile
FROM ruby:2.6

RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
    && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list

RUN apt-get update -qq && apt-get install -y build-essential nodejs yarn
RUN apt-get -y install imagemagick
RUN mkdir /app
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle install
COPY . /app
```

１行ずつ解説していきます。

FROMでベースイメージを取得します。オフィシャルやDocker Hubから取得できます。
１行目：`FROM ruby:2.6.5`

RUNでDebianパッケージリポジトリからYarnをインストールします。
https://classic.yarnpkg.com/en/docs/install#debian-stable
2行目：`RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
    && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list`

RUNでコマンドを実行してインストール可能なパッケージの「一覧」を更新して、nodejsをインストールします。
3行目：`RUN apt-get update -qq && apt-get install -y build-essential nodejs`

RUNでコマンドを実行して画像の操作に必要なソフトをインストールします。
4行目：`RUN apt-get -y install imagemagick`

RUNでコマンドを実行してdocker内にappディレクトリを作成
5行目：`RUN mkdir /app`

WORKDIRでdocker内にappディレクトリを作成
6行目`WORKDIR /app`

COPYでカレントデイレクトリにあるGemfileをdocker内にコピーする。
7行目：`COPY Gemfile /app/Gemfile`

COPYでカレントディレクトリにあるGemfile.lockをdocker内にコピーする。
8行目：`COPY Gemfile.lock /app/Gemfile.lock`

RUNでdocker上でbundle installを実行してgemをインストールする。
9行目:`RUN bundle install`

COPYでカレントディレクトリにある全てをコピーする。
10行目：`COPY . /app`

##docker-compose.ymlを作成します。

```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
volumes:
  db-volume:
```

docker-compose.ymlのざっくりとした解説

`web:` の部分がrailsコンテナの定義で、  `db:` の部分がmysqlサーバーコンテナの定義です。

`build: .` は、同じ階層にあるDockerfailを使用してビルドする（イメージ作成）

`command:` 以降の　`bundle exec rails s` でwebサーバー起動、 `-p 3000` でポート番号指定　`-b '0.0.0.0'` でバインドするIPアドレスの指定をしてます。（コンテナが持っている全てのネットワークインターフェイスにおいて、3000番ポートにアクセスが来た場合はrailsサーバーが起動するようになっています。）

`volumes:` の　`- .:/app` はローカルで変更したソースがdocker上で反映されるおまじない(即座に動作確認できます。)

`ports:` は、コンテナのポート解放（左側が公開するポート番号で、右側がコンテナ内部の転送先ポート番号）

`depends_on:` で `db` を指定しているので先にDBサーバーが起動します。

`tty: true
stdin_open: true` はpry使用のためのおまじない（pryは気になったら調べてみてください、便利です）

`image: mysql:5.7` 指定したmysqlを使用します。

`volumes: db-volume:` でPC上にdb-volumeという名前でデータ保存領域が作成され、`volumes: - db-volume:/var/lib/mysql`　でマウントしていています（これがないとコンテナが削除された場合にデータが消えてしまいます。）

`environment: MYSQL_ROOT_PASSWORD: password` は環境変数設定で、mysqlのrootのパスワードを設定しています。

ちなみに、 `web`と`db`がサービス名です。railsからmysqlに接続する時のhostはdbといった感じになります。

##やっと環境構築
任意のディレクトリ内にこれら４っつのファイルを集めましょう。

ターミナル上でそのディレクトリまで移動して、以下のコマンドを実行します。
`docker-compose run web rails new . --force --database=mysql`

<img width="451" alt="スクリーンショット 2020-05-07 23.31.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598005/c9369fc7-a739-8393-815e-43dcc3c88005.png">
クラッカーと、ケーキが出たら成功です。結構時間かかります。

railsプロジェクトが作成されたので、それらをコンテナに取り込むために以下のコマンドを実行します。
`docker-compose build`

終わったら以下を編集します。

```yml:database.yml
default: &default　
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password　　//ここが環境変数設定で指定したパスワードです。
  host: db             //ここがDBのサービス名です。
```

コンテナを起動します。-dオプションでバックグラウンド起動
`docker-compose up -d`

両方のサーバーが起動したはずです。確認するには、以下のコマンドを実行します。
`docker-compose ps`

```
       Name                     Command               State           Ports         
------------------------------------------------------------------------------------
dockerrails6_db_1    docker-entrypoint.sh mysqld      Up      3306/tcp, 33060/tcp   
dockerrails6_web_1   bundle exec rails s -p 300 ...   Up      0.0.0.0:3000->3000/tcp
```
stateがupになっていると起動中です。

ちなみに停止する場合は、以下のコマンドです。
`docker-compose stop`

停止の場合

```
       Name                     Command               State    Ports
--------------------------------------------------------------------
dockerrails6_db_1    docker-entrypoint.sh mysqld      Exit 0        
dockerrails6_web_1   bundle exec rails s -p 300 ...   Exit 1  
```

開発環境用のDBを作成します。コンテナを起動したまま以下のコマンドを実行します。
`docker-compose run web bundle exec rake db:create`

終わったら、
http://localhost:3000
にブラウザでアクセスすると、、、

<img width="878" alt="スクリーンショット 2020-05-07 23.36.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598005/f3ec5fb0-0232-a8ac-7a34-962d922c379c.png">

この画面が出れば成功です。お疲れ様でした。