keiino0425
@keiino0425 (いのぼー)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

(docker)test用のデータベースが作成できず、NoDatabaseErrorが発生する

解決したいこと

RailsアプリケーションにRspecテストを導入しようと思ったのですが、
テスト用のデータベースが作成できず困っています。
解決方法を教えて下さい。

発生している問題・エラー

ある程度完成したRailsアプリケーションにRspecテストを導入しようと思い、rspecをインストールしたのちに

$ docker-compose run web bundle exec rspec

を入力しましたが、

Running via Spring preloader in process 44
rake aborted!
ActiveRecord::NoDatabaseError: Unknown database 'jsmcreserveapp_test'
以下略

というエラーが発生しました。

$ docker-compose up -d
$ docker exec -it jsmcreserveapp_db_1 bash
$ mysql -u root -p

とコマンドを入力し、データベースを確認しましたがjsmcreserveapp_testはありませんでした。
(jsmcreserveapp_developmentはありました)

なのでデータベースを作成しようと思い、以下のコマンドを打ち込みました。

$ docker-compose run web bundle exec rails db:create

Running via Spring preloader in process 29
Database 'JSMCreserveapp_development' already exists
Created database 'JSMCreserveapp_test'

$ docker-compose down

$ docker-compose run web bundle exec rails db:migrate
Running via Spring preloader in process 31

その後rspecを実行すると

$ docker-compose run web bundle exec rspec

Running via Spring preloader in process 45
rake aborted!
ActiveRecord::StatementInvalid: Mysql2::Error: Schema directory './JSMCreserveapp_test' already exists. This must be resolved manually (e.g. by moving the schema directory to another location).
以下略

のエラーが発生します。

一度docker-compose downをして再びrspecを実行すると、

$ docker-compose run web bundle exec rspec

Running via Spring preloader in process 44
rake aborted!
ActiveRecord::NoDatabaseError: Unknown database 'jsmcreserveapp_test'

という別のエラーが発生します。

$ docker-compose run web bundle exec rails db:create

を実行した後はdb/mysql_dataの中にJSMCreserveapp_testは存在しました。

しかし

$ docker-compose run web bundle exec rspec

を実行したのちに

$ docker-compose down

するとdb/mysql_dataの中からJSMCreserveapp_testがなくなっていました。
docker-compose stop を実行した場合も同じくJSMCreserveapp_testがなくなっていました。

解決策を色々調べましたが詰まってしまったため、アドバイスをいただければありがたいです。

該当するソースコード

database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password
  host: db

development:
  <<: *default
  database: JSMCreserveapp_development

test:
  <<: *default
  database: JSMCreserveapp_test
  host: <%= ENV.fetch("APP_DATABASE_HOST") { 'db' } %>

production:
  <<: *default
  database: <%= ENV['APP_DATABASE'] %>
  host: <%= ENV['APP_DATABASE_HOST'] %>
  username: <%= ENV['APP_DATABASE_USERNAME'] %>
  password: <%= ENV['APP_DATABASE_PASSWORD'] %>

FROM ruby:2.7.5

ENV RAILS_ENV=production

RUN 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 -qq \
  && apt-get install -y nodejs yarn
WORKDIR /app
COPY . /app
RUN bundle config --local set path 'vendor/bundle' \ 
  && bundle install

COPY start.sh /start.sh
RUN chmod 744 /start.sh
CMD ["sh", "/start.sh"]
dockercompose.yml
version: '3'
services:
  db:
    image: mysql:8.0
    command: --default-authentication-plugin=mysql_native_password
    volumes:
      - ./db/mysql_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/app
    ports:
      - "3000:3000"
    environment:
      RAILS_ENV: development
    depends_on:
      - db

補足情報(FW/ツールのバージョンなど)

ruby '2.7.5'
rails '6.1.6'

0

2Answer

@keiino0425

$ docker-compose up
# 別ターミナルで
$ docker-compose exec web bash
$ bundle exec rails db:create
$ bundle exec rails db:migrate RAILS_ENV=test
$ bundle exec rspec

とかするとどうなります?

1Like

Comments

  1. @keiino0425

    Questioner

    ご回答ありがとうございます!

    上記の通りにやるとdatabaseが作成されてrspecが作動しました!

    しかし、一度docker-compose downをしたのちに
    bundle exec rspec
    を行うと

    ```
    ActiveRecord::ConnectionNotEstablished:
    Unknown MySQL server host 'db' (-2)
    ```

    というエラーが表示されてしまいます。

    https://qiita.com/SyoInoue/items/2ed5b3017c517920ec09
    こちらの記事などを参考にしましたが解決には至りませんでした。

    もしよろしければアドバイスなどお願いします。
  2. @keiino0425
    上記で down で落とすまでは動くということは
    db サービスの永続化がうまくいっていない気がします。
    この回答の次に回答している `docker-compose.yml` に修正した後に
    この回答の手順をやるとどうなるか試してもらっても良いですかね
  3. @keiino0425

    Questioner

    ご回答ありがとうございます!

    上手く永続化でき、エラーも無事消えました!

    本当にありがとうございます!!

@keiino0425
後は、以下とかにするとどうなります。

docker-compose.yml
version: '3'
services:
  db:
    image: mysql:8.0
    command: --default-authentication-plugin=mysql_native_password
    volumes:
      - ./db/mysql_data:/var/lib/mysql # 削除
      - db_data:/var/lib/mysql         # 追加
    environment:
      MYSQL_ROOT_PASSWORD: password
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/app
    ports:
      - "3000:3000"
    environment:
      RAILS_ENV: development
    depends_on:
      - db

volumes:           # 追加
  db_data:         # 追加
    driver: local  # 追加
0Like

Your answer might help someone💌