Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

running on Heroku #14

Closed
andyvb opened this issue Dec 19, 2011 · 51 comments
Closed

running on Heroku #14

andyvb opened this issue Dec 19, 2011 · 51 comments

Comments

@andyvb
Copy link

andyvb commented Dec 19, 2011

Have you tried running your adapter on Heroku? Out of the box you end up needing to modify the Heroku config variable DATABASE_URL to use the 'postgis' adapter. Wondering if you had any suggestions on how to do this without editing the DATABASE_URL, so things like heroku pg:promote still works.

@nodrog
Copy link

nodrog commented Jan 24, 2012

as far as i know you cannot use postgis on heroku currently, they have not included the pg extension, although they are doing some testing, you can email them to add a beta service to your database.

@dazuma
Copy link
Member

dazuma commented Feb 22, 2012

Unfortunately, I can't support Heroku right now, as I don't use them, nor do I have any immediate plans to use them. If someone else knows how to set it up, and wants to send me a pull request to improve the integration, that would be great, but it's not something I can solve myself.

I'll leave this issue open for the time being.

@nodrog
Copy link

nodrog commented Mar 7, 2012

An update...

There is company that have a heroku add-on https://addons.heroku.com/spacialdb

and heroku have a beta version of postgis running for any dedicated database http://devcenter.heroku.com/articles/is-postgis-available

@WearyMonkey
Copy link

We have been running on Heroku successfully using the beta postgis addon.

To create the schema we connected to the heroku database from a locally running instance of our rails app, so the rake task could access the required postgis schema files.

Then we changed the DATABASE_URL Heroku env variable (using 'heroku config') to use the postgis adapter instead of postgres, e.g. 'postgis://...'

A downside is the the pgbackups addon doesn't work after changing the DATABASE_URL.

@quartzmo
Copy link

Thanks WearyMonkey, changing DATABASE_URL also worked for me, I appreciate you posting.

@softwaregravy
Copy link

We're also running on Heroku with no problems

resolve issue?

@peteonrails
Copy link

+1 for closing the issue. Heroku should provide a command to properly promote PostGIS enabled databases to DATABASE_URL, but there's nothing to change in activerecord-postgis-adapter here. For posterity's sake, you don't need to create the schema from a local instance if you create the PostGIS extension on Heroku using psql first. It'll correctly install the spatial reference system and such without needing the SQL files.

@dazuma
Copy link
Member

dazuma commented Mar 8, 2013

Ideally we don't want to have to modify DATABASE_URL since, as some commenters have pointed out, some of the addon tasks (like backup, which is pretty important!) don't work unless the schema is postgres://.

I'm actually working with one of the Heroku engineers now on a solution. We may be able to get that to land in the next couple weeks. I'll keep this open until then.

@quarterdome
Copy link

@dazuma, agree that ideally DATABASE_URL should not be modified. I am wondering why did you decide to call the adapter something else in database.yml (postgis) instead of just piggy backing on the existing postgres (like what https://github.com/nofxx/postgis_adapter did)?

My thinking is that PostGIS is just an extension to PostgreSQL, and changing an adapter name for each extension one uses won't scale (e.g. what if one day you use two extensions?). I was chatting with @pvh at Heroku during their Waza conference about it, and he had some good ideas how to handle that. Perhaps you guys should connect?

@quarterdome
Copy link

Another indication that changing an adapter name may not be good idea is that as of now running rails dbconsole produces an error:

avalanche:postgis_on_rails matt$ rails db
Unknown command-line client for postgis_on_rails_development. Submit a Rails patch to add support!

@softwaregravy
Copy link

@dazuma @quarterdome Holy $#&!. I did not realize that changing from postgres to postgis would break heroku backups. I haven't been doing backups in months. Thanks for pointing this out. This is a big one

@WearyMonkey
Copy link

To fix the backups problem, we monkey patched the database_configuration method by adding the below code to application.rb. Then left DATABASE_URL as the default. Neither an elegant or permanent solution, but works and might help people who want both backups and postgis to work right now before a proper fix is released.

# add to application.rb application class
# override the adapter setting to 'postgis' as heroku DATABASE_URL must be
# set to postgres
def config.database_configuration
  parsed = super
  parsed.each_value { |config| config['adapter'] = 'postgis' }
end

@softwaregravy
Copy link

@WearyMonkey Thanks

@pvh
Copy link

pvh commented Mar 26, 2013

hey guys! yeah, please don't override the protocol. it's still postgres,
and the postgres://blahblahblah/ URL format is now accepted by libpq and
ultimately we'll work on getting everyone standardized on that in the
future.

On Mon, Mar 25, 2013 at 5:57 PM, John Hinnegan notifications@gh.neting.ccwrote:

@WearyMonkey https://github.com/WearyMonkey Thanks


Reply to this email directly or view it on GitHubhttps://github.com//issues/14#issuecomment-15435157
.

@hgmnz
Copy link

hgmnz commented Mar 29, 2013

Here's another approach. You can throw this in an initializer:

Rails.application.config.after_initialize do
  ActiveRecord::Base.connection_pool.disconnect!

  ActiveSupport.on_load(:active_record) do
    config = Rails.application.config.database_configuration[Rails.env]
    config['adapter'] = 'postgis'
    ActiveRecord::Base.establish_connection(config)
  end
end

@softwaregravy
Copy link

@hgmnz I couldn't get that to work. Maybe a rails version issue?

@WearyMonkey Your approach is working for me. Thanks.

@bricestacey
Copy link

@hgmnz I couldn't get your suggestion to work either. I'm using Rails 4 rc1 and latest master on activerecord-postgis-adapter. Says "could not connect to server: No such file or directory. Is the server running locally and accepting connections on Unix domain socket"

Got it working for now by modifying the DATABASE_URL's schema as @WearyMonkey suggested.

@softwaregravy
Copy link

@WearyMonkey This worked for us on Rails 3.1 it is now broken on Rails 3.2 :(

@WearyMonkey
Copy link

@softwaregravy We're currently using the monkey patch approach from my previous comment on Rails 3.2.11 and it's working fine.

@softwaregravy
Copy link

@WearyMonkey Thanks. We just went from 3.1 to 3.2.13. We are switching to the solution suggested by @hgmnz above which seems to be working in testing.

@smidwap
Copy link

smidwap commented May 29, 2013

Has anyone gotten this working on Rails 4? Both monkey patches aren't working. A peak at the Rails code shows that so long as ENV["DATABASE_URL"] is defined, all other config (database.yml and monkey patch additions) will be ignored.

@smidwap
Copy link

smidwap commented May 30, 2013

To get Heroku to see use the postgis adapter on Rails4, I had to add the following funky monkey patch to application.rb (the main config file):

module ActiveRecord
  class Base
    def self.establish_connection(spec = ENV["DATABASE_URL"].try(:gsub, "postgres", "postgis"))
      super(spec)
    end
  end
end

This substitutes "postgres" in DATABASE_URL with "postgis".

@tompesman
Copy link

I'm running into the same problems on Heroku. Heroku advises to use unicorn and you should reconnect to the database after the fork, undoing the reconnect @hgmnz suggests. This reconnect is needed for the rake/console tasks, but for unicorn you need to adjust the unicorn.rb file.

worker_processes 4
timeout 30
preload_app true

before_fork do |server, worker|

  Signal.trap 'TERM' do
    puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
    Process.kill 'QUIT', Process.pid
  end

  defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!
end

after_fork do |server, worker|

  Signal.trap 'TERM' do
    puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to sent QUIT'
  end

  if defined?(ActiveRecord::Base)
    config = Rails.application.config.database_configuration[Rails.env]
    config['adapter'] = 'postgis'
    ActiveRecord::Base.establish_connection(config)
    Rails.logger.info('Connected to ActiveRecord')
  end
end

With both solutions in place there are multiple reconnects to the database. Probably the monkey patch of @smidwap will work for both unicorn and rake/consoles, but I'm not a bug fan of the monkey patches.

@SubaruWRX55
Copy link

what's about @WearyMonkey suggestion? Seems pretty elegant to me

@hgmnz
Copy link

hgmnz commented Jun 12, 2013

@SubaruWRX55 I'd advice against modifying DATABASE_URL yourself. The reason is that then we (Heroku Postgres) lose the ability to change it without breaking your app.

Reasons to change it include

  • Catastrophic hardware failure and consequent migration to new host,
  • Credentials rotation, initiated by you (eg: heroku pg:credentials --reset) - surely you want the ability to rotate creds on a regular basis.

Further, as was pointed out earlier on this thread, without a valid postgres URL, logical backups (pgbackups) will not be taken (although your data is safe by means of our continuous archiving).

@anthonator
Copy link

Just curious, is there any reason why this gem was written with it's own adapter? Other postgres extensions that I use (postgres_ext and activerecord-postgres-hstore) just extend the postgres adapter.

@tompesman
Copy link

I was also curious and made fork and changed the postgis adapter name to postgresql. It seems to work. There's still some work to do in the databases.rake files. It's just a test.

tompesman/activerecord-postgis-adapter@dca1776

@christopherdbull
Copy link

Has anyone got this working on Rails 4? This is causing me some serious pain currently as Rails refuses to use the correct DB adapter and breaks everything Geo (throwing No Function Matches the Given Name errors).

@futuretap
Copy link

Both patches by @WearyMonkey and @tompesman don't work for me. The database connection is apparently set to postgis correctly (ActiveRecord::Base.connection_config[:adapter] says postgis) but when accessing a geometry column, all I get from the database is an Integer. When I set the DATABASE_URL to postgis, the app works fine. Does the switch from postgres to postgis occur too late in the initialization process perhaps?

I'm on Rails 3.2.13.

@smidwap
Copy link

smidwap commented Jul 16, 2013

@futuretap have you tried the monkey patch I used? Scroll up or #14 (comment)

@futuretap
Copy link

@smidwap it is already self.establish_connection in your code. The crash occurs in the super call. Not sure how I could modify that to call through to the original Rails code?

@smidwap
Copy link

smidwap commented Jul 16, 2013

Hm where did you place this code? It could be that you placed it before the ActiveRecord module is loaded. I had to put it in application.rb

@futuretap
Copy link

@smidwap I have it in application.rb. I tried to put it both before and after the module MyApp block.

@tompesman
Copy link

@futuretap if you have other postgis related parts in your database.yml, you can add them also in the initializer.

config['postgis_extension'] = 'postgis'
config['schema_search_path'] = 'public, postgis'

@smidwap
Copy link

smidwap commented Jul 16, 2013

@futuretap did some more digging. The issue has to do with my fowl treatment of super() in this case. I'm on Ruby 2 which may treat super differently. Anyways try this:

module ActiveRecord
  class Base
    class << self
      alias :monkey_patched_establish_connection :establish_connection

      def monkey_patched_establish_connection(spec = ENV["DATABASE_URL"].try(:gsub, "postgres", "postgis"))
        establish_connection(spec)
      end
    end
  end
end

@futuretap
Copy link

@smidwap, @tompesman thanks for your suggestions. I tried both solutions and at least they load fine. But alas the problem isn't fixed. When I access a geometry column, it's read as a number. Interestingly, there's a

SELECT * FROM geometry_columns WHERE f_table_name='pois'

in the log when accessing it. So the PostGIS driver seems to be at work. But it returns a Fixnum instead of an RGeo object.

Here's the full backtrace (my latitude method returns lat of my Geometry column):

NoMethodError: undefined method `lat' for 101000020:Fixnum
    from /app/app/models/poi.rb:185:in `latitude'
    from (irb):6
    from /app/vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/commands/console.rb:47:in `start'
    from /app/vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/commands/console.rb:8:in `start'
    from /app/vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/commands.rb:41:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'

As soon as I change DATABASE_URL to postgis everything works fine.

@christopherdbull
Copy link

@bricestacey yep I got it working eventually too. Had an unrelated issue it turns out that was breaking things. I imported my database from an old server to heroku and the way it setup postgis was different. When I manually built the database and imported the old data it worked. Still have a couple of issues but the recommended heroku way works for me with Puma (threaded and forked) and ruby 2.0.0 on rails 4

@mattsprig
Copy link

For those like myself who are still having trouble, Heroku has published a devcenter article with a clear workaround: https://devcenter.heroku.com/articles/postgis

Credit goes to @catsby for his comment on this pull request #57

@abatko
Copy link

abatko commented Jun 18, 2014

Has anyone got this working with phusion passenger?

  • rails 4.0.5
  • ruby 2.0.0p481
  • rgeo 0.3.20
  • rgeo-activerecord 1.0.0
  • passenger 4.0.42
  • PostgreSQL 9.3.4
  • POSTGIS 2.1.1 r12113

@abatko
Copy link

abatko commented Jun 19, 2014

The May 29, 2013 solution presented by @smidwap did the trick for me. I placed it at the bottom of config/application.rb but it also worked placed just above Bundler.require(:default, Rails.env). Note that I also have the class ActiveRecordOverrideRailtie < Rails::Railtie block as presented in Heroku's Setting up PostGIS with Rails docs. According to my tests, the ActiveRecordOverrideRailtie block does indeed have to be in config/application.rb, because if placed in config/initializers/postgis.rb (for example) the initializer does not get called.

@mikeatlas
Copy link

I'm on puma here, and still had problems getting the on_load hook to use the right adapter:

ActiveSupport.on_load(:active_record) do
    config = Rails.application.config.database_configuration[Rails.env]
    config['reaping_frequency'] = ENV['DB_REAP_FREQ'] || 10 # seconds
    config['pool']              = ENV['DB_POOL'] || 20
    config['adapter']           = 'postgis'
    ActiveRecord::Base.establish_connection(config)
end

As a side note, I also use resque, and this is in my resque.rb initializer:

Resque.after_fork do
    if defined?(ActiveRecord::Base)
        config = ActiveRecord::Base.configurations[Rails.env]
        config ||= Rails.application.config.database_configuration[Rails.env]
        config['adapter']           = 'postgis'
        ActiveRecord::Base.establish_connection(config)
    end
end

It seems that the only workaround for me was to update DATABASE_URL to use postgis:// like in the original post. The heroku article suggesting that you can change the adapter on load/boot with initializers still wasn't quite good enough to work in my case.

@omphe
Copy link

omphe commented Nov 9, 2015

I got this working successfully on Heroku with the following in my puma.rb

on_worker_boot do
  if defined?(ActiveRecord::Base)
    config = ActiveRecord::Base.configurations[Rails.env] ||
        Rails.application.config.database_configuration[Rails.env]
    config['adapter'] = 'postgis'
    ActiveRecord::Base.establish_connection(config)
  end
    end

on_restart do
  if defined?(ActiveRecord::Base)
    config = ActiveRecord::Base.configurations[Rails.env] ||
        Rails.application.config.database_configuration[Rails.env]
    config['adapter'] = 'postgis'
    ActiveRecord::Base.establish_connection(config)
  end
end

@blackjid
Copy link

This looks like a very old issue, but it's still a problem. I'm using rails 4.1.16 and activerecord-postgis-adapter 2.x

This has been working for me, in the url property in the database.yml file I just replace the adapter before passing it to the configuration:

# config/database.yml
production:
  ...
  url: <%= ENV.fetch("DATABASE_URL", "").gsub(/postgres/, 'postgis') %>

@Drowze
Copy link

Drowze commented Jul 27, 2017

I am using the same setup @blackjid which is working flawlessly so far.

I really would like not to version database.yml though, since it contains the local database credentials (it was on my .gitignore) so I am not that happy with the solution.
What I am doing right now is pushing simply what is needed to heroku and then running git update-index --assume-unchanged config/database.yml, so I can edit it with no much trouble, though trying to checkout old branches that had no database.yml present had led me to some trouble 😢

@softwaregravy
Copy link

@Drowze The recommended way to set up your database.yml is to use environment variables that are set in your config. This issue is specifically concerning Heroku, so I'll refer you to the configs. https://devcenter.heroku.com/articles/config-vars

Your database.yml shouldn't contain any production credentials.

@mjy
Copy link

mjy commented Aug 19, 2020

Perhaps we need a wiki with current standards/gotchas/setup information on Heroku? Maybe someone who uses it can stepup and confirm their setup so we can close this issue?

At minimum we could 1) start a Heroku wiki page and two cross-reference to this closed issue?

@keithdoggett
Copy link
Member

I've set up this wiki that just cross-references this.

If someone wants to make a proper wiki with the info @mjy mentioned that would be great, but I'm going to close the issue now.

lucasgomide added a commit to lucasgomide/entregis that referenced this issue Nov 8, 2020
The activerecord-postgis-adapter does not support Heroku by default. The following commit replace the current DATABASE_URL adapter by postgis.

For more details check out the (issue on github)[rgeo/activerecord-postgis-adapter#14]
lucasgomide added a commit to lucasgomide/entregis that referenced this issue Nov 8, 2020
The activerecord-postgis-adapter does not support Heroku by default. The following commit replaces the current DATABASE_URL adapter by postgis.

For more details check out the (issue on github)[rgeo/activerecord-postgis-adapter#14]
lucasgomide added a commit to lucasgomide/entregis that referenced this issue Nov 8, 2020
The activerecord-postgis-adapter does not support Heroku by default. The following commit replaces the current DATABASE_URL adapter by postgis.

For more details check out the [issue on github](rgeo/activerecord-postgis-adapter#14)
lucasgomide added a commit to lucasgomide/entregis that referenced this issue Nov 8, 2020
The activerecord-postgis-adapter does not support Heroku by default. The following commit replaces the current DATABASE_URL adapter by postgis.

For more details check out the [issue on github](rgeo/activerecord-postgis-adapter#14)
lucasgomide added a commit to lucasgomide/entregis that referenced this issue Nov 8, 2020
The activerecord-postgis-adapter does not support Heroku by default. The following commit replaces the current DATABASE_URL adapter by postgis.

For more details check out the [issue on github](rgeo/activerecord-postgis-adapter#14)
lucasgomide added a commit to lucasgomide/entregis that referenced this issue Nov 10, 2020
The activerecord-postgis-adapter does not support Heroku by default. The following commit replaces the current DATABASE_URL adapter by postgis.

For more details check out the [issue on github](rgeo/activerecord-postgis-adapter#14)
lucasgomide added a commit to lucasgomide/entregis that referenced this issue Nov 10, 2020
The activerecord-postgis-adapter does not support Heroku by default. The following commit replaces the current DATABASE_URL adapter by postgis.

For more details check out the [issue on github](rgeo/activerecord-postgis-adapter#14)
@gagalago
Copy link

gagalago commented Feb 8, 2021

After having again this issue, I just update quickly the wiki. feel free to continue to improve it 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests