Capybaraのためのcompose.ymlの設定
こんにちは
プログラミングスクールで Ruby on Rails を主に学習している、りゅうという者です。
卒業制作でWebアプリを作成しています。
その中で今回 Capybara を使うときに、compose.yml の設定をしていない関係でエラーが起きたので、記事にさせていただきました。
⚠️ 注意
プログラミング初心者のため、間違いがあるかもしれません。
また、お使いのPCや環境によってはうまく動作しない可能性もございます。
お気付きの点がありましたら遠慮なく教えていただけると嬉しいです。
よろしくお願いいたします。
言葉の理解には ChatGPT を多く使っているので、正確性には欠けるかもしれません。
より正確性を求めるには 公式を参考 にしてください。
💡 前提
- Capybaraに必要なgemをインストールしている。
- Capybaraに関する設定やテストの実装は終わっている。
🧭 Capybaraの流れ
Capybara(Railsのテスト)が「このページを開いて」「このボタンを押して」などの命令を出します。 その命令を Selenium Server に送って、
Selenium Server がその命令を WebDriver に伝えて実際にブラウザ(Chrome)を操作する流れになります。
┌────────────────────────────┐
│ Docker環境(共通ネットワーク) │
│────────────────────────────│
│ │
│ 🧱 webコンテナ (Rails + Capybara) │
│ ↓ │
│ ↓ HTTPリクエスト │
│ ↓ (SELENIUM_DRIVER_URL=http://chrome:4444/wd/hub) │
│ │
│ 🌐 chromeコンテナ (Selenium Server + Chromeブラウザ) │
│ ↑ │
│ └── SeleniumがWebDriverに命令を伝え、Chromeを操作 │
│ │
└────────────────────────────┘
🧪 Capybaraのテスト実行時に出たエラー
Capybaraの設定やテストの実装が終わって、
以下のコマンドを実行しました👇
docker compose exec web bundle exec rspec spec/system/users_spec.rb
# ./spec/system/users_spec.rb:6:in `block (3 levels) in <top (required)>'
# ------------------
# --- Caused by: ---
# Errno::ECONNREFUSED:
# Connection refused - connect(2) for "127.0.0.1" port 4444
# /usr/local/bundle/gems/timeout-0.4.3/lib/timeout.rb:185:in `block in timeout'
🧐 エラーと原因
Rails(Capybara / Seleniumクライアント)が
「127.0.0.1:4444」に接続しようとして失敗しました。
127.0.0.1 は webコンテナのOS自身を指します。
つまり、Railsがwebコンテナに接続しようとしています。
本来はRailsがchromeに接続しないといけません。
🔧 対応
なので、以下を追加しました(dbなど無関係な部分は省略しています)
version: '3'
services:
web:
build:
context: .
command: bash -c "bundle install && bundle exec rails db:prepare && rm -f tmp/pids/server.pid && ./bin/dev"
tty: true
stdin_open: true
volumes:
- .:/myapp
- bundle_data:/usr/local/bundle:cached
- node_modules:/myapp/node_modules
environment:
TZ: Asia/Tokyo
+ SELENIUM_DRIVER_URL: http://chrome:4444/wd/hub
ports:
- "3000:3000"
depends_on:
db:
condition: service_healthy
+ chrome:
+ condition: service_started
+ chrome:
+ image: seleniarm/standalone-chromium:latest
+ ports:
+ - 4444:4444
📘compose.ymlとは
複数のコンテナをまとめて構成・起動するための設定ファイル。
ここで言うコンテナとは、db、webやchromeを指します。
🧩加筆したコードの理解
+ chrome:
+ image: seleniarm/standalone-chromium:latest
+ ports:
+ - 4444:4444
chromeと言うコンテナを作成しようとしています。imageは設計図のイメージで、ここではchromeとseleniumの設計図です。
ポート番号は4444を指定します。
depends_on:
db:
condition: service_healthy
+ chrome:
+ condition: service_started
depends_onはコンテナの起動順序の制御です。
web:に書いているので、
dbコンテナが立ち上がったらwebコンテナを立ち上げてと明示しています。
chromeも同じです。
conditionなどは以下の記事が参考になります。↓↓
environment:
TZ: Asia/Tokyo
+ SELENIUM_DRIVER_URL: http://chrome:4444/wd/hub
environment(環境変数)とはコンテナ起動時に読む設定項目です
ここで設定した値は、Railsアプリの中から ENV["変数名"] で使えます。
Capybara.register_driver :remote_chrome do |app|
options = Selenium::WebDriver::Chrome::Options.new
省略
ENV['SELENIUM_DRIVER_URL'], capabilities: options)
end
と書いています。この中のENV['SELENIUM_DRIVER_URL']に先ほどのURLの値が入ります。
URLはSeleniumの住所のイメージです。
具体的にはChromeコンテナを作ってポート番号を指定した場所になります。
wd/hubはSelenium Server が自動で提供しているAPIのルートパスです。
まとめ
Capybara(Railsのテスト)がwebコンテナを探していた原因でエラーが起きました。
compose.ymlにChromeに関する設定を加筆したことで解決できました。
Dockerにブラウザ(Chromeコンテナ)を追加して、その中で自己完結していくんですね。
間違いがあったらぜひ教えてください!
参考になった記事
最後に
Dockerのイメージは抽象的で難しいですが、理解が少し深まったと思います。
noteで卒業制作の過程を書いています。
よかったらぜひおねがします!
Discussion