Deploying GeoDjango applications on heroku: Easy workthrough
Tags: webdev, django, geodjango, gis
Published: 2021-06-27 04:02:56

## Motivation

Recently, I was in the position to quickly prototype a location-based application. Since Django is pretty awesome for quick scaffolding with all other requirements still intact, I went straight for it using its extenstion [GeoDjango](https://docs.djangoproject.com/en/3.2/ref/contrib/gis/tutorial/)[^1]. The development process was pretty interesting 😌. However, deploying the prototyped application on [Heroku](https://www.heroku.com/) was a huge pain 😢 since resources were sparse and those available were seemingly outdated. 


This guide tends to provide an updated workthrough to overcoming this hurdle.


## Assumption
It is assumed that you have a [GeoDjango](https://docs.djangoproject.com/en/3.2/ref/contrib/gis/tutorial/)[^1] application available for deployment. If not, go through [^1] or [Make a Location-Based Web App With Django and GeoDjango](https://realpython.com/location-based-app-with-geodjango-tutorial/)[^2]. Another assumption is that you have chosen to host your application on Heroku and your database is PostgreSQL.


## Content

Let's get started. Having [configured your application for Heroku deployment](https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Deployment)[^3], append the following to your `settings.py` file.

```python
...
DATABASES['default']['ENGINE'] = 'django.contrib.gis.db.backends.postgis'
```
If you follow Django Tutorial Part 11: Deploying Django to production[^3], it should come directly after:
```python
# Heroku: Update database configuration from $DATABASE_URL.
import dj_database_url
db_from_env = dj_database_url.config(conn_max_age=500)
DATABASES['default'].update(db_from_env)
```
The added code instructs Heroku to use a spatial database extension called [postgis](https://docs.djangoproject.com/en/3.2/ref/contrib/gis/install/postgis/). In most cases, failure to include that line results in this error:

```python
AttributeError: 'DatabaseOperations' object has no attribute 'geo_db_type'
```

Next, we need to add a custom buildpack to our project on heroku. By default, all Python applications are automatically given `heroku/python` official buildpack. However, since our application needs more than just a `python` runtime environment &mdash; our application needs [`GDAL`](https://www.gdal.org/), [`GEOS`](https://trac.osgeo.org/geos/), and [`PROJ`](https://proj4.org/) in addition to a python runtime environment &mdash; we must get the additional environment in place for our application to compile. There are various buildpacks out there for this, however [Heroku Buildpack Geo](https://github.com/heroku/heroku-geo-buildpack) worked seemlessly. 

**NOTE: It should be noted that this buildpack only provides the runtime environments for `GIS` related projects therefore, it cannot be used alone. You still need a python runtime environment for your applications to run.**

Doing this is pretty easy with Heroku since it supports multiple buildpacks.

To add this custom buildpack &mdash; after you created your heroku application using `heroku create application_name` &mdash; follow the steps below:

 - Set the official python buildpack:
    ```bash
    heroku buildpacks:set heroku/python
    ```
 - Insert the custom `heroku-geo-buildpack`:
    ```bash
    heroku buildpacks:add --index 1 https://github.com/heroku/heroku-geo-buildpack.git
    ```
    This will insert the `heroku-geo-buildpack` buildpack at the first position in the order of buildpack execution, and move the other buildpacks that are ahead of it down one position.[^4]

**NOTE: Ensure `heroku-geo-buildpack` buildpack comes first! It installs the basic requirements of a `GIS` application.**

You can confirm it has been included by issuing the following command in your terminal:

```bash
heroku buildpacks
```

You can now happily deploy your application 😊㊗️🎈.

Ran into some issues? The comment session is live 🤗.


[^1]: [GeoDjango Tutorial](https://docs.djangoproject.com/en/3.2/ref/contrib/gis/tutorial/) - by <cite>Official Django Docs</cite>


[^2]: [Make a Location-Based Web App With Django and GeoDjango](https://realpython.com/location-based-app-with-geodjango-tutorial/) - by <cite>Ahmed Bouchefra</cite>

[^3]: [Django Tutorial Part 11: Deploying Django to production](https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Deployment) - by <cite>MDN</cite>

[^4]: [Using Multiple Buildpacks for an App](https://devcenter.heroku.com/articles/using-multiple-buildpacks-for-an-app) - by <cite>Heroku</cite>

## Attribution
 - Cover image: https://www.google.com/url?sa=i&url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DR9ZJZtHY7RY&psig=AOvVaw1PEbujb86dE7nkyQJAv5gU&ust=1624852485065000&source=images&cd=vfe&ved=0CAwQ3YkBahcKEwiw6ee39bbxAhUAAAAAHQAAAAAQAw