Search code examples
rubyruby-on-rails-4dokkurgeo

Getting RGeo GEOS support to work in a Rails app deployed to Dokku


I have a rails app that uses the RGeo gem and I'm having a hard time getting the gem to install with support for the underlying GEOS library which my app requires to work properly.

Typically you can run RGeo::Geos.supported? from the rails console and it will return true if GEOS is supported, false otherwise. This works on my devel machine (OS X) but always returns false on my Dokku container.

I am using build packs to pull these libraries in, here is the contents of my .buildpack file:

https://github.com/cyberdelia/heroku-geo-buildpack.git#1.3
https://github.com/heroku/heroku-buildpack-ruby.git#v141

This does seem to at least partially work since the gem is picking up the PROJ.4 library. This can be checked by running RGeo::CoordSys::Proj4.supported? in the rails console, which returns true on my Dokku deployment.

When I deploy the app the build pack appears to be working without any issues:

-----> Cleaning up...
-----> Building demoapp from herokuish...
-----> Adding BUILD_ENV to build environment...
-----> Multipack app detected
=====> Downloading Buildpack: https://github.com/cyberdelia/heroku-geo-buildpack.git
=====> Detected Framework: geos/gdal/proj
   Using geos version: 3.4.2
   Using gdal version: 1.11.1
   Using proj version: 4.8.0_1
-----> Vendoring geo libraries done
=====> Downloading Buildpack: https://github.com/heroku/heroku-buildpack-ruby.git
=====> Detected Framework: Ruby
-----> Compiling Ruby/Rails
-----> Using Ruby version: ruby-2.2.3
-----> Installing dependencies using bundler 1.9.7
   Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin -j4 --deployment

I am using the latest version of Dokku (0.4.10) and the app is currently running on Ruby 2.2.3, Rails 4.2.5.

Edit (for clarification): I need this method call (RGeo::Geos.supported?) to return true in the rails console in my app container. Only then will my app work correctly, currently it is returning false which means that the RGeo gem did not find the GEOS (libgeos) library during installation. There are no errors during the deployment and the log output (relevant section included above) reports that GEOS 3.4.2 is installed via the buildpack. Without GEOS support I'm unable to even seed my database since part of that process involves reading in shapfiles and storing them as geometries via PostGIS. My app also uses many other features that require GEOS via RGeo so it is a requirement that RGeo::Geos.supported? returns true in the console, meaning that GEOS is available via the RGeo gem and features like reading in shapefiles, etc will work.


Solution

  • As pointed out by Jose in the comments you can use the apt-get plugin to install packages into your container during deployment. This allows you to bypass the current problems with the geo buildpack completely.

    After installing the plugin to my Dokku instance, I created an apt-packages file in the root of my project with the following contents:

    libgeos-dev
    libgeos++-dev
    libgdal-dev
    libproj-dev
    

    I removed the geo buildpack (https://github.com/cyberdelia/heroku-geo-buildpack.git#1.3) from my .buildpacks file since that is no longer being used. It's now possible to just get rid of the .buildpacks file altogether and simply create a BUILDPACK_URL environment variable dokku config:set pointing to the ruby buildpack repo.

    After deploying, the RGeo gem now reports GEOS is available since it was now able to build the native extensions during installation:

    irb(main):001:0> RGeo::Geos.supported?
    => true
    

    PROJ.4 still works as well, since I included the library in the apt-packages file:

    irb(main):002:0> RGeo::CoordSys::Proj4.supported?
    => true