現在docker-composeを用いてRailsアプリケーションを開発しており,
本番環境へのリリースとしてHerokuへのデプロイを行っている途中でエラーが発生している状態です.
やったこと
こちらのQiita記事やherokuのdocsを参照しながら以下のコマンドを実行していきました.
ここまでは何のエラーもなく通っています.
(herokuへログイン済み)
$ heroku container:push web
$ heroku container:release web
$ heroku addons:create cleardb:ignite
$ heroku config
=== myapp Config Vars
CLEARDB_DATABASE_URL: mysql://xxx
$ heroku config:set DATABASE_URL='mysql2://xxx'
Setting DATABASE_URL and restarting ⬢ myapp... done, v21
DATABASE_URL: mysql2://xxx
$ heroku config:set RAILS_ENV='production'
Setting RAILS_ENV and restarting ⬢ myapp... done, v22
RAILS_ENV: production
発生している問題
以上のコマンドに引き続きdb:create
を実行した際に以下のエラーが発生しています.
$ heroku run rails db:create
Running rails db:create on ⬢ myapp... up, run.9235 (Free)
rails aborted!
NameError: Cannot load database configuration:
undefined local variable or method `root' for main:Object
(erb):19:in `block in <main>'
(erb):19:in `fetch'
(erb):19:in `<main>'
/usr/local/bundle/gems/railties-5.2.4.1/lib/rails/application/configuration.rb:172:in `database_configuration'
/usr/local/bundle/gems/activerecord-5.2.4.1/lib/active_record/railtie.rb:39:in `block (3 levels) in <class:Railtie>'
/usr/local/bundle/gems/railties-5.2.4.1/lib/rails/commands/rake/rake_command.rb:23:in `block in perform'
/usr/local/bundle/gems/railties-5.2.4.1/lib/rails/commands/rake/rake_command.rb:20:in `perform'
/usr/local/bundle/gems/railties-5.2.4.1/lib/rails/command.rb:48:in `invoke'
/usr/local/bundle/gems/railties-5.2.4.1/lib/rails/commands.rb:18:in `<main>'
/usr/local/bundle/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require'
/usr/local/bundle/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `block in require_with_bootsnap_lfi'
/usr/local/bundle/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
/usr/local/bundle/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `require_with_bootsnap_lfi'
/usr/local/bundle/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
/usr/local/bundle/gems/activesupport-5.2.4.1/lib/active_support/dependencies.rb:291:in `block in require'
/usr/local/bundle/gems/activesupport-5.2.4.1/lib/active_support/dependencies.rb:257:in `load_dependency'
/usr/local/bundle/gems/activesupport-5.2.4.1/lib/active_support/dependencies.rb:291:in `require'
/katagami-ant/bin/rails:9:in `<top (required)>'
/usr/local/bundle/gems/spring-2.1.0/lib/spring/client/rails.rb:28:in `load'
/usr/local/bundle/gems/spring-2.1.0/lib/spring/client/rails.rb:28:in `call'
/usr/local/bundle/gems/spring-2.1.0/lib/spring/client/command.rb:7:in `call'
/usr/local/bundle/gems/spring-2.1.0/lib/spring/client.rb:30:in `run'
/usr/local/bundle/gems/spring-2.1.0/bin/spring:49:in `<top (required)>'
/usr/local/bundle/gems/spring-2.1.0/lib/spring/binstub.rb:11:in `load'
/usr/local/bundle/gems/spring-2.1.0/lib/spring/binstub.rb:11:in `<top (required)>'
/katagami-ant/bin/spring:15:in `<top (required)>'
bin/rails:3:in `load'
bin/rails:3:in `<main>'
考えうる原因
/usr/local/bundle/gems/railties-5.2.4.1/lib/rails/application/configuration.rb:172:in `database_configuration'
エラーが発生したコードは以上の部分ということだったので, database_configuration
について調べてみると
Loads and returns the entire raw configuration of database from values stored in
config/database.yml
.
ということで, どうもconfig/database.yml
が怪しいと分かりました.
heroku config
で設定した環境変数が読み込まれているかを確認するために,
initializers/
の適当なファイルに以下を置いてみましたが問題ないようでした.
p ENV['DATABASE_URL']
p ENV['RAILS_ENV']
$ heroku run rails db:create
Running rails db:create on ⬢ myapp... up, run.2733 (Free)
"mysql2://xxx"
"production"
rails aborted!
NameError: Cannot load database configuration:
undefined local variable or method `root' for main:Object
...
関連のあるコード
version: "3"
services:
web:
build: .
command: /bin/sh -c "rm -f /myapp/tmp/pids/server.pid && bundle exec rails s -p '3001' -b '0.0.0.0'"
tty: true
stdin_open: true
# environment:
# - DATABASE=myapp_development
# - DATABASE_USER=root
# - DATABASE_PASSWORD=password
# - DATABASE_HOST=db
volumes:
- .:/katagami-ant
ports:
- 3001:3001
depends_on:
- db
- redis
db:
image: mysql:5.7
command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
environment:
- MYSQL_DATABASE=myapp_development
- MYSQL_ROOT_USER=root
- MYSQL_ROOT_PASSWORD=password
volumes:
- mysql_vol:/var/lib/mysql
ports:
- 3306:3306
redis:
image: redis
ports:
- 6379:6379
volumes:
- "./app/redis:/data"
volumes:
mysql_vol:
default: &default
adapter: mysql2
encoding: utf8
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
development:
<<: *default
# username: <%= ENV.fetch("DATABASE_USER") { root } %>
# password: <%= ENV.fetch("DATABASE_PASSWORD") { password } %>
# host: <%= ENV.fetch("DATABASE_HOST") { db } %>
# database: <%= ENV.fetch("DATABASE") { katagami-ant_development } %>
production:
<<: *default
url: <%= ENV['DATABASE_URL'] %>
実現したいこと
heroku run db:create
を実行したい.
開発環境
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.15.1
BuildVersion: 19B88
$ docker -v
Docker version 19.03.1, build 74b1e89
$ docker-compose -v
docker-compose version 1.24.1, build 4667896b
解決
config/database.yml
において,
username: <%= ENV.fetch("DATABASE_USER") { root }
のrootを
ちゃんと文字列にしてなかったのが原因でした.
以下のように他の部分もクォーテーションで囲って実行すると上手くいきました.
コメントアウトが効いてないのかな...ちょっと謎いです...
development:
<<: *default
# username: <%= ENV.fetch("DATABASE_USER") { 'root' } %>
# password: <%= ENV.fetch("DATABASE_PASSWORD") { 'password' } %>
# host: <%= ENV.fetch("DATABASE_HOST") { 'db' } %>
# database: <%= ENV.fetch("DATABASE") { 'katagami-ant_development' } %>