【Docker】Ruby2.6.5とRails6.0.0とmysql  DockerComposeで環境構築

#はじめに
Ruby2.6.5とRails6.0.0とmysqlでDockerComposeで環境構築をしたので記録として記事を書きます。
もし誰かのお役に立てたら幸いです。

Docker環境でアプリケーション開発する手順

１、RailsのDockerfileを作成してDockerをbuild
２、DockerCompose.ymlを作成しコンテナを作る
３、Rails のセットアップ
４、データベースを作成する

#開発環境
Docker version 20.10.0
docker-compose version 1.27.4




#１、RailsのDockerfile作成

新しいデレクトリを作成します。
今回はデレクトリ名をexamとしてます。

```:ターミナル
mkdir [新規デレクトリ名]
cd [新規デレクトリ名]
```

###Dockerfile
新規で作ったデレクトリに「Dockerfile」をいう名前でDockerファイルを作成します。
VSコードをお使いの方は`code Dockerfile`でターミナルから直接ファイルの作成＆移動をしてくれます。
もちろんディレクトリを呼び込んでファイルを作成しても大丈夫です。

```Dockerfile:exam/Dockerfile
FROM ruby:2.6.5
RUN apt-get update && apt-get install -y \
    build-essential \
    libpq-dev \
    nodejs\
    yarn \
    vim 

WORKDIR /新規デレクトリ名
COPY Gemfile Gemfile.lock /新規デレクトリ名/
RUN bundle install
```



Gemファイルを作成する

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

Gemfileにファイルを持ってくるソースとrailsのバージョンを記述します。



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



Dockerを建てます。

```:ターミナル
docker build .
.
.
.
Installing rails 6.1.2.1
Bundle complete! 1 Gemfile dependency, 42 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
Removing intermediate container 06448279a57c
 ---> c21a3ec7e3a4
Successfully built c21a3ec7e3a4

#イメージが出来てるか調べる事も出来ます。
docker images 

#もし使っていないイメージがあれば下記のコマンドで削除できます。
docker rmi [IMAGE ID]
```






#2、DockerCompose.ymlを作成しコンテナを作る

dockerc-compose.ymlファイルを作成し記述する

```:ターミナル
code docker-compose.yml
```

これで新しい`docker-compose.yml`が作成されます。


```docker-compose.yml
version: '3'

services:
  web:
    build: .
    ports:
      - 3000:3000
    volumes:
      - '.:/[作成したディレクトリ名]'
    tty: true
    stdin_open: true
```

`dockerc-ompose.yml`の確認をして実行します

```:ターミナル
#確認します
cat docker-compose.yml

#実行します
docker-compose up -d


#コンテナが動いてる事を確認します。
docker ps
docker-compose ps

#コンテナの中に入ります。
docker-compose exec web bash
```



#3、Rails のセットアップ
Railsの環境でコンテナができのでその中で`rails new`をしてセットアップして行きます。

```:ターミナル
#新しいrailsを作ります
rails new . --force --database=mysql --skip-bundle

#一度コンテナから抜けます
exit

#今のコンテナとイメージを削除します
docker-compose down

#Downになってるか確認します
docker ps

#新しいイメージでコンテナを建てます
docker-compose up --build -d

#確認します
docker-compose ps

#コンテナに入ります
docker-compose exec web bash

#Railsを起動します
rails s -b 0.0.0.0　#現段階ではエラーが出ます
```

現段階ではデータベースの記述を Dockerfileに記述していないので、mysql2のエラーが出ると思います。
下記の対応を試して下さい。

【Docker】エラー　Could not find gem 'mysql2 (~> 0.5)' in any of the gem sources listed in your Gemfile
https://qiita.com/AKI3/items/8009b5218be0ad67b6b7


エラーが解決したら`rails s -b 0.0.0.0`でサーバーが立ち上がります。
実際に`localhost:3000`でアクセスします。
しかしこのままではデータベースが無いのでエラー画面が表示されます。
![スクリーンショット 2021-02-15 17.02.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/769854/783507e1-7445-183b-ac2c-01ae491f3f90.png)





#4、データベースを作成する。

ローカルであれば`rails db:create`をするとデータベースを作れるのですが、コンテナ内では現状の設定では作れません。
Dockerではサービス（環境）ごとにコンテナを作る事が推奨されております。
今回であればRubyとmysqlのコンテナを別々に作り、それぞれのコンテナどうしを接続する必要があります。
その為、detabase.ymlの設定ファイルを編集して正しい指定をし、docker-compose.ymlの設定ファイルの編集します。

####先ずdetabase.ymlを編集します。

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

development:
  <<: *default
  database: 新規デレクトリ名_development
  username: root
  password:

省略
```


####次にdocker-compose.ymlを編集します。


```docker-compose.yml
version: '3'

volumes:
  db-data:

services:
  web:
    build: .
    ports:
      - 3000:3000
    volumes:
      - '.:/新規デレクトリ名'
    environment:
      - 'MYSQL_ROOT_PASSWORD=1'
    tty: true
    stdin_open: true
    depends_on:
      - db
    links:
      - db

  db:
    image: mysql:8
    volumes:
      - 'db-data:/var/lib/mysql'
    # このenvironmentはテスト環境でのみ使用可能
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: 1

    # command: bundle exec rails s -p 3000 -b '0.0.0.0' #こちらはお好みで
```

docker-compose.ymlを編集したので新しくコンテナを作ります。
今回はweb(Raisl)とdb(mysql)2つのコンテナを作る事になります。


```
#再びコンテナを建てます
docker-compose up -d

#upになってるか確認します
docker-compose ps

#コンテナに入ります
docker-compose exec web bash

#データベースを作成します
rails db:create #現段階ではエラーが出ます
```


Rails側のコンテナ内で作業を進めていきます。
先程作ったRails側のコンテナとmysql側のコンテナがしっかり繋がっていれば`rails db:create`のコマンドは通りますが、現段階では下記のエラーが発生します。

```
Mysql2::Error::ConnectionError: Plugin caching_sha2_password could not be loaded: /usr/lib/x86_64-linux-gnu/mariadb19/plugin/caching_sha2_password.so: cannot open shared object file: No such file or directory
```

これはwebコンテナが mysql 8.0 の`caching_sha2_password`が認証方式に対応していないためだそうです。

詳しくは、こちらの記事で解決できます。
https://blog.toshimaru.net/rails-on-docker-compose/

コマンドだけこちらに記載します。

```:ターミナル
 #データベース側のコンテナに入る
docker-compose exec db bash

 #mysqlを操作する
mysql -u root

 #ユーザー一覧とその認証方式が閲覧
select User,Host,plugin from mysql.user;

 #root@% のユーザー設定を変更
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '';

 #再度ユーザー一覧とその認証方式が閲覧
select User,Host,plugin from mysql.user;
```

エラーが解決できたら最後サーバーを立ち上げます。

```:ターミナル
rails s -b 0.0.0.0

=> Booting Puma
=> Rails 6.1.2.1 application starting in development 
=> Run `bin/rails server --help` for more startup options
Puma starting in single mode...
* Puma version: 5.2.1 (ruby 2.6.5-p114) ("Fettisdagsbulle")
*  Min threads: 5
*  Max threads: 5
*  Environment: development
*          PID: 29
* Listening on http://0.0.0.0:3000
Use Ctrl-C to stop
.
.
.
省略
```

出来ました！
`localhost3000`にアクセスすると-Yay! You’re on Rails!-の画面が表示されます。
![スクリーンショット 2021-02-17 17.16.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/769854/fce10ff7-e1cf-842a-398d-53c383ceb62a.png)


#最後に
手探りの対処療法でサーバー起動まで達成しましので、これからも継続学習が必要です。
なんとか環境構築まで至りましたが、Dockerについて完全に理解できておりません、万が一情報が間違っている場合ご指摘していただけると幸いです。

エンジニア初学者ですが、同じ様に悩んでる方々の助けになればと思い記事を投稿しております。
万が一情報が間違っている場合ご指摘していただけると幸いです。


#参考

今回Udemyの教材とやっすんのエンジニア大学を主に参考にさせていただきました。
https://www.udemy.com/course/aidocker/
https://github.com/yassun-youtube/docker-compose-sample/blob/master/docker-compose.yml