docker　ruby(2.6.5)・mysql(5.6.47)・rails(6.0.0)の開発環境構築

## 概要
dockerを開発環境に使ってアプリを作成しました。初めてdockerを使ってなかなかうまく動かなかったので動いたものをアウトプットを含めて共有します。また、deviseの導入も行って開発も少々行っていきたいと思います。


## dockerの導入
ベースはdockerの公式サイトにRailsとPostgresSQLのdocker-composeの使い方が乗っていたのでそちらを参考にします。

dockerの公式サイト
https://docs.docker.com/compose/rails/

ただ、rails6.0.0からはwebpackerが標準になったことにより6.0.0を使う際には修正が必要です。また、今回はmysqlを使うのでそちらも変更していきます。

#### アプリのディレクトリ作成

```ターミナル.
mkdir sampleapp
```

#### アプリのディレクトリに移動

```ターミナル.
cd sampleapp 
```

#### dockerfileの生成

```ターミナル.
touch dockerfile
```

#### dockerfileの編集
作成したdockerfileを以下のように編集します。

```dockerfile.
FROM ruby:2.6.5

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 libpq-dev nodejs yarn

RUN mkdir /myapp

WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp

COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

CMD ["rails", "server", "-b", "0.0.0.0"]
```

#### 公式の以下の点を修正しました。
1.rubyのバージョンを変更。
2.webpackerが標準になったことにより、必要になったyarnのインストールを行う。

>FROM ruby:2.6.5

>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 libpq-dev nodejs yarn


#### entrypoint.shの生成

```
 touch entrypoint.sh
```


#### entrypoint.shの編集
作成したentrypoint.shを編集します。こちらはdockerの公式サイトの通りになります。

```entrypoint.sh
#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
```

#### docker-compose.ymlの生成

```
touch docker-compose.yml
```

#### docker-compose.ymlの編集
生成したファイルを以下のように編集します。


```docker-compose.yml
version: "3"
services:
  db:
    image: mysql:5.6.47
    environment:
        MYSQL_ROOT_PASSWORD: password
        MYSQL_DATABASE: root
    ports:
        - "3306:3306"
    volumes:
        - ./db/mysql/volumes:/var/lib/mysql
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    stdin_open: true
    tty: true
    volumes:
      - .:/myapp
      - gem_data:/usr/local/bundle
    ports:
      - "3000:3000"
    depends_on:
      - db
volumes:
  mysql_data:
  gem_data:
```


公式のリファレンスではpostgresqlを使っているためmysqlにしています。

>services:
  db:
    image: mysql:5.6.47
    environment:
        MYSQL_USER: root
        MYSQL_ROOT_PASSWORD: password
    ports:
        - "3306:3306"
    volumes:
        - ./db/mysql/volumes:/var/lib/mysql


アプリ製作中にbinding.pryを使えるように以下を追加しています。

> stdin_open: true
  tty: true


データとgemを永続化するために以下の記述を追加しています。

>volumes:
  mysql_data:
  gem_data:

#### Gemfileの生成

```ターミナル.
touch Gemfile
```

生成したファイルを以下のように編集します。

```Gemfile.
source 'https://rubygems.org'
gem 'rails', '~>6'
```

#### 空のGemfile.lockを生成
```ターミナル.
touch Gemfile.lock
```

#### railsのプロジェクトを作成

```ターミナル.
docker-compose run web rails new . --force -d mysql
```

#### docker-composeをbuildする

```ターミナル.
docker-compose build
```

#### database.ymlの修正

```config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password 
  host: db
```

#### docker-composeの再起動
docker-composeを一旦downさせてバックグラウンドで起動するようにコマンドを入力

```ターミナル.
docker-compose down
docker-compose up -d
```

#### データベースの作成

```ターミナル.
docker-compose run web bundle exec rails db:create
```

ここまできたらlocalhost:3000/にアクセスしてみましょう。以下の画面が表示されるはずです。

![スクリーンショット 2020-12-08 16.14.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/741390/109ef844-26a6-83f0-a692-76726828ca76.png)



## deviseを用いた簡単なアプリの開発
ここからはアプリ開発の入り口をやっていきます。

#### コントローラーとビューを生成
トップページを表示するためにposts(投稿)コントローラーとindexのビューを生成します

```ターミナル.
docker-compose run web rails g controller posts index
```

生成したらルーティングを設定します。routes.rbを以下のように編集しましょう。

```config/routes.rb
Rails.application.routes.draw do
  root 'posts#index'
  get 'posts/index'
end
```
この時点でlocalhost:3000/にアクセスすると以下のような画面になっています。
先ほど作成したpostsのindex(view)が表示されていることがわかります。

![スクリーンショット 2020-12-08 16.19.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/741390/d030a0ca-fd05-0e51-25e8-2b550d3a78a2.png)

#### deviseの導入
gemファイルの一番したにdeviseを記述します。

```Gemfile.
gem 'devise'
```

#### bundle installを行う
dockerを利用している場合には通常行っているコマンドに "docker-compose run web"をつける必要があります。

```ターミナル.
docker-compose run web bundle install
```

#### dockerの再起動
gemを新たに追加したためdocker-composeの再起動を行います。

```ターミナル.
docker-compose down
docker-compose up -d
```

あとは通常のdeviseと同じ作業を行っていきます。
それぞれのコマンドを入力していきます。

```ターミナル.
docker-compose run web rails g devise:install
docker-compose run web rails g devise user
docker-compose run web rails db:migrate
docker-compose run web rails g devise:views
```

ここまできたら再度dockerを再起動させます

```ターミナル.
docker-compose down
docker-compose up -d
```

ここまででdeviseの導入全てが終わったためあとはposts/index.html.erbに以下を記述してみましょう。

```posts/index.html.erb
<%=link_to "ログイン", new_user_session_path %>
```

ここまででlocalhost:3000/にアクセスするとログインボタンが表示され、押すとログイン画面に遷移します。
これでdockerを使ってdeviseを動かすところまで行えました。
ここからはそれぞれのオリジナルアプリの仕様に従って開発ができると思います。
トップページ
![スクリーンショット 2020-12-08 16.30.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/741390/a03ae4fa-c6fc-3f84-a7de-25470b67fc41.png)

ログインページ
![スクリーンショット 2020-12-08 16.33.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/741390/4fa2d851-9faa-778a-3598-7e3156e745e9.png)