【M1Mac】DockerでRails開発環境構築

# Rails開発環境構築手順
**前提：Dockerがインストールされていること**
[【初心者】Dockerのインストールと仕組みについて](https://qiita.com/rexid/items/dd3db91b612f0c70097c)
### 1. 空のアプリケーションディレクトリを作成
- 今回はDocumentsディレクトリ配下に`rails_docker`ディレクトリを作成
　※ディレクトリ名は任意
```terminal
$ mkdir ~/Documents/rails_docker
$ cd ~/Documents/rails_docker
```


### 2. 作成したディレクトリ配下に空の`src`ディレクトリを用意し、更にその配下に`Gemfile`を用意し編集する
```terminal
$ mkdir src
$ cd ~/Documents/rails_docker/src
$ touch Gemfile
```
- railsのgemを使って「rails new」コマンドを打つとrailsのファイルの雛形を作ってくれる
※エディタは*Visual Studio Code*を使用
```Gemfile:Gemfile
source 'https://rubygems.org'

gem 'rails', '~> 6.1.0'
```

### 3. srcディレクトリと同じ階層に`Dockerfile`と`docker-compose.yml`を用意

```terminal
$ cd ../
$ touch Dockerfile
$ touch docker-compose.yml
```

**【Dockerファイルとは】**
- 新規にDockerイメージを作成するための手順を記したテキストファイル

:::note warn
Gemfileに記載するRubyのバージョンはDockerfileに記載したバージョン（今回の例だと2.7.5）に合わせる
:::

```Dockerfile:Dockerfile
# Rubyの2.7.5を使用
FROM ruby:2.7.5

# 必要なライブラリをインストール
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
  # nodejsとyarnをインストールするために必要なライブラリのアップデート関連
  && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \
  && apt-get update -qq \
  && apt-get install -y nodejs yarn # nodejsとyarnをインストール

# 今回は作業ディレクトリを/appとする
WORKDIR /app

# ローカルの./src（railsのソースコードを入れる場所）以下のソースコードを/app配下にコピー
COPY ./src /app

# RubyのGemfileを一括インストール
RUN bundle config --local set path 'vendor/bundle' \
  && bundle install
```

**【Docker Composeとは】**
- `docker-compose.yml`というファイルに記述して複数のコンテナを一括で管理できる
    - アプリケーションは複数のコンテナが必要
    - 個別に管理することなく、連携も簡単
```docker-compose.yml
version: '3'
# 2つのサービスを定義
services:
  # MySQL
  db:
    # MySQLのバージョンを指定
    image: mysql:8.0
    # MySQL8.0から認証形式が変わっており、その認証形式の設定（行っていないとエラーになる）
    command: --default-authentication-plugin=mysql_native_password
    volumes:
      # コロンより左側がローカルのディレクトリ、右側がDocker側のディレクトリ（同期）
      - ./src/db/mysql_data:/var/lib/mysql
    environment:
      # 環境変数
      MYSQL_ROOT_PASSWORD: password
  # Rails
  web:
    # カレントディレクトリのDockerfileを参照
    build: .
    # railsのサーバを起動。ポート番号は3000番で、バインドは0.0.0.0
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      # ローカルのsrcディレクトリ以下のファイルをDockerコンテナ内のappに同期
      - ./src:/app
    ports:
      # ローカルの3000番ポートをDocker側の3000番ポートに接続
      - "3000:3000"
    depends_on:
      # webはdbサービスに依存している（これを書かない場合、RailsからMySQLに接続する時にIPアドレスを直接しなければならない）
      - db
```
    

### 4. `rails new`をしてRailsの雛形を作成

```terminal
$ docker-compose run web rails new . --force --database=mysql
```
- docker-compose.ymlに記載されたwebに対して行う
- 実行時間少しかかる
    - srcディレクトリ配下にrailsの雛形が作成される
- 実行が完了するとsrcの配下にGemfileが新しく作成され、内容も追記されて根本的に変わっている



### 5. イメージをBuild
```terminal
$ docker-compose build
```
- Gemfileの内容が更新されたり、Dockerfileの内容が更新された時は、イメージをBuildする

### 6. データベースの設定（接続先情報設定）
- `database.yml`でデータベースの設定が行われている
    - passwordと追加する（docker-compose.ymlで設定した環境変数）
    - hostは接続先（docker-compose.ymlでdepends_onしたdb）
```src/config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password
  host: db
```

### 7. データベース作成
- webのサービスに対して`rails db:create`
    - `app_development`と`app_test`というデータベースが作成される

```terminal
$ docker-compose run web rails db:create
```

```terminal:terminal
(base) sample@SampleMBP rails_docker % docker-compose run web rails db:create
[+] Running 1/1
⠿ Container rails_docker-db-1  Recreated                                                                                1.5s
[+] Running 1/1
⠿ Container rails_docker-db-1  Started                                                                                  0.2s
Running via Spring preloader in process 20
Created database 'app_development'
Created database 'app_test'
```

### 8. Docker起動

```
$ docker-compose up -d
```

- `-d`はデタッチで、terminal画面を占領せずバックグラウンドで起動し実行してくれる
- http://localhost:3000/ にアクセス
    - いつもの画面が表示されたら勝利
![スクリーンショット 2022-09-23 11.09.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689074/98721eeb-3e3f-e38a-c0bf-ef5064d756d7.png)



### 9. その他よく使うコマンドたち
---
- ログ確認
```terminal
$ docker-compose logs
```
---
- サーバ停止＆削除
```terminal
$ docker-compose down
```
---
- 起動または停止かどうかを確認したい時（STATUSがrunnningになっていると起動中)
```terminal
$ docker compose ps
```
---
- お掃除（未使用のDockerイメージを削除）
```terminal
$ docker system prune
```
---
- コンテナ内でコマンドを実行したい時
```terminal
$ docker-compose exec web /bin/bash
```


```terminal:例
(base) sample@SampleMBP rails_docker % docker-compose exec web /bin/bash
root@9c210f303XXX:/app# ls
Gemfile       README.md  app		  bin	  config.ru  lib  node_modules	postcss.config.js  storage  tmp     yarn.lock
Gemfile.lock  Rakefile	 babel.config.js  config  db	     log  package.json	public		   test     vendor
root@9c210f303XXX:/app# exit
exit
```

## NextStep
https://qiita.com/rexid/items/9ba6b1bb338a3e2b5d8b