Docker環境構築 [Rails & MySQL]

まだDockerに慣れていませんがなんとなくわかって来たので
`Dockerfile`と`docker-compose`作り方を簡単にまとめました。

#構成
```
sample_docker
  ├── docker-compose.yml
  ├── mysql
  │   ├── Dockerfile
  │   └── my.cnf
  ├── ruby
  │   └── Dockerfile
  └── Railsのアプリ名
      ├── Gemfile
      ├── Gemfile.lock
```
myslとrubyにDockerfileを作ります。
mysqlにはmy.cnfを作成します。
docker-compose.ymlもこの位置に作成します。

```
$ mkdir mysql
$ mkdir ruby
$ touch Dockerfile
$ touch Dockerfile
$ touch my.cnf
$ touch docker-compose.yml
$ rails new アプリ名
```



#Ruby

```Dockerfile:Dockerfile

FROM ruby:2.6.1

# 必要なパッケージのインストール
RUN apt-get update -qq && \
  apt-get install -y build-essential libpq-dev

# yarnのインストール
RUN apt-get update && apt-get install -y curl apt-transport-https wget && \
  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 && \
  apt-get update && apt-get install -y yarn

# Nodeのインストール
RUN curl -sL https://deb.nodesource.com/setup_13.x | bash - && \
  apt-get install -y nodejs

RUN mkdir /app
RUN cd /app
RUN gem install bundler
COPY ./Railsのアプリ名/ /app
WORKDIR /app

EXPOSE 3000

# 実行したいコマンド
CMD ["/bin/bash"]
```


#MySQL

```my.cnf
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_bin
default_authentication_plugin=mysql_native_password
[client]
default-character-set=utf8mb4
```

```Dockerfile:Dockerfile

FROM mysql:8.0

EXPOSE 3306

COPY ./my.cnf /etc/mysql/conf.d/my.cnf

CMD ["mysqld"]
```


#docker-compose.yml
```docker-compose.yml
version: '3'
services:
  rails:
      build:
        context: .
        dockerfile: ./ruby/Dockerfile
      environment:
        RAILS_ENV: "development"
        MYSQL_USER: "root"
        MYSQL_PASSWORD: "example_root_password"
        MYSQL_HOST: "mysql"
      command: "bundle exec rails server -p 3000 -b '0.0.0.0'"
      tty: true
      # コンテナを起動し続けるオプション
      stdin_open: true
      #  docker run -i に相当するものになります。
      depends_on:
      # serviceの起動順序を指定します。
        - mysql
      ports:
        - "3000:3000"
      # ホスト環境ポート:コンテナ内部ポート
      volumes:
      # ホスト環境とコンテナ環境のファイル等の永続化を行う際に利用します。
        - ./Railsのアプリ名:/app
        - bundle_data:/usr/local/bundle
  mysql:
      build:
        context: ./mysql
        dockerfile: Dockerfile
      environment:
        MYSQL_ROOT_PASSWORD: "example_root_password"
        MYSQL_USER: "sample_user"
        MYSQL_PASSWORD: "sample_password"
        MYSQL_DATABASE: "sample_rails_db"
        TZ: 'Asia/Tokyo'
      command: --default-authentication-plugin=mysql_native_password
      volumes:
        - ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf
        - mysql_data:/var/lib/mysql
      ports:
        - "33306:3306"

# データ永続化領域
volumes:
  bundle_data:
  mysql_data:
```

#[docker]iamgeの作成
docker-composeの直下で`docker-compose build`をしてiamgeの作成します。

```
$ docker-compose build
```
`$ docker images`で作成した`image`の確認ができます。




#作成したRailsアプリ

```/config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: <%= ENV['MYSQL_USER'] %>
  password: <%= ENV['MYSQL_PASSWORD'] %>
  host: <%= ENV['MYSQL_HOST'] %>

development:
  <<: *default
  database: Railsのアプリ名_development

# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
  <<: *default
  database: Railsのアプリ名_test

```
データベースの設定を変更します。
hostという部分で定義しているのはdocker-compose.ymlにて記述したserviceの名前になります。

```
$ docker-compose run --rm rails bundle install
```
`docker-compose run サービス名`コマンド実行できます。
--rm オプションはコンテナ終了時にコンテナを自動的に削除する為のオプションになります。

もし、エラーになりましたら`Gemfil.lock`中を空にしてください。

```
$ docker-compose run --rm rails yarn install
$ docker-compose run --rm rails bundle exec rails db:create db:migrate
```
データベース作成できましたらコンテナを立ち上げましょう。

```
$ docker-compose up -d 
```
`-d`はバックグラウンドでコンテナが立ち上がります。
`$ docker-compose down `でコンテナ停止できます。

#補足

Dockerfileをもとにimageを作成します。

```
docker build ./ -t [image名]
```

```
docker run [imge名]
```
コンテナが立ち上がります。コンテナを立ち上げると「Dockerfile」に書いてあるCMDのコマンドが実行される様になります。




`docker-compose.yml`があるディレクトリで
`docker-compose up -d`する。


**エラーなりやすいところ**

```
ERROR: Service 'rails' failed to build : The command '/bin/sh -c bundle install' returned a non-zero code: 7
```

`docker-compose up -d`をして
上のエラーになったらGemfile.lockを空にする

```
# コンテナ立ち上げる
docker-compose up -d
# コンテナ停止する
docker-compose down

# DBの作成
docker-compose up -d

#docker-compose execは起動しているものに対して実行するコマンド

docker-compose exec サービス名 bundle exec rails db:create
# DBのマイグレーション
docker-compose exec サービス名 bundle exec rails db:migrate
# DBのseed
docker-compose exec サービス名 bundle exec rails db:seed
```