Heroku "Application error" on a Django/React app

I'm currently working on a to do list project for my studies and I was able to chose the technologies involved.

I decided to use Django, React, MongoDB for the app and Heroku for the hosting. I had previous experience with React MongoDB and NodeJS and managed to host the app on heroku very easily.

However with this new project I always get an "Application Error" whenever I try to access the website.

I struggled to find up to date information on how to properly host a Django/React app on Heroku and none of the answers I found solved my problem.

What concerns me the most is that the deployment log do not show any major issue during the build process :

> Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 8 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 356 bytes | 356.00 KiB/s, done.
Total 4 (delta 3), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote: 
remote: -----> Building on the Heroku-20 stack
remote: -----> Using buildpacks:
remote:        1. heroku/nodejs
remote:        2. heroku/python
remote: -----> Node.js app detected
remote:        
remote: -----> Creating runtime environment
remote:        
remote:        NPM_CONFIG_LOGLEVEL=error
remote:        NODE_VERBOSE=false
remote:        NODE_ENV=production
remote:        NODE_MODULES_CACHE=true
remote:        
remote: -----> Installing binaries
remote:        engines.node (package.json):  unspecified
remote:        engines.npm (package.json):   unspecified (use default)
remote:        
remote:        Resolving node version 16.x...
remote:        Downloading and installing node 16.16.0...
remote:        Using default npm version: 8.11.0
remote:        
remote: -----> Restoring cache
remote:        - npm cache
remote:        
remote: -----> Installing dependencies
remote:        Installing node modules
remote:        
remote:        added 1457 packages, and audited 1458 packages in 12s
remote:        
remote:        205 packages are looking for funding
remote:          run `npm fund` for details
remote:        
remote:        6 high severity vulnerabilities
remote:        
remote:        To address all issues (including breaking changes), run:
remote:          npm audit fix --force
remote:        
remote:        Run `npm audit` for details.
remote:        
remote: -----> Build
remote:        Running build
remote:        
remote:        > frontend@0.1.0 build
remote:        > react-scripts build
remote:        
remote:        Creating an optimized production build...
remote:        Compiled with warnings.
remote:        
remote:        [eslint] 
remote:        src/components/AppNavbar.js
remote:          Line 1:10:   'Collapse' is defined but never used                                                                                                                                                                                                                                                                                                                                      no-unused-vars
remote:          Line 53:19:  The href attribute requires a valid value to be accessible. Provide a valid, navigable address as the href value. If you cannot provide a valid href, but still need the element to resemble a link, use a button and change it with appropriate styles. Learn more: https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/HEAD/docs/rules/anchor-is-valid.md         jsx-a11y/anchor-is-valid
remote:          Line 57:25:  The href attribute is required for an anchor to be keyboard accessible. Provide a valid, navigable address as the href value. If you cannot provide an href, but still need the element to resemble a link, use a button and change it with appropriate styles. Learn more: https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/HEAD/docs/rules/anchor-is-valid.md  jsx-a11y/anchor-is-valid
remote:          Line 58:25:  The href attribute is required for an anchor to be keyboard accessible. Provide a valid, navigable address as the href value. If you cannot provide an href, but still need the element to resemble a link, use a button and change it with appropriate styles. Learn more: https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/HEAD/docs/rules/anchor-is-valid.md  jsx-a11y/anchor-is-valid
remote:        
remote:        src/components/Body.js
remote:          Line 13:6:  React Hook useEffect has a missing dependency: 'dispatch'. Either include it or remove the dependency array  react-hooks/exhaustive-deps
remote:        
remote:        src/components/TaskElement.js
remote:          Line 59:11:  The href attribute is required for an anchor to be keyboard accessible. Provide a valid, navigable address as the href value. If you cannot provide an href, but still need the element to resemble a link, use a button and change it with appropriate styles. Learn more: https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/HEAD/docs/rules/anchor-is-valid.md  jsx-a11y/anchor-is-valid
remote:          Line 65:13:  The href attribute is required for an anchor to be keyboard accessible. Provide a valid, navigable address as the href value. If you cannot provide an href, but still need the element to resemble a link, use a button and change it with appropriate styles. Learn more: https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/HEAD/docs/rules/anchor-is-valid.md  jsx-a11y/anchor-is-valid
remote:        
remote:        Search for the keywords to learn more about each warning.
remote:        To ignore, add // eslint-disable-next-line to the line before.
remote:        
remote:        File sizes after gzip:
remote:        
remote:          89.81 kB  build/static/js/main.67b777d4.js
remote:          27.94 kB  build/static/css/main.fc8229bc.css
remote:          1.78 kB   build/static/js/787.cda612ba.chunk.js
remote:        
remote:        The project was built assuming it is hosted at /.
remote:        You can control this with the homepage field in your package.json.
remote:        
remote:        The build folder is ready to be deployed.
remote:        You may serve it with a static server:
remote:        
remote:          npm install -g serve
remote:          serve -s build
remote:        
remote:        Find out more about deployment here:
remote:        
remote:          https://cra.link/deployment
remote:        
remote:        
remote: -----> Caching build
remote:        - npm cache
remote:        
remote: -----> Pruning devDependencies
remote:        
remote:        up to date, audited 1458 packages in 3s
remote:        
remote:        205 packages are looking for funding
remote:          run `npm fund` for details
remote:        
remote:        6 high severity vulnerabilities
remote:        
remote:        To address all issues (including breaking changes), run:
remote:          npm audit fix --force
remote:        
remote:        Run `npm audit` for details.
remote:        
remote: -----> Build succeeded!
remote: -----> Python app detected
remote: -----> Using Python version specified in runtime.txt
remote:  !     Python has released a security update! Please consider upgrading to python-3.8.13
remote:        Learn More: https://devcenter.heroku.com/articles/python-runtimes
remote: -----> No change in requirements detected, installing from cache
remote: -----> Using cached install of python-3.8.10
remote: -----> Installing pip 22.1.2, setuptools 60.10.0 and wheel 0.37.1
remote: -----> Installing dependencies with Pipenv 2020.11.15
remote:        Installing dependencies from Pipfile...
remote: -----> Installing SQLite3
remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote: 
remote: -----> Compressing...
remote:        Done: 153M
remote: -----> Launching...
remote:        Released v11
remote:        https://task-list-manager-gf.herokuapp.com/ deployed to Heroku
remote: 
remote: This app is using the Heroku-20 stack, however a newer stack is available.
remote: To upgrade to Heroku-22, see:
remote: https://devcenter.heroku.com/articles/upgrading-to-the-latest-stack
remote: 
remote: Verifying deploy... done.
To https://git.heroku.com/task-list-manager-gf.git
   15c029d..a5e2c42  master -> master

The only errors displayed in this log are related to react and they do not prevent the app from working perfectly fine locally.

I figured the problem might reside in my settings.py file:

from pathlib import Path
import os

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '#######################################################""'

DEBUG = False

ALLOWED_HOSTS = ['localhost:3000/', '127.0.0.1', 'task-list-manager-gf.herokuapp.com/']


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'api.apps.ApiConfig',
    'corsheaders',
    'pymongo'
]

CORS_ORIGIN_ALLOW_ALL = True

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
ROOT_URLCONF = 'backend.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'build')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'backend.wsgi.application'


# Database

DATABASES = {
    'default': {
        'ENGINE': '',
        'NAME': '',
    }
}


# Password validation

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization


LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)

STATIC_URL = 'static/'

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'build/static')
]

STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

# Default primary key field type

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

The current file structure of my app looks like this :

Main project directory

There is a 'build' and 'staticfile' folder because I tried to use the python manage.py collectstatic command to see if the problem came from python not being able to access React files.

my requirement.txt is the following :

asgiref==3.5.2
backports.zoneinfo==0.2.1
Django==4.0.6
django-cors-headers==3.13.0
dnspython==2.2.1
gunicorn==20.1.0
pymongo==4.2.0
sqlparse==0.4.2
whitenoise==6.2.0

and my package.json file :

{
  "name": "frontend",
  "proxy": "http://localhost:8000",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@primer/octicons-react": "^17.3.0",
    "@reduxjs/toolkit": "^1.8.3",
    "@testing-library/jest-dom": "^5.16.4",
    "@testing-library/react": "^13.3.0",
    "@testing-library/user-event": "^13.5.0",
    "bootstrap": "^5.2.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-redux": "^8.0.2",
    "react-scripts": "5.0.1",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

All the source code is available on my git : https://github.com/GuillaumeFavrot/TaskListManager.live

I'm running out of ideas so if you see something I'm missing that'd be great and let me know if more information is required.

Thanks!

Try setting allowed host in your settings.py to *

Back to Top