Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

`initialize': the scheme postgres does not accept registry part: postgres:@ (or bad hostname?) (URI::InvalidURIError) with Docker

I'm using Rails with Postgres DB Docker container attached. It looks like I'm getting below error when I run rails c:

/usr/local/rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/uri/generic.rb:204:in `initialize': the scheme postgres does not accept registry part: postgres:@ (or bad hostname?) (URI::InvalidURIError)

Is there a reason why this isn't working?

My database.yml is:

production:
  <<: *default
  url: <%= ENV['DATABASE_URL'] %>

$DATABASE_URL is defined

Interestingly it was working for a few days until yesterday and stopped working again today.

Below is what Rails 4.2.1 generates!

# As with config/secrets.yml, you never want to store sensitive information,
# like your database password, in your source code. If your source code is
# ever seen by anyone, they now have access to your database.
#
# Instead, provide the password as a unix environment variable when you boot
# the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database
# for a full rundown on how to provide these environment variables in a
# production deployment.
#
# On Heroku and other platform providers, you may have a full connection URL
# available as an environment variable. For example:
#
#   DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase"
#
# You can use this database configuration with:
#
#   production:
#     url: <%= ENV['DATABASE_URL'] %>

Why on earth would they recommend env variable that is reserved!?

UPDATE: Actually this is still not fixed. It looks like environment variable is not being picked up from database.yml file when running rails runner which is run by cron task to invoke Sidekiq worker job (using Whenever). I had to put url: static value instead to get it working for now but given that docker ip changes every time its run from the image I would prefer rails runner to pick up environment variables properly. This may be related to https://github.com/rails/rails/issues/19256#issuecomment-102980786 but the solution didn't work either.

like image 956
Passionate Engineer Avatar asked Dec 08 '15 07:12

Passionate Engineer


3 Answers

Rename your environment variable!

DATABASE_URL is reserved by Rails, and interpreted by ActiveRecord itself. I ran into the same issue.

Instead, use something like this:

    host:     <%= ENV['DB_HOST'] %>
    password: <%= ENV['DB_PWD'] %>
like image 111
Tilo Avatar answered Oct 18 '22 20:10

Tilo


The accepted answer is wrong. There's nothing wrong with using DATABASE_URL in your database.yml, although doing so explicitly is probably redundant. The problem is with the value of the URL.

ActiveRecord uses URI::RFC2396_Parser to parse database URLs. The error message above indicates that it's not able to parse the URL, probably because the hostname is missing, cf.

URI::RFC2396_Parser.new.parse('postgres://postgres:@/mydb')
# Traceback (most recent call last):
#       1: from (irb):30
# URI::InvalidURIError (the scheme postgres does not accept registry part: postgres:@ (or bad hostname?))

Other invalid hostnames, such as hostnames with underscores (common in docker-compose setups) will cause similar errors:

URI::RFC2396_Parser.new.parse('postgres://postgres:postgres@my_postgres/mydb')
# Traceback (most recent call last):
#        1: from (irb):34
# URI::InvalidURIError (the scheme postgres does not accept registry part: postgres:postgres@my_postgres (or bad hostname?))

What can be especially confusing is that URI.parse() uses URI::RFC3986_Parser, which is much more forgiving, and will accept either of these "bad" URLs.

like image 20
David Moles Avatar answered Oct 18 '22 20:10

David Moles


From the "Configuring Rails Applications" guide, it would appear that DATABASE_URL is used for configuring database access. Another way to configure database access is the presence of the file config/database.yml. Trying to use both methods to configure database access causes the issue you are facing.

if your password contains unsafe characters

Connection string used for DATABASE_URL cannot contain special characters (anything other than [a-zA-Z0-9_~-\.], e.g. @ is a common one to mess up). Solution is to url-encode.

if you are using dokku

  • https://github.com/Kloadut/dokku-pg-plugin/issues/76 - Host and Port information are missing
  • https://github.com/dokku/dokku-postgres/issues/28 - Rewritten link command generates invalid host

if you are using pghero

  • https://github.com/ankane/pghero - Fail to start if password contain @
like image 21
dnozay Avatar answered Oct 18 '22 21:10

dnozay