😃

Docker + Rails6 + MySQL

2021/10/31に公開

はじめに

  • なんでこの構成をやるようにしたのか?

    • いろんな環境で開発したい
      • win
      • mac
      • ubuntu
        を気分で使い分けたい
    • rbenvをそれぞれにインストールしたくない
       それぞれの環境用にrbenv等を調べてインストールする必要がある。
    • MySQLをインストール
      上記に挙げたそれぞれの環境へのセットアップ方法を調べて準備することが面倒。
  • この記事を作った経緯

    • 公式ではRails5しか書かれていない
      Rails6ではwebpackerが必須になるので、変更する必要がある。
    • dockerだけで開発するため
      dockerで環境を立ち上げる記事はいくつかありましたが、docker環境で完結してる記事がなかったように思えたので書きました。

はじめに用意するファイル

RailsをDocker環境で作るというのは公式に載っているのですが罠がありました。
あるのはRails5の設定ファイルとなります。
Rails6からはWebpackerのインストールが必要になるのでちょっとした工夫が必要になります。

以下が参考にしたサイト

上のサイトを参考に5つのファイルを作ります。

  • Dockerfile
  • docker-compose.yml
  • Gemfile
  • Gemfile.lock
  • entrypoint.sh

私の作成したファイルを参考に載せます。
以下のファイルはすべてカレントルートにおいてください。

Dockerfile

FROM ruby:2.7.3
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
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
RUN apt-get install nodejs
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp

# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]

docker-compose.yml

※MySQLも準備しています。

version: '3'
services:
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: password
    ports:
      - '3306:3306'
    command: --default-authentication-plugin=mysql_native_password
    volumes:
      - mysql-data:/var/lib/mysql
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
    stdin_open: true
    tty: true
volumes:
  mysql-data:
    driver: local

Gemfile

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

Gemfile.lock

※空

entrypoint.sh

#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"

以上で準備完了です。

Railsアプリ作成

参考サイトには以下のコマンドが書かれています。

$ docker-compose run web rails new . --force --no-deps --database=mysql --skip-test --webpacker

あとはビルドを行います。

docker-compose build

終わったら起動してください。

いつもの例のページが見れると思います。

困ったこと

私はRailsのアプリがありそれに上で立ち上がった環境設定を基にアプリに適用しました。
以下が困ったことです。

rails new 実行をすると、Railsアプリを作成してくれるのですが、困ったことにdocker内でコマンドを実行するとrootが作成したことになります。よって権限も違うため、編集するためには権限付与等が必要になります。

---中略---
-rw-r--r--   1 root       root          227 Sep 24 01:20 Rakefile
drwxr-xr-x  11 root       root         4096 Sep 24 01:20 app
-rw-r--r--   1 root       root         1897 Sep 24 01:23 babel.config.js
drwxr-xr-x   2 root       root         4096 Sep 24 01:23 bin
drwxr-xr-x   6 root       root         4096 Sep 24 01:23 config
-rw-r--r--   1 root       root          160 Sep 24 01:20 config.ru
drwxr-xr-x   2 root       root         4096 Sep 24 01:20 db

もどって、ホストで作成したものがdocker内でどうなっているかを確認します。
確認したのがこちら

root@ec7dcad4b67d:/myapp# ls -l
total 16
-rw-r--r-- 1 1000 1000 790 Sep 23 16:42 Dockerfile
-rw-r--r-- 1 1000 1000  49 Sep 23 16:43 Gemfile
-rw-r--r-- 1 1000 1000   0 Sep 23 16:43 Gemfile.lock
-rw-r--r-- 1 1000 1000 548 Sep 23 16:42 docker-compose.yml
-rw-r--r-- 1 1000 1000 201 Sep 23 16:43 entrypoint.sh

railsのコマンドから自動生成されたファイルは権限が違うため、毎回権限を変更しないといけないそれではdockerに移して開発しても面倒になってしまう。
では、どうしたか?
-u 1000:1000を足して実行ユーザーを変えることで解決しました。
コマンドに足さずとも、設定ファイルに足すことで解決するのですが、私は取り急ぎコマンドに足すことで対処しました(rootで実行する方がいい場合があると考えたため)

以上になります。
記事に更新があれば追記していきます。

追記: WSL2を使っていたために起こっていた。

こちらの記事を参考にしました。
http://codelabo.com/posts/20210928184252#本件に関係なくてやっても意味がなかった対応

ほかのMacでは起こるのか?という疑問から試してみると、Macではこのようなことは起こることはなく、私がこの記事を書くためにwin+WSL2の環境で作業していたことが原因でした。

Discussion