Search code examples
herokupostgisheroku-postgresheroku-ci

Heroku CI with Postgres postgis extension


I'm using a postgis extension to my database on Heroku. In production this works just fine; I'm mapping like a boss.

But, I can't get my app to build on HerokuCI because the database addon in the test environment doesn't have GDAL installed (part of the postgis extension):

django.core.exceptions.ImproperlyConfigured: Could not find the GDAL library (tried "gdal", "GDAL", "gdal2.3.0", "gdal2.2.0", "gdal2.1.0", "gdal2.0.0", "gdal1.11.0"). Is GDAL installed? If it is, try setting GDAL_LIBRARY_PATH in your settings.
-----> test command `python manage.py migrate --noinput && python manage.py test` failed with exit status 1

I can't find out how to create extensions in the heroku CI environment. Heroku's app json schema say nothing about how to create extensions on the test databases.

I know that I can't use in-dyno database for CI, as postgis is not an available extension for that, but I'm not using an in-dyno one, I'm using a plan...

Here's my app schema:

{
  "name": "mymegaapp",
  "scripts": {
    "heroku-prebuild": "create extension postgis",
    "heroku-postbuild": "echo heroku-postbuild script runs here."
  },
  "env": {
  },
  "formation": {
  },
  "addons": [
  ],
  "buildpacks": [
    {
      "url": "heroku/python"
    },
    {
      "url": "heroku/nodejs"
    }
  ],
  "environments": {
    "test": {
      "scripts": {
        "test": "python manage.py migrate --noinput && python manage.py test"
      },
      "env": {
        "DJANGO_DEBUG": "1"
      },
      "addons":[
        {
          "plan": "heroku-postgresql",
          "options": {
            "version": "11"
          }
        },
        "heroku-redis:hobby-dev"
      ]
    }
  }
}

Note that I've tried to create the postgis extension in the prebuild script, which doesn't make a difference.

I've also tried invoking the creation before the test script:

      "scripts": {
        "test": "heroku create extension postgis && python manage.py migrate --noinput && python manage.py test"
      },

which doesn't work because the heroku cli isn't installed in the dyno.

The key questions:

  1. How can I create extensions in HerokuCI?
  2. Is postgis an allowable extension at all in HerokuCI?

Solution

  • You've almost got it. There's no first class support for creating pg extensions directly from the CLI. However, you can pass a statement into psql.

    Try this in your postdeploy or test setup script: psql -c "create extension postgis" $DATABASE_URL As you're aware, you'll need to do this with a real database, not in-dyno. If you've attached the database as something other than DATABASE_URL, you will need to update that in the script.

    [Edit by OP to add useful info] In this case, GDAL libraries will also be needed, which can be installed by setting the BUILD_WITH_GEO_LIBRARIES environment variable to 1. The final working solution in app.json will be:

      "environments": {
        "test": {
          "scripts": {
            "postdeploy": "psql -c \"create extension postgis\" $DATABASE_URL",
            "test": "python manage.py migrate --noinput && python manage.py test"
          },
          "env": {
            "DJANGO_DEBUG": "1",
            "BUILD_WITH_GEO_LIBRARIES": "1"
          },
          "addons":[
            {
              "plan": "heroku-postgresql",
              "options": {
                "version": "11"
              }
            }
          ]
        }
      }