Django with GDAL throwing error when deploying on Heroku

When I deploy my Django app with Heroku there seems to be some problem with GDAL. When I run heroku logs --tail I get the following:

[...]
2022-01-14T11:20:56.792392+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/contrib/gis/db/backends/postgis/base.py", line 6, in <module>
2022-01-14T11:20:56.792393+00:00 app[web.1]: from .features import DatabaseFeatures
2022-01-14T11:20:56.792393+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/contrib/gis/db/backends/postgis/features.py", line 1, in <module>
2022-01-14T11:20:56.792394+00:00 app[web.1]: from django.contrib.gis.db.backends.base.features import BaseSpatialFeatures
2022-01-14T11:20:56.792394+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/contrib/gis/db/backends/base/features.py", line 3, in <module>
2022-01-14T11:20:56.792394+00:00 app[web.1]: from django.contrib.gis.db import models
2022-01-14T11:20:56.792395+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/contrib/gis/db/models/__init__.py", line 3, in <module>
2022-01-14T11:20:56.792395+00:00 app[web.1]: import django.contrib.gis.db.models.functions  # NOQA
2022-01-14T11:20:56.792395+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/contrib/gis/db/models/functions.py", line 3, in <module>
2022-01-14T11:20:56.792396+00:00 app[web.1]: from django.contrib.gis.db.models.fields import BaseSpatialField, GeometryField
2022-01-14T11:20:56.792401+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/contrib/gis/db/models/fields.py", line 3, in <module>
2022-01-14T11:20:56.792401+00:00 app[web.1]: from django.contrib.gis import forms, gdal
2022-01-14T11:20:56.792402+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/contrib/gis/forms/__init__.py", line 3, in <module>
2022-01-14T11:20:56.792402+00:00 app[web.1]: from .fields import (  # NOQA
2022-01-14T11:20:56.792402+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/contrib/gis/forms/fields.py", line 2, in <module>
2022-01-14T11:20:56.792402+00:00 app[web.1]: from django.contrib.gis.gdal import GDALException
2022-01-14T11:20:56.792403+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/contrib/gis/gdal/__init__.py", line 28, in <module>
2022-01-14T11:20:56.792406+00:00 app[web.1]: from django.contrib.gis.gdal.datasource import DataSource
2022-01-14T11:20:56.792407+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/contrib/gis/gdal/datasource.py", line 40, in <module>
2022-01-14T11:20:56.792407+00:00 app[web.1]: from django.contrib.gis.gdal.driver import Driver
2022-01-14T11:20:56.792407+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/contrib/gis/gdal/driver.py", line 5, in <module>
2022-01-14T11:20:56.792407+00:00 app[web.1]: from django.contrib.gis.gdal.prototypes import ds as vcapi, raster as rcapi
2022-01-14T11:20:56.792408+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/contrib/gis/gdal/prototypes/ds.py", line 9, in <module>
2022-01-14T11:20:56.792408+00:00 app[web.1]: from django.contrib.gis.gdal.libgdal import GDAL_VERSION, lgdal
2022-01-14T11:20:56.792408+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/contrib/gis/gdal/libgdal.py", line 53, in <module>
2022-01-14T11:20:56.792409+00:00 app[web.1]: lgdal = CDLL(lib_path)
2022-01-14T11:20:56.792409+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/ctypes/__init__.py", line 374, in __init__
2022-01-14T11:20:56.792409+00:00 app[web.1]: self._handle = _dlopen(self._name, mode)
2022-01-14T11:20:56.792409+00:00 app[web.1]: OSError: /opt/homebrew/opt/gdal/lib/libgdal.dylib: cannot open shared object file: No such file or directory
2022-01-14T11:20:56.792410+00:00 app[web.1]: [2022-01-14 11:20:56 +0000] [10] [INFO] Worker exiting (pid: 10)
2022-01-14T11:20:56.895552+00:00 app[web.1]: [2022-01-14 11:20:56 +0000] [4] [WARNING] Worker with pid 10 was terminated due to signal 15
2022-01-14T11:20:56.993856+00:00 app[web.1]: [2022-01-14 11:20:56 +0000] [4] [INFO] Shutting down: Master
2022-01-14T11:20:56.993930+00:00 app[web.1]: [2022-01-14 11:20:56 +0000] [4] [INFO] Reason: Worker failed to boot.
2022-01-14T11:20:57.168821+00:00 heroku[web.1]: Process exited with status 3
[...]

I'm using a PostgreSQL database with postgis enabled (it is a geolocation app).

I've installed this buildpack and my requirements.txt file has GDAL==2.4.0 in there (which aligns with the version the buildpack appears to install).

My understanding of dylibs is that they are a MACOS filetype - therefore Heroku is pointing to my local machine for GDAL rather than a Heroku dyno, I'm fairly new to all this but I believe I need to figure out why this is happening and how to change where Heroku is searching for GDAL.

Requirements.txt:

asgiref==3.4.1
beautifulsoup4==4.10.0
bs4==0.0.1
certifi==2021.10.8
cffi==1.15.0
charset-normalizer==2.0.10
cryptography==36.0.1
defusedxml==0.7.1
dj-database-url==0.5.0
Django==4.0.1
django-allauth==0.47.0
django-bootstrap-modal-forms==2.2.0
django-heroku==0.3.1
django-on-heroku==1.1.2
django-widget-tweaks==1.4.11
djangorestframework==3.13.1
GDAL==2.4.0
gunicorn==20.1.0
idna==3.3
oauthlib==3.1.1
psycopg2==2.9.3
psycopg2-binary==2.9.3
pycparser==2.21
PyJWT==2.3.0
python3-openid==3.2.0
pytz==2021.3
requests==2.27.1
requests-oauthlib==1.3.0
soupsieve==2.3.1
sqlparse==0.4.2
urllib3==1.26.8
whitenoise==5.3.0

Okay, how I fixed this:

  1. Make sure there is nothing funky to do with GDAL in your settings.py - I had followed this answer to get GDAL working on my local server during development and had to delete it the Paths from my settings.py
  2. pip uninstall GDAL
  3. pip freeze > requirements. txt
  4. Add the heroku-geo-buildpack (link) and make sure it is set as the first buildpack for your app
  5. git commit all your changes
  6. Push the app again