LoginSignup
3
0

More than 1 year has passed since last update.

[Ruby on Rails] 速習実践ガイドの環境をDockerで構築する [Docker]

Last updated at Posted at 2023-04-07

はじめに

Ruby on Railsの入門書籍として知られる”速習実践ガイド”
とても勉強になる良い書籍ですが、いかんせんRubyやRailsのバージョンが古いこと、手元の環境がMac M1が相まって開発環境構築に難儀しました。
そこで、試行錯誤の末、RSpecが動くまでの環境を残したいと思います。
これからRuby on Railsを始める方、速習実践ガイドを始める方のお役に立てれば幸いです。

環境構築

手元環境

  • Macbook Air M1
  • Docker Desktop

dockerfile

dockerfileは以下の通りです。
こちらのサイトを参考に構築しています。
速習実践ガイドのRuby2.5なので、それに合わせています。

# syntax=docker/dockerfile:1
FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install

# コンテナー起動時に毎回実行されるスクリプトを追加
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

# イメージ実行時に起動させる主プロセスを設定
CMD ["rails", "server", "-b", "0.0.0.0"]

entrypoint.sh

#!/bin/bash
set -e

# Rails に対応したファイル server.pid が存在しているかもしれないので削除する。
rm -f /myapp/tmp/pids/server.pid

# コンテナーのプロセスを実行する。(Dockerfile 内の CMD に設定されているもの。)
exec "$@"

docker-compose.yaml

docker-compose.yamlは以下の通りです。
RSpecでシステムテストを実行するためには、ブラウザが必要です。
ただ、webコンテナの中にブラウザをインストールするのは大変です。
なので、docker-compose.yamlで別途ブラウザ用のコンテナを用意します。
webコンテナのdepends_onとenvironmentでブラウザ用コンテナを利用するように設定します。

version: "3.9"
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: password
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    environment:
      SELENIUM_DRIVER_URL: http://webdriver_chrome:4444/wd/hub
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
      - webdriver_chrome

  webdriver_chrome:
    image: seleniarm/standalone-chromium
    ports:
      - "4444:4444"

Gemfile

続いて、Gemfileです。
bin/rails new で追加されるモジュールの一部は省略しています。
速習実践ガイドでは Headless Chromeが紹介されています。しかし、このChromeは今はあまり使われていないようです(よくわかってないです)
なので、group :test do の箇所にはgem 'selenium-webdriver'を指定します。
また、Rubyのバージョンですが、速習実践ガイドのバージョンは素直に使えなかったので、2.5.9に変更しています。

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.5.9'
group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'rspec-rails', '~> 3.7'
  gem 'factory_bot_rails', '~> 4.11'
end

group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '>= 3.0.5', '< 3.2'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
end

group :test do
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '>= 2.15'
  gem 'selenium-webdriver'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

gem 'slim-rails'
gem 'html2slim'
gem 'bootstrap'
gem 'rails_autolink'

RSpecの設定

続いて、RSpecの設定です。
まずspec/rails_helper.rbの25行目あたりの記述をコメントインします。

Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f }

続いて、spec/support/capybara.rb をフォルダ含めて作成します。
capybara.rbの内容は以下の通りです。

require 'capybara/rspec'

RSpec.configure do |config|
  config.before(:each, type: :system) do
    driven_by :remote_chrome
    Capybara.server_host = IPSocket.getaddress(Socket.gethostname)
    Capybara.server_port = 3000
    Capybara.app_host = "http://#{Capybara.server_host}:#{Capybara.server_port}"
  end

  config.before(:each, type: :system, js: true) do
    driven_by :remote_chrome
    Capybara.server_host = IPSocket.getaddress(Socket.gethostname)
    Capybara.server_port = 3000
    Capybara.app_host = "http://#{Capybara.server_host}:#{Capybara.server_port}"
  end
end

# Chrome
Capybara.register_driver :remote_chrome do |app|
  url = 'http://webdriver_chrome:4444/wd/hub'
  caps = ::Selenium::WebDriver::Remote::Capabilities.chrome(
    'goog:chromeOptions' => {
      'args' => [
        'no-sandbox',
        'headless',
        'disable-gpu',
        'window-size=1680,1050'
      ]
    }
  )
  Capybara::Selenium::Driver.new(app, browser: :remote, url: url, desired_capabilities: caps)
end

実行方法

ここまでで、設定は終了です。
最後に環境の実行方法は以下の通りです

$ docker compose build
$ docker compose up

補足情報

残りは実行時に詰まりそうな情報です。

RSpec Systemテストが失敗する

私の環境では、チュートリアル通りに進めたところ、fill_inが正しく動作せず、入力失敗していました。

こちらの方の情報通りに直して動作しました。click_onは念の為、生成されるボタンのcommitを指定しました。
【RSpec/capybara】fill_inが上手く動作しな

before do
  visit login_path

  fill_in 'session_email', with: 'a@example.com'
  fill_in 'session_password', with: 'password'
  click_on 'commit'
end

Docker環境でのコマンド実行の方法

Dockerで構築したwebコンテナで速習実践ガイドで紹介されているコマンドを実行する場合は以下の通りです。

$ docker compose run web {実行したいコマンド}
# 例えば、db:migrationやrailsコマンドを実行したい場合
$ docker compose run web db:migrate
$ docker compose run web bin/rails g controller

gemを追加する方法

gemfileに新しいモジュールを追加した場合、コマンド実行だけでは不十分です。
必ずBuildしましょう。何が動作がおかしい場合は、--no-cacheコマンドでしっかりBuildしましょう。

$ docker compose build

以上です。皆様の参考になれば幸いです。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0