everyday-railsというテスト本を元にdocker環境で学習しようとしたのがことの発端です。
私自身dockerのことをよくわかっていなかったので、なかなか解決に時間がかかってしまいました。
前提
この記事では、docker-composeにrailsの環境(everyday-railsで用意されているソースを元に使います。)を構築するにあたって遭遇したエラーとその対処について書きます。
Dockerファイルなど
dockerファイル
FROM ruby:2.7
ENV LANG C.UTF-8
RUN apt-get update -qq && apt-get install -y \
build-essential \
nodejs \
&& rm -rf /var/lib/apt/lists/*
RUN gem install bundler
WORKDIR /tmp
ADD Gemfile Gemfile
ADD Gemfile.lock Gemfile.lock
RUN bundle install
ENV APP_HOME /myapp
RUN mkdir -p $APP_HOME
WORKDIR $APP_HOME
ADD . $APP_HOME
docker-compose.yml
version: '3'
services:
web:
build: .
ports:
- "3000:3000"
command: bundle exec rails s -p 3000 -b '0.0.0.0'
volumes:
- .:/myapp
- bundle:/usr/local/bundle
depends_on:
- db
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: password
ports:
- '3306:3306'
volumes:
- mysql_data:/var/lib/mysql
volumes:
bundle:
mysql_data:
database.yml
(config/database.ymlのことです。)
default: &default
adapter: mysql2
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
timeout: 5000
username: root
password: password
host: db
development:
<<: *default
database: development_database
test:
<<: *default
database: test_database
production:
<<: *default
database: production_database
Gemfile
# gem 'sqlite3'
↑これを消して
gem 'mysql2'とします
これは今回使うデータベースがmysqlのためです。
docker-composeを立ち上げる
ここまででdocker-composeの設定となるファイルを書いたら、docker-composeを立ち上げます。
コマンドは
docker-compose build
何も問題なければ、以下のようにターミナルに表示されるはずです。
➜ everydayrails-rspec-2017 git:(master) ✗ docker-compose ps
NAME COMMAND SERVICE STATUS PORTS
➜ everydayrails-rspec-2017 git:(master) ✗ docker-compose build
[+] Building 1.5s (15/15) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 32B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/ruby:2.7 1.3s
=> [ 1/10] FROM docker.io/library/ruby:2.7@sha256:2b5ffc71a256f93e98a1b596f38bbe33632c5c48138f939aae7347e65343383f 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 13.34kB 0.0s
=> CACHED [ 2/10] RUN apt-get update -qq && apt-get install -y build-essential nodejs && rm -rf /var/lib/apt/lists/* 0.0s
=> CACHED [ 3/10] RUN gem install bundler 0.0s
=> CACHED [ 4/10] WORKDIR /tmp 0.0s
=> CACHED [ 5/10] ADD Gemfile Gemfile 0.0s
=> CACHED [ 6/10] ADD Gemfile.lock Gemfile.lock 0.0s
=> CACHED [ 7/10] RUN BUNDLER_VERSION=2.1.2 bundle install 0.0s
=> CACHED [ 8/10] RUN mkdir -p /myapp 0.0s
=> CACHED [ 9/10] WORKDIR /myapp 0.0s
=> CACHED [10/10] ADD . /myapp 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:c57dc4b7785a80ee5b1a6c2086bda32e5ed8f009d69648a18b0f6ef045ca7400 0.0s
=> => naming to docker.io/library/everydayrails-rspec-2017_web 0.0s
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
今回遭遇したエラーというのが、このbuildを行なった時に出たエラーとなります。
エラー文
### 省略します
=> CACHED [ 4/10] WORKDIR /tmp 0.0s
=> CACHED [ 5/10] ADD Gemfile Gemfile 0.0s
=> CACHED [ 6/10] ADD Gemfile.lock Gemfile.lock 0.0s
=> ERROR [ 7/10] RUN bundle install
------
> [ 7/10] RUN bundle install:
#11 0.555 You must use Bundler 2 or greater with this lockfile.
------
executor failed running [/bin/sh -c bundle install]: exit code: 20
ERROR: Service 'web' failed to build : Build failed
bundle install
を走らせた時にエラーが発生しているようです。
gemfile.lockにはbundlerのバージョン2を使う必要があるとのことです。
ですが、私の環境ではbundlerは2以上を使っていました。
確認方法としては、
- gem list bundler で現在インストールされているものをリストアップ
- Gemfile.lockの一番下にある
BUNDLED WITH
を見る
これらを行うことでbundlerのバージョンを見ることができます。
バージョンを指定して、bundle install
を実行する際には
bundle _1.16.6_ install
と打つことで`1.16.6_を用いてbundle installができます。
ちょっと脱線しましたが、本題に戻ります。
私の環境では、bundlerを2以上で作成しているのにエラーでは2以上がいると怒られています。
ここで対処法としていくつか考えました。
1.バージョンを下げてみる
2.「BUNDLER_VERSION=2.1.2 bundle install」を実行する
3.バージョンを2で指定してみる
これくらいしか思いつきませんでした。
それぞれ実行してみると、、、、、、、
2
の手順でエラーに変化がありました。
requires ruby version >= 2.6, which is incompatible
という文に変わり、rubyのバージョンを2.6以上にしないといけないようです。
なので、dockerファイルのFROMの部分を書き換えます。
FROM ruby:2.7
としてください。
これでbuildができました。
次はdocker-composeの中でbundle installを走らせます。
docker-compose run web bundle install
その後
docker-compose up
を入力してください
これでlocalhost:3000
にアクセスすることで表示されるはずなのですが、実際にアクセスしてみると、エラーになるはずです。
おそらく、databaseが無いと怒られます。私がそうでした。
これを解消するには、
rails db:create
rails db:migrate
の2つを実行して、databaseを作成しないといけません。
ただこのコマンドを打つだけでは、コンテナの外で実行していることになるので、ちょっとコマンドを追加しないといけません。
docker-compose exec web rails db:create
docker-compose exec web rails db:migrate
これで何のエラーもなくデータベースが作成されたら成功です!
localhost:3000にアクセスすると正常に動くはずです。
まとめ
- bundlerのエラーが出た時は、バージョンを落とすか上げる。
- Gemfile.lockを削除して再度bundle installを実行する
- 必要に応じてrubyのバージョンも上げること
- エラー文をよく読むこと
以上です!!