Libgeos not recognized in CircleCI 2.0 environment

ruby

#1

I’m upgrading a project from Circle 1.0 and ran into an issue related to the library RGeo whenever I use test that call “shape.contains?”

RGeo::Error::UnsupportedOperation:
Method Geometry#contains? not defined.

This error is usually because the geos library is not installed on the host machine. However, I’ve already added the required libs to the config (they install successfully when CI is running):

sudo apt-get install postgis
sudo apt-get install libgeos-dev
sudo apt-get install libgeos++-dev
sudo apt-get install libproj-dev

I’m using the following three images:

docker:
 - image: circleci/ruby:2.4.1-node
   environment:
     PGHOST: 127.0.0.1
     PGUSER: root
 - image: circleci/postgres:10.4-alpine-postgis
   environment:
     POSTGRES_USER: root
     POSTGRES_DB: spin-web_test
 - image: redis:4.0.9

Rgeo-proj4 & postgis config for CircleCi 2.0
#2

Aha, I think I can spot this. Is this a PostgreSQL server extension?

Your first image is circleci/ruby:2.4.1-node, which becomes the build container that all build commands are done in. Your second image circleci/postgres:10.4-alpine-postgis is spun up as a separate container.

That means any apt-get install commands you execute will be done in the context of the first container, not the second.

To solve this, you will need to create an image based on circleci/postgres:10.4-alpine-postgis, install the database server extensions you want, and then pull this from your own registry. There are docs on using custom images.

You can, if you wish, set up a separate CI process to build this custom image. If you do so, you can rebuild the image on a schedule, so it pulls the latest version of the parent.


#4

@halfer I’ve done the suggestion (used 10.4-postgis instead because alpine didn’t have all the necessary packages), even installed the libraries on the ruby container, but the error is still there:

RGeo::Error::UnsupportedOperation: Method Geometry#contains? not defined.

Extract from config.yml:

docker:
- image: circleci/ruby:2.4.1-node
  environment:
    PGHOST: 127.0.0.1
    PGUSER: root
- image: szpasztor/postgres-geos:v1
  environment:
    POSTGRES_USER: root
    POSTGRES_DB: spin-web_test
- image: redis:4.0.9
steps:
- checkout
- run: gem install bundler
- run: 'bundle check --path=vendor/bundle || sudo bundle install --path=vendor/bundle --jobs=4 --retry=3 '    
- run: |
    sudo apt-get update && sudo     apt-get install -y redis-tools
    echo "CONFIG SET save ''" | redis-cli -x
- run: sudo apt-get install postgresql-client
- run:
    name: Waiting for PostgreSQL to start
    command: |
        for i in 'seq 1 10';
        do
          nc -z localhost 5432 && echo Success && exit 0
          echo -n .
          sleep 2
        done
        echo Failed waiting for Postgres && exit 1
- run: sudo mkdir -p $CIRCLE_ARTIFACTS $CIRCLE_TEST_REPORTS
[...some unrelated config...] 
- run: bundle exec rake db:create db:structure:load --trace
- run: sudo mkdir -p $CIRCLE_TEST_REPORTS/rspec
- run: sudo chmod -R 777 /tmp/circleci-test-results/
- run: sudo apt-get update && sudo apt-get -y install postgis libgeos-dev libgeos++-dev libproj-dev imagemagick
- run: bundle exec rspec --color --require spec_helper --format RspecJunitFormatter --out $CIRCLE_TEST_REPORTS/rspec/rspec.xml --format progress $(circleci tests glob spec/**/*_spec.rb | circleci tests split)

Any ideas? One thing I’ve thought of is that the package is installed but not available to rspec, but that should not be a problem since apt-get install automatically makes newly installed packages available right away.


#8

So my general feedback is that you need to make sure that:

  • Your build container has the right Ruby libraries
  • Your database container has the right database extension binaries

Are there some simple command(s) you can issue in both to show what is missing?

For example, can you get an SSH session into your build container, then use psql to connect to the database, and issue a SQL command that will only work if the database extensions are installed? That will either expose this as the problem or eliminate it as the problem.


#9

Hey @halfer , I fixed the filename. So the answer to both question should be yes - bundle install successfully installs the rgeo-geojson gem, and the required apt libs also install just fine. Since this is a ruby library, there isn’t a way (as far as I know) to check it via SQL, but it’s possible to verify with a command in the loaded rails environment. I tried it in a CI run and it failed:

> RGeo::Geos.supported?
 => false

Here’s a related question, from which I already applied the accepted solution: https://github.com/rgeo/rgeo/issues/143#issuecomment-232102725

I think this might potentially be a bug with the rgeo-geojson gem and not the docker/circleci environment. What do you think?


#10

Sure, but one part of your solution is to install PostgreSQL extensions. That must be independently checkable, since by definition it provides more functionality to the database server. I still think you should do this first - your gems won’t work if this extension doesn’t work, right?

Agreed - most problems are not to do with CI. The most common issue is that a system/library/whatever doesn’t work in a specific CI environment - that’s just a Linux problem. And library bugs are a possibility too, as you say.


#14

About checking the postgres extension: unfortunately there’s not much that I think can be done regardless of whether the SQL command returns true/false - at least I haven’t found any forums/discussions where apt-get succeeds but the library isn’t actually installed. After all, this seems like a environment/library incompatibility bug - I’ll try using the machine executor or even macos and see how it goes. Do you think there’s a better option?


#15

Yes to the machine executor (I don’t think it will make a difference, but it’s a one-line change). I’d say no to the MacOS executor, it’s a total OS change so that’s probably not going in the right direction.

OK, so you’re assuming the database extension works, fair enough. I wonder if your apt-get install for the Gem is upgrading one version of Ruby and you’re invoking another? That might be worth looking at next. Is there a comment you can use to list the libraries Ruby thinks it has installed?

Or you could build your own image from scratch so that there is only one Ruby on there.


#16

The development environment we use for the app is all mac based and the specs run fine, so setting that up could be a last resort if all else fails.

I’m pretty sure Ruby is aware of the library, because the class of the exception that’s raised (RGeo::Error::UnsupportedOperation) is defined by the library itself. If the gem wasn’t available/loaded, the exception couldn’t have been raised in the first place.

Or you could build your own image from scratch so that there is only one Ruby on there.

I already did, but it had multiple strange errors resulting from multiple servers (redis, postgres and ruby) running and colliding on a single container. Also, in light of what I mentioned above, this would solve a probably non-existant problem anyway (ruby unaware of the library). So I wouldn’t explore that route further.


#17

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.