環境
docker compose
mysql
rails6
rails初心者が色々迷走しているうちに様々なエラーに出会ったのでまとめてみます。
エラー
データベースがない時に出るエラーです。
ActiveRecord::NoDatabaseError: Unknown database
対応
データベースがあるかを確認します。
#execコマンドでrailsコンテナの中に入ります。
$ docker exec -it xxxxxxxxxx bash
#railsコンテナの中からmysqlコンテナに接続しつつmysqlを立ち上げます。
root@xxxxxxxxxx:/app# mysql -u root -p -h db
#ここでmysqlが立ち上がらない場合そもそもdockerコンテナ同士の通信がうまく行っていないので下の「dockerコンテナ間の通信を確認する」を見てください。
#mysqlが立ち上がった場合はshow databasesでデータベースがあるか確認します。データベース名はrailsアプリの/config/database.ymlでdatabase: rails_sample_dvなどと記載されています。
MySQL [(none)]> show databases;
#データベースがなかった場合は作成します。
MySQL [(none)]>exit
root@xxxxxxxxxx:/app# rails db:create
root@xxxxxxxxxx:/app# rails db:migrate
これでデータベースが作成されるので0.0.0.0:3000などでアクセスができるようになります。
dockerコンテナ同士がつながっていなそうな場合
docker-compose.ymlの設定を確認します。
以下db接続関連の項目のみを書き出してみます。
これらがない場合は書き足してみてdockerを再構築
(環境によってはimage、volumeを削除してdocker compose build --no-cacheなどとすると確実かもしれません。)
してみて再度ウェブコンテナからmysqlに接続できるかを確認します。
version: "3"
services:
app:
depends_on:
- mysql
mysql:
volumes:
- mysql-volume:/var/lib/mysql
environment:
- MYSQL_ALLOW_EMPTY_PASSWORD=yes
ports:
- "3306:3306"
volumes:
mysql-volume:
railsのdatabase.ymlの記述が間違っていたときのエラー
自分の場合は以下のエラーがブラウザでアクセスした時に出ました。
ActiveRecord::ConnectionNotEstablished
No connection pool for 'ActiveRecord::Base' found.
Puma caught this error: Cannot load database configuration:
そしてその状態でrails consoleを立ち上げようとして以下のエラーに遭遇
webapp/config/database.yml:33:in `<main>': Cannot load database configuration:
undefined method `[]' for nil:NilClass (NoMethodError)
ちなみにその時のdatabase.ymlは以下
default: &default
adapter: mysql2
encoding: utf8mb4
pool: 5
timeout: 3306
host: mysql
development:
<<: *default
username: root
host: mysql
database: rails_sample_dv
socket: /tmp/mysql.sock
# test:
# <<: *default
# username: root
# host: <%= ENV['DB_HOST'] %>
# database: rails_sample_dv
# socket: /tmp/mysql.sock
# production:
# <<: *default
# username: <%= Rails.application.credentials.db[:user] %>
# host: <%= Rails.application.credentials.db[:host] %>
# password: <%= Rails.application.credentials.db[:password] %>
# database: <%= Rails.application.credentials.db[:name] %>
これはなぜかコメントアウトしている行が読み込まれているようで
以下のようにコメントアウトしている部分を削除したらとりあえずエラーは解消されました。
default: &default
adapter: mysql2
encoding: utf8mb4
pool: 5
timeout: 3306
host: mysql
development:
<<: *default
username: root
host: mysql
database: rails_sample_dv
socket: /tmp/mysql.sock
master.key、credentials.yml.encを作り直してみる
railsアプリの/configディレクトリにmaster.key、credentials.yml.encというファイルがあります。
これらがなかったり、なんらかの影響で変更されたりした場合railsアプリが立ち上がらない場合があります。
そんな時は念の為2つのファイルをバックアップしてから
作成し直すことでアプリが立ち上がる場合もあります。
作成し直す際は前述同様docker execコマンドでrailsコンテナにログインしてから以下のコマンドで再生成します。
EDITOR=vim rails credentials:edit
場合によってはsudoをつけたほうが良いかもしれません。
そもそもmaster.key、credentials.yml.encとは?
いわゆるサーバで設定する環境変数をrails内で設定できるという仕組みで
master.key(秘密鍵)、credentials.yml.enc(公開鍵)といった具合に
1組の対になっています。
ですから何らかの拍子で一つが変わったりする場合エラーになります。
またmaster.keyは必ず.gitignoreなどに記載し、公開されないように
デプロイツールに登録しなければなりません。
#番外編|コンテナが立ち上がらない
railsのWebサーバが立ち上がっていない状態です。
$ docker compose up -d
$ docker container ls
cfxxxxxxa776 mysql:5.7 "docker-entrypoint.s…" 1 minutes ago Up 1 minutes 0.0.0.0:3306->3306/tcp, 33060/tcp webapp-db-1
対応方法
/tmp/pids/server.pid
というファイルを削除しコンテナを再度立ち上げると無事ウェブサーバが立ち上がりました。
これはrails特有のお作法でよくある原因とのことでした。