質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.36%
docker-compose

docker-composeとは、複数のコンテナで構成されるサービスを提供する手順を自動的し管理を簡単にするツール。composeファイルを使用しコマンド1回で設定した全サービスを作成・起動することが可能です。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

RSpec

RSpecはRuby用のBDD(behaviour-driven development)フレームワークです。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

Q&A

解決済

2回答

2475閲覧

Docker上でRspecを実行するとMySQLに接続できない

mikepp

総合スコア11

docker-compose

docker-composeとは、複数のコンテナで構成されるサービスを提供する手順を自動的し管理を簡単にするツール。composeファイルを使用しコマンド1回で設定した全サービスを作成・起動することが可能です。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

RSpec

RSpecはRuby用のBDD(behaviour-driven development)フレームワークです。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

0グッド

0クリップ

投稿2020/08/21 01:56

質問内容

Docker上でRspecを走らせようとしたところエラーが発生してしまいました。
MySQLとの接続が上手くいっていないようです。
database.ymlとdocker-compose.ymlを見直しても問題があるようには見えず、コンテナとイメージを全て削除して再び起動してもエラーコードの内容は変わりませんでした。

アドバイス等ありましたら頂けると幸いです。
よろしくお願いします。

開発環境

Ruby 2.5.1
Rails 5.2.4.3
Mac OS

#エラーコード

console

1~@yk golfour_aws % bundle exec rspec 2An error occurred while loading ./spec/system/training_posts_spec.rb. 3Failure/Error: ActiveRecord::Migration.maintain_test_schema! 4 5Mysql2::Error::ConnectionError: 6 Unknown MySQL server host 'db-test' (0) 7# ./spec/rails_helper.rb:28:in `<top (required)>' 8# ./spec/system/training_posts_spec.rb:1:in `require' 9# ./spec/system/training_posts_spec.rb:1:in `<top (required)>' 10No examples found. 11 12Finished in 0.00004 seconds (files took 2.88 seconds to load) 130 examples, 0 failures, 1 error occurred outside of examples

関連ファイル

docker-compose.yml:

version: '3' services: db: image: mysql:8.0 command: --default-authentication-plugin=mysql_native_password environment: MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: golfour_development MYSQL_USER: yuki MYSQL_PASSWORD: password TZ: Asia/Tokyo volumes: - ./mysql/mysql_data:/var/lib/mysql - ./logs:/var/log/mysql - ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf ports: - "4306:3306" db-test: image: mysql:8.0 command: --default-authentication-plugin=mysql_native_password environment: MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: golfour_test MYSQL_USER: yuki MYSQL_PASSWORD: password TZ: Asia/Tokyo volumes: - ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf tmpfs: - /var/lib/mysql - /var/log/mysql ports: - "5306:3306" web: build: context: . dockerfile: Dockerfile command: /bin/sh -c "rm -f /workdir/tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'" tty: true stdin_open: true depends_on: - db - db-test ports: - "3000:3000" volumes: - .:/workdir

database.yml:

default: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> development: <<: *default database: golfour_development username: yuki password: password host: db socket: /tmp/mysql.sock test: <<: *default database: golfour_test username: yuki password: password host: db-test socket: /tmp/mysql.sock production: <<: *default database: <%= ENV['DB_NAME'] %> username: <%= ENV['DB_USERNAME'] %> password: <%= ENV['DB_PASSWORD'] %> host: <%= ENV['DB_HOSTNAME'] %>

rails.helper:

# This file is copied to spec/ when you run 'rails generate rspec:install' require 'spec_helper' ENV['RAILS_ENV'] ||= 'test' require File.expand_path('../config/environment', __dir__) # Prevent database truncation if the environment is production abort("The Rails environment is running in production mode!") if Rails.env.production? require 'rspec/rails' # Add additional requires below this line. Rails is not loaded until this point! # Requires supporting ruby files with custom matchers and macros, etc, in # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are # run as spec files by default. This means that files in spec/support that end # in _spec.rb will both be required and run as specs, causing the specs to be # run twice. It is recommended that you do not name files matching this glob to # end with _spec.rb. You can configure this pattern with the --pattern # option on the command line or in ~/.rspec, .rspec or `.rspec-local`. # # The following line is provided for convenience purposes. It has the downside # of increasing the boot-up time by auto-requiring all files in the support # directory. Alternatively, in the individual `*_spec.rb` files, manually # require only the support files necessary. # # Dir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f } # Checks for pending migrations and applies them before tests are run. # If you are not using ActiveRecord, you can remove these lines. begin ActiveRecord::Migration.maintain_test_schema! rescue ActiveRecord::PendingMigrationError => e puts e.to_s.strip exit 1 end RSpec.configure do |config| # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures config.fixture_path = "#{::Rails.root}/spec/fixtures" # If you're not using ActiveRecord, or you'd prefer not to run each of your # examples within a transaction, remove the following line or assign false # instead of true. config.use_transactional_fixtures = true # You can uncomment this line to turn off ActiveRecord support entirely. # config.use_active_record = false # RSpec Rails can automatically mix in different behaviours to your tests # based on their file location, for example enabling you to call `get` and # `post` in specs under `spec/controllers`. # # You can disable this behaviour by removing the line below, and instead # explicitly tag your specs with their type, e.g.: # # RSpec.describe UsersController, type: :controller do # # ... # end # # The different available types are documented in the features, such as in # https://relishapp.com/rspec/rspec-rails/docs config.infer_spec_type_from_file_location! # Filter lines from Rails gems in backtraces. config.filter_rails_from_backtrace! # arbitrary gems may also be filtered via: # config.filter_gems_from_backtrace("gem name") end

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

docker-composer up後に
docker psで"db", "db-test"いずれも起動していますか?

投稿2020/08/21 05:47

naokit-dev

総合スコア424

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mikepp

2020/08/21 05:52

回答ありがとうございます。 確認したところ起動しています。 〜@yk golfour_aws % docker-compose ps Name Command State Ports -------------------------------------------------------------------------------------------------- golfour_aws_db-test_1 docker-entrypoint.sh --def ... Up 0.0.0.0:5306->3306/tcp, 33060/tcp golfour_aws_db_1 docker-entrypoint.sh --def ... Up 0.0.0.0:4306->3306/tcp, 33060/tcp golfour_aws_web_1 /bin/sh -c rm -f /workdir/ ... Up 0.0.0.0:3000->3000/tcp
naokit-dev

2020/08/21 06:43

Dockerでmysqlを使用したことがないのですが、 StackOverflow等で似たエラーを検索しているとコンテナを分けてテスト環境用、開発環境用と構成するべきとの投稿も見られますが、現状の構成はそれを目指しているように見えます How to create Mysql test database in dockerized Rails application? - Stack Overflow https://stackoverflow.com/questions/47224999/how-to-create-mysql-test-database-in-dockerized-rails-application database.ymlのsocketの記述が気になります dockerではmysqlとの接続にsocketを使えない というコメントも見られましたのでこれをコメントアウトしてみてはいかがでしょうか? おそらく開発環境では問題ないようですので、なんとも言えませんが... 力不足ですがお役に立てれば幸いです
mikepp

2020/08/21 09:10

自己解決しました! docker上でrspecを実行していなかったのが原因でした。 非常に初歩的なミスでした... Docker上でRspecを実行することでエラーが発生しないようになりました。 ~@yk golfour_aws % docker-compose exec web bash root@00498044b281:/workdir# bundle exec rspec . Finished in 6.78 seconds (files took 2.12 seconds to load) 1 example, 0 failures 丁寧に回答していただき本当にありがとうございました。 socketについても調べてみます!
naokit-dev

2020/08/21 09:12

解決したようでよかったです!
guest

0

ベストアンサー

追記

たとえば、web から ping を実行してみるとどうでしょうか?

console

1root@3ac5aad020bf:/workdir# ping db-test 2PING db-test (172.31.0.2) 56(84) bytes of data. 364 bytes from test-docker-286284_db-test_1.test-docker-286284_default (172.31.0.2): icmp_seq=1 ttl=64 time=0.116 ms 464 bytes from test-docker-286284_db-test_1.test-docker-286284_default (172.31.0.2): icmp_seq=2 ttl=64 time=0.067 ms 564 bytes from test-docker-286284_db-test_1.test-docker-286284_default (172.31.0.2): icmp_seq=3 ttl=64 time=0.082 ms 664 bytes from test-docker-286284_db-test_1.test-docker-286284_default (172.31.0.2): icmp_seq=4 ttl=64 time=0.070 ms

こちらで質問欄のコードをすべて使い動作確認を行ったところ、
rspec は実行できました:

console

1root@385d4f318198:/workdir# bundle exec rspec 22020-08-21 06:36:20 WARN Selenium [DEPRECATION] Selenium::WebDriver::Chrome#driver_path= is deprecated. Use Selenium::WebDriver::Chrome::Service#driver_path= instead. 3. 4 5Finished in 0.07961 seconds (files took 1.63 seconds to load) 61 example, 0 failures

database.yml を次のように書き換えると:

diff

1- host: db-test 2+ host: db-not-exist

console

1root@385d4f318198:/workdir# bundle exec rspec 22020-08-21 06:36:52 WARN Selenium [DEPRECATION] Selenium::WebDriver::Chrome#driver_path= is deprecated. Use Selenium::WebDriver::Chrome::Service#driver_path= instead. 3 4An error occurred while loading ./spec/models/test_spec.rb. 5Failure/Error: ActiveRecord::Migration.maintain_test_schema! 6 7Mysql2::Error::ConnectionError: 8 Unknown MySQL server host 'db-not-exist' (-2) 9# /usr/local/bundle/gems/mysql2-0.5.3/lib/mysql2/client.rb:90:in `connect' 10# /usr/local/bundle/gems/mysql2-0.5.3/lib/mysql2/client.rb:90:in `initialize' 11# /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/connection_adapters/mysql2_adapter.rb:22:in `new' 12# /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/connection_adapters/mysql2_adapter.rb:22:in `mysql2_connection' 13# /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/connection_adapters/abstract/connection_pool.rb:830:in `new_connection' 14# /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/connection_adapters/abstract/connection_pool.rb:874:in `checkout_new_connection' 15# /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/connection_adapters/abstract/connection_pool.rb:853:in `try_to_checkout_new_connection' 16# /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/connection_adapters/abstract/connection_pool.rb:814:in `acquire_connection' 17# /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/connection_adapters/abstract/connection_pool.rb:538:in `checkout' 18# /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/connection_adapters/abstract/connection_pool.rb:382:in `connection' 19# /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/connection_adapters/abstract/connection_pool.rb:1033:in `retrieve_connection' 20# /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/connection_handling.rb:118:in `retrieve_connection' 21# /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/connection_handling.rb:90:in `connection' 22# /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/migration.rb:583:in `load_schema_if_pending!' 23# /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/migration.rb:599:in `block in maintain_test_schema!' 24# /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/migration.rb:848:in `suppress_messages' 25# /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/migration.rb:604:in `method_missing' 26# /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/migration.rb:599:in `maintain_test_schema!' 27# ./spec/rails_helper.rb:93:in `<top (required)>' 28# ./spec/models/test_spec.rb:1:in `require' 29# ./spec/models/test_spec.rb:1:in `<top (required)>' 30No examples found. 31 32 33Finished in 0.00005 seconds (files took 2.5 seconds to load) 340 examples, 0 failures, 1 error occurred outside of examples

そのため、質問欄に提示されているコード自体は誤っていなさそうです

元の回答

おそらく、次のようにすると実行できます:

console

1RAILS_ENV=development bundle exec rspec

ただし、開発で利用しているデータベース golfour_development を使うことになるので、
rspec の内容によっては golfour_development の状態が変化することに注意します

rspec は規定の動作では config/database.ymltest のデータベースを使って動作します
しかし、MySQL の公式イメージでは複数のデータベースを作成する手順をサポートしていません

参考:

もし、データベースを分けたい場合は、
何かしらの方法で自身で test のデータベースを作成する必要があります
例えば、次のような方法が考えられます:

  • Rails から root として接続するようにして rails db:create
  • テスト用テーブル初期化処理を .sql.sh として作成して、そのファイルが配置されているディレクトリーを /docker-entrypoint-initdb.dvolumes で bind マウント

ただし、開発で何度も使うデータは factory_bot で定義する、という習慣があれば、
個人的には上記の対応を行わなくても、それほど不便は感じません

参考: thoughtbot/factory_bot: A library for setting up Ruby objects as test data.

投稿2020/08/21 04:40

編集2020/08/21 06:47
y_shinoda

総合スコア3272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mikepp

2020/08/21 05:32

丁寧な回答ありがとうございます。 ご指摘通り、 RAILS_ENV=development bundle exec rspec を実行したところ、 bundle exec rspec 実行した時と同じエラーが発生しました。(質問内容のエラーコード) また、データベースを分けるために ・docker-compose.ymlでテスト用のコンテナ(db-test)を作成 ・database.ymlのtest環境にhost:db-testを設定 ・docker-compose run web bundle exec rake db:create を実行 ・bundle exec rspec 以上を実行してもエラーが発生してしまいます。 dockerに環境を移行する前は問題なくテストが成功していました。 docker-compose.ymlの設定が問題なのでしょうか。
y_shinoda

2020/08/21 06:50

失礼しました、回答を修正しました 開発とテストでコンテナを分けるのはいい方法ですね
mikepp

2020/08/21 09:08

解決しました! docker上でrspecを実行していなかったのが原因でした。 非常に初歩的なミスでした... Docker上でRspecを実行することでエラーが発生しないようになりました。 ~@yk golfour_aws % docker-compose exec web bash root@00498044b281:/workdir# bundle exec rspec . Finished in 6.78 seconds (files took 2.12 seconds to load) 1 example, 0 failures 丁寧に回答していただき本当にありがとうございます。 解説していただいた内容が非常に勉強になるので参考にさせていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問