Docker + rails 開発環境構築

##はじめに
新しいwebサービスを開発することになり、**Dockerを利用してrailsの開発環境を構築**したので、Qiitaに残しておこうと思います。
###対象
Dockerを使ってみたい人。Dockerでrailsの開発環境を構築してみたい人。
##環境
ruby:2.6.2
mysql:5.7
##手順
1. Githubでリポジトリを作成して、クローンする
2. Rails環境テンプレートの内容（）をクローンしたフォルダにコピー
3. docker-compose.ymlファイルを修正する(Dockerfile)
3-1. %%project_name%%をプロジェクト名称(英語)に書き換える
3-2. contariner_nameをプロジェクト名称を含んだ形に変更 (_は使わない)
3-3. mysqlの@の後ろを3-2で変更した内容に揃える
4. docker-compose run の rails new を実行してRailsをインストール
docker-compose run --rm rails rails new . --force --database=mysql --skip-bundle
5. dockerフォルダの中のGemfile, Gemfile.lockをapplication配下にコピー
6. dockerフォルダの中のunicorn.rbをapplication/config配下にコピー
7. docker-compose build --no-cache
8. docker-compose up
※ ここでエラーがでていなければ成功



##実践

###1:Githubでリポジトリを作成して、クローンする

Github( https://github.com )で新しくリポジトリを作る。
<img width="1439" alt="スクリーンショット 2019-04-23 17.21.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365406/4e3fda61-0d30-1bc4-347e-b16c800bb037.png">

次にクローン。
<img width="1434" alt="スクリーンショット 2019-04-23 17.25.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365406/fdd11927-8373-76ad-6c94-6eac8295184f.png">

コピーして、ターミナル上で作りたいフォルダに移動し以下のコマンドを打つ。

```
$ git clone https://github.com/horikazu0715/kikasetene.git
```

###2:クローンしたフォルダにRails環境テンプレートの内容をコピー
ここで、Rails環境テンプレートの内容とは、
<img width="293" alt="スクリーンショット 2019-04-23 17.41.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365406/ed99efac-9a9c-8780-eb5a-1b69fe110e42.png">
のようなものになる。
dockerファルダ、docker-compose.yml、README.mdをクローンしたフォルダにコピーする。

###3: docker-compose.yml、Dockerfileファイルを修正する
未編集のdocker-compose.yml、Dockerfileファイルは以下の通り。
**docker-compose.yml**

```docker-compose.yml
version: '3'
services:
  rails:
    container_name: rails
    build:
      context: ./
      dockerfile: ./docker/containers/rails/Dockerfile
    command: bundle exec unicorn -p 80 -c /var/project/%%project_name%%/config/unicorn.rb
    ports:
      - '80:80'
    environment:
      RAILS_ENV: development
      MYSQL_ROOT_PASSWORD: 'root'
      DATABASE_URL: 'mysql2://root:root@mysql:3306'
    depends_on:
      - db
    volumes:
      - ./application:/var/project/%%project_name%%
    links:
      - db
  db:
    container_name: mysql
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: 'root'
    ports:
      - '3306:3306'
    volumes:
      - ./docker/containers_data/mysql:/var/lib/mysql
```
**docker/containers/rails/Dockerfile**

```
FROM ruby:2.6.2

RUN apt-get update && \
    apt-get install -y nodejs \
                       mysql-client \
                       --no-install-recommends && \
    rm -rf /var/lib/apt/lists/*

RUN mkdir /var/lib/mysql && touch /var/lib/mysql/mysql.sock
ADD ./docker/containers/mysql/my.cnf /etc/

RUN mkdir /var/project
RUN mkdir /var/project/%%project_name%%
WORKDIR /var/project/%%project_name%%

COPY ./docker/containers/rails/Gemfile /var/project/%%project_name%%/Gemfile
COPY ./docker/containers/rails/Gemfile.lock /var/project/%%project_name%%/Gemfile.lock

RUN bundle install

COPY ./application /var/project/%%project_name%%
COPY ./docker/containers/rails/unicorn.rb /var/project/%%project_name%%/config/unicorn.rb

EXPOSE 80
```

上記のコードの ```%%project_name%%``` といくつかの箇所を修正する。
**docker-compose.yml**

```docker-compose.yml
version: '3'
services:
  rails:
    #rails→rails-kikasetene.ここで.や_を使用するとエラーになる。使える記号は-のみ。
    container_name: rails-kikasetene
    build:
      context: ./
      dockerfile: ./docker/containers/rails/Dockerfile
    command: bundle exec unicorn -p 80 -c /var/project/kikasetene/config/unicorn.rb
    ports:
      - '80:80'
    environment:
      RAILS_ENV: development
      MYSQL_ROOT_PASSWORD: 'root'
      #@mysql→@mysql-kikasetene
      DATABASE_URL: 'mysql2://root:root@mysql-kikasetene:3306'
    depends_on:
      - db
    volumes:
      - ./application:/var/project/kikasetene
    links:
      - db
  db:
    #mysql→mysql-kikasetene
    container_name: mysql-kikasetene
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: 'root'
    ports:
      - '3306:3306'
    volumes:
      - ./docker/containers_data/mysql:/var/lib/mysql
```

**docker/containers/rails/Dockerfile**
```%%project_name%%``` を編集

```
FROM ruby:2.6.2

RUN apt-get update && \
    apt-get install -y nodejs \
                       mysql-client \
                       --no-install-recommends && \
    rm -rf /var/lib/apt/lists/*

RUN mkdir /var/lib/mysql && touch /var/lib/mysql/mysql.sock
ADD ./docker/containers/mysql/my.cnf /etc/

RUN mkdir /var/project
RUN mkdir /var/project/kikasetene
WORKDIR /var/project/kikasetene

COPY ./docker/containers/rails/Gemfile /var/project/kikasetene/Gemfile
COPY ./docker/containers/rails/Gemfile.lock /var/project/kikasetene/Gemfile.lock

RUN bundle install

COPY ./application /var/project/kikasetene
COPY ./docker/containers/rails/unicorn.rb /var/project/kikasetene/config/unicorn.rb

EXPOSE 80
```
###4:docker-compose run の rails new を実行してRailsをインストール

３の編集が終われば、クローンしたフォルダ下にapplicationフォルダを作成する。

```
$ mkdir application
```
次に、rails newをターミナル上で実行する。

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

成功すれば、application配下はこのようになる。
<img width="302" alt="スクリーンショット 2019-04-23 18.06.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365406/f6777384-92bc-0209-63f9-e488b87a814f.png">
###5:dockerフォルダの中のGemfile, Gemfile.lockをapplication配下にコピー
２の手順でクローンしたフォルダ配下にコピーしたGemfile, Gemfile.lockをコピーする。
application配下にはすでにGemfileがあるはずなので、Gemfileはdockerフォルダ内の内容を上書きコピーし、Gemfile.lockはapplicationに存在しないため、コピーしそのまま貼り付ける。

（今回はすでに用意しているdockerフォルダ内のGemfileを利用したが、そのまま使用、または自分でカスタマイズでもいい）

###6:dockerフォルダの中のunicorn.rbをapplication/config配下にコピー
今回はunicornを使用するので、あらかじめ用意しておいた```unicorn.rb```をapplication/config配下にコピーする。

```application/config/unicorn.rb
rails_root = ENV['RAILS_ROOT']
worker_processes Integer(ENV['WEB_CONCURRENCY'] || 1)
timeout 300 # タイムアウト
preload_app true # 更新時ダウンタイム無し

# listen 8080
listen "#{rails_root}/tmp/unicorn.sock"
pid "#{rails_root}/tmp/unicorn.pid"

# ログの出力
stderr_path File.expand_path('log/unicorn.log', rails_root)
stdout_path File.expand_path('log/unicorn.log', rails_root)
```

###7:docker-compose build --no-cache
ここまで完了すれば、buildする。
末に、```--no-cache``` をつけることで以前のbuildの影響なしに０の状態からbuildする。

```
docker-compose build --no-cache
```

<img width="760" alt="スクリーンショット 2019-04-23 18.28.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365406/cf352494-aecb-6245-64f9-7465262ba14d.png">
上のように、Successfully builtと出れば成功。

###8:docker-compose up
次に```docker-compose up```でコンテナを起動する。

```
$ docker-compose up
```

<img width="913" alt="スクリーンショット 2019-04-23 18.31.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365406/b75912fd-e643-b82a-4034-7034c20b39bf.png">

ターミナルが上のような表示になれば成功。

ちなみに```docker-compose ps ```というコマンドでコンテナの起動状態を確認することができる。
<img width="678" alt="スクリーンショット 2019-04-23 19.14.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365406/a0cec203-e154-f78f-12fa-3e99a117fc72.png">


ここまでエラーが出ずに進めることができれば、開発環境構築は完了となる。
ブラウザでlocalhostとうち、以下の画面になればok!!

<img width="1240" alt="スクリーンショット 2019-04-23 18.36.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365406/ef6fafe0-67ee-2d0c-62fe-c06e19319eb6.png">

localhostを開き、データベースがないというエラーが出る場合がある。
Sequel Proで```kikasetene_development```というデータベースを作成するとエラーが消え、上のような画面に変わった。
Sequel Pro(https://www.sequelpro.com/)

##さいごに
Dockerでrailsの開発環境構築するということで、エラーなくスムーズにいけば１５分ほどで上記の全ての工程をクリアできますが、僕の場合は少し手こずりました。

この作業はサービス開発するたびに必要になるので、なれておきたいところですね〜。