Rails6アプリ on Docker

## :bomb: 注意 :bomb: 

本番のサービスに入れようと思ったのですが、いくつか問題があって調整中です。

- [ ] system specが動かない
- [ ] webpackerのことを忘れていた


## はじめに

未だ自分は開発環境でDockerを使ったことがありませんでした。
そんな折に、[Rails7.1でDocker関連ファイルが入るという話](https://techracho.bpsinc.jp/hachi8833/2023_02_20/126518)を小耳に挟み…少し試しておこうかな…という気持ちになりました。

せっかくなら会社のアプリにも導入したい！と思ったので、Ruby3.0とRails6.0で試しました。

## やったこと

↓ができれば問題ないかなと思ってました。

- Docker ComposeでWeb、DBサーバを管理
- DBサーバのデータはローカルに保存して、コンテナを削除しても残るようにする
- デバッグできる
- rubocopできる

### やってないこと
- Github Codespaces
    - ホントはちょっとやってすぐ動いたんですが、まとめてないです。
- Dev Container
    - VSCodeの一機能が切り離されて、コマンドラインでも使えるらしく…。ちょっと気になってますが、やってません。

### [サンプル用Railsアプリ](https://github.com/ken1flan/rails6_docker)

雑ですが、こんな感じです。

- Ruby3.0
- Rails6.0
- MySQL5.7
- Webpacker
- rubocop
- rspec
- アプリの機能
    - ↓をやって、なんとなく整えただけです
    - rails g scaffold article title:string body:text
    - rails g controller top index
- [ソースコード](https://github.com/ken1flan/rails6_docker)

## 行った変更

### [Dockerfileの追加](https://github.com/ken1flan/rails6_docker/blob/main/Dockerfile)

細かいことをいろいろしてますので、インラインコメントを見てください。

```Dockerfile:Dockerfile
FROM ruby:3.0.5

# nodeとyarnのインストール
RUN apt-get update -qq && apt-get install -y nodejs npm && npm install -g yarn

WORKDIR /app
# Gemのインストール
COPY Gemfile Gemfile.lock /app/
RUN bundle install
# ソースのコピー
COPY . /app
```

### [docker-compose.yml](https://github.com/ken1flan/rails6_docker/blob/main/docker-compose.yml)の追加

細かいことをいろいろしてますので、インラインコメントを見てください。

```yml:docker-compose
version: '3'
services:
  db:
    image: mysql:5.7
    platform: linux/amd64 # mysqlにはarmのイメージがないので、amd64版を明示的に指定してます。
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: rails6_docker_development
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci # mysql5.7はデフォルトがratin1なので、utf8を指定して実行するようにしています。
    volumes:
      - ./db_data:/var/lib/mysql # ローカルのディレクトリをマウントして、コンテナが破棄されても残るようにします。
    ports:
      - "3306:3306" # ローカルの3306番ポートをコンテナに転送して、いつもの使い慣れたmysqlクライアントで扱えます。
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/app
    ports:
      - "3000:3000" # ローカルの3０００番ポートをコンテナに転送して、ブラウザで確認できるようにしています。
    # stdin_open、ttyを設定して、attachしたときに操作できるようにします。
    stdin_open: true
    tty: true
    depends_on:
      - db
    environment:
      DATABASE_HOST: db
      DATABASE_USER: root
      DATABASE_PASSWORD: password
      DATABASE_NAME: rails6_docker_development
```

### [config/database.yml](https://github.com/ken1flan/rails6_docker/blob/main/config/database.yml)の修正

host、passwordを環境変数を見て設定することで、ローカルとコンテナの開発を切り替えられるようにしています。

```yaml:config/database.yml
# (省略)
development:
  <<: *default
  database: rails6_docker_development
  host: <%= ENV.fetch('DATABASE_HOST', 'localhost') %>
  password: <%= ENV.fetch('DATABASE_PASSWORD', 'password') %>

test:
  <<: *default
  database: rails6_docker_test
  host: <%= ENV.fetch('DATABASE_HOST', 'localhost') %>
  password: <%= ENV.fetch('DATABASE_PASSWORD', 'password') %>
# (省略)
```

### [config/environments/development.rb](https://github.com/ken1flan/rails6_docker/blob/main/config/environments/development.rb#L63)の修正

github codespacesで利用したときに、Blocked hostエラーで参照できなかったので、hostsを空に設定しています。development環境なので大丈夫かと思います。

```ruby:config/environments/development.rb
Rails.application.configure do
  # : (省略)
  config.hosts = nil
end
```

## アレできます？

### デバッグ

できます。

`docker ps`で名前を特定し、`docker attach`すると、`byebug`などを埋め込んだところでとまってくれます。

終了するときは`ctrl-p`+`ctrl+q`です。
（VSCodeのターミナルだと`ctrl+q`に別の機能が当てられていて、ちょっと不便でした…。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14380/4f5351d5-cba5-20fe-b980-42b791d615f9.png)

### mysqlクライアント

できます。

`docker-compose.yml`でローカルの3306番ポートをmysqlのコンテナに転送しているので、お好みのクライアントで接続できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14380/49e0087c-0b15-69f5-43fa-07da463636d6.png)

### ログインして操作

できます。

`docker-compose exec サービス名 /bin/bash`とか、Docker Desktopのterminalとか、VSCodeでAttach Shellとか、いろいろなやり方でできます。

### rails console

できます。

ログインして操作ができるので…何でもどうぞ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14380/10ea6c32-4b1a-63b4-4c86-c5bf57c369c6.png)


### rubocopその他

できます。

ログインして操作ができるので…何でもどうぞ。

## 最後に

あれ？案外かんたんにできそうじゃん？
会社のプロジェクトにも入れてみようかな…？
そしたら開発環境に差分が出にくくて幸せになれそう。

## おまけ

- [この記事の元のスクラップ](https://zenn.dev/ken1flan/scraps/6f807f2f3d4f8e)