Docker + Rails6 + MySQL
はじめに
-
なんでこの構成をやるようにしたのか?
- いろんな環境で開発したい
- win
- mac
- ubuntu
を気分で使い分けたい
- rbenvをそれぞれにインストールしたくない
それぞれの環境用にrbenv等を調べてインストールする必要がある。 - MySQLをインストール
上記に挙げたそれぞれの環境へのセットアップ方法を調べて準備することが面倒。
- いろんな環境で開発したい
-
この記事を作った経緯
- 公式ではRails5しか書かれていない
Rails6ではwebpackerが必須になるので、変更する必要がある。 - dockerだけで開発するため
dockerで環境を立ち上げる記事はいくつかありましたが、docker環境で完結してる記事がなかったように思えたので書きました。
- 公式ではRails5しか書かれていない
はじめに用意するファイル
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を使っていたために起こっていた。
こちらの記事を参考にしました。
ほかのMacでは起こるのか?という疑問から試してみると、Macではこのようなことは起こることはなく、私がこの記事を書くためにwin+WSL2の環境で作業していたことが原因でした。
Discussion