DEV Community

Cover image for 🎯 Tutorial: Deploying a Django app on Heroku
Daniel Diaz for Developer Road

Posted on • Updated on

🎯 Tutorial: Deploying a Django app on Heroku

Deploying a Django App

Deploying a Django application to the internet could be difficult, but there are free and dedicated hosting platforms designed for deploy specific frameworks to the Internet.

Heroku may be the perfect choose for those how want a starting free web hosting and sub-domain, and an easy configurable hosting.

Pre-requirements:

  • You need to have Heroku CLI installed, and be logged in to your account. If you don't have it installed, check out the official docs, Here

Now that you have it installed and you are logged in, you can continue with the Python stuff 🐍.

Necessary packages to deploy on Heroku:

Now make sure to create a virtual environment, my preferred way is virtualenv:
First install it with pip install virtualenv, create a virtual env and create it:

virtualenv venv

#then 
source venv/bin/activate

# Depending on your shell, you could run a different command.
Enter fullscreen mode Exit fullscreen mode

Install Django and your Python development tools:

pip install django
Enter fullscreen mode Exit fullscreen mode

You need some packages to deploy an application to heroku, so let's get into it:

If you just want a command to install most packages you need, copy the line below:

pip install gunicorn django-heroku python-decouple
Enter fullscreen mode Exit fullscreen mode

Let's start with the package that handles most of the server operations: Gunicorn is an easy yet powerful Python HTTP server.

pip install gunicorn
Enter fullscreen mode Exit fullscreen mode

Django Heroku, allow us to don't worry of our settings in the Heroku server.

pip install django-heroku
Enter fullscreen mode Exit fullscreen mode

This package comes with other important packages that facilitates us the deployment in the fields, of static files whitenoise, a postgreSQL adapter psycopg, a package that helps to connect with the Database dj-database-url, and django-heroku itself.

This is almost everything but only a package is left 😁 :

pip install python-decouple
Enter fullscreen mode Exit fullscreen mode

This package helps us to pass python environmental variables on Django, we will se it later I promise😊.

Now let's run pip freeze, you should get something like this:

asgiref==3.3.1
dj-database-url==0.5.0
Django==3.1.6
django-heroku==0.3.1
gunicorn==20.0.4
psycopg2==2.8.6
python-decouple==3.4
pytz==2021.1
sqlparse==0.4.1
whitenoise==5.2.0
Enter fullscreen mode Exit fullscreen mode

Run this command to create a requirements.txt file that Heroku will use to install of the packages needed.

pip freeze > requirements.txt  
Enter fullscreen mode Exit fullscreen mode

Create a Procfile

# Run this in the root directory of the app
touch Procfile
Enter fullscreen mode Exit fullscreen mode

Open the file and copy the following file:

web: gunicorn (Your app).wsgi
Enter fullscreen mode Exit fullscreen mode

This tells Heroku, that it must run a web process, with gunicorn as HTTP server and with a wsgi file located in (Your app). Remember to change (Your app) with the name of your project.

Settings.py file

We just installed a lot of stuff, but now it's time to apply all of this in the settings.py file, but first Pro tip.

Pro Tip:

Before continuing modifying the settings file, do the following things:

Duplicate the settings.py file of your project, and rename it as settings_local.py,you will leave that file untouched, and use that configuration, while developing the application in local.

To run the server with the local settings just run the following command:

python manage.py runserver --settings=(Your app).settings_local
Enter fullscreen mode Exit fullscreen mode

Now after that, continue configuring the production environment.

Modifying the settings:

Importing modules

At the top of the file import the following modules:

# Import to serve staticfiles correctly
import os
import django_heroku
import dj_database_url
from decouple import config
Enter fullscreen mode Exit fullscreen mode

Static files

In the MIDDLEWARE variable, set whitenoise middleware below the Security Middleware:

MIDDLEWARE = [
  # 'django.middleware.security.SecurityMiddleware',
  'whitenoise.middleware.WhiteNoiseMiddleware',
  # ...
]
Enter fullscreen mode Exit fullscreen mode

Now go to the bottom of the app, where you could find the following commentaries:

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/
Enter fullscreen mode Exit fullscreen mode

Below paste this codeπŸ–₯️:

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

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static"),
]

STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

Enter fullscreen mode Exit fullscreen mode

Perfect, now our static files should be managed by Whitenoise.

Last step

At the very bottom of the file set the django heroku settings

django_heroku.settings(locals())
Enter fullscreen mode Exit fullscreen mode

That's all of you need to deploy an app to Heroku, good luck!

Create a Pipeline, from a Github Repository

Login or Create an account on Heroku, go to dashboard and click in the New Button.

image

Now click on create a new pipeline:
image

After that you will be redirected, to the pipeline, click on the add app button in order to create a new app.
image

Click and add your new app.

image

From now you will get a fully featured dashboard with the app.

Go to Deploy tab, and in the bottom you will get a button where you can deploy your app. Now click on that button and deploy the main branch.
image

Extra:

Troubleshooting:

Probably you will get a lot of errors before you can publish your app to the internet, so I'm going to tell you the most common problems and how to fix them.

Static files errors:

One of the most common errors that you will get, may be related with static files.

Error:

-----> $ python manage.py collectstatic --noinput
       Post-processing 'css/owl.carousel.min.css' failed!
       Traceback (most recent call last):
         File "manage.py", line 22, in <module>
           main()
         File "manage.py", line 18, in main
           execute_from_command_line(sys.argv)
         File "/app/.heroku/python/lib/python3.6/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
           utility.execute()
         File "/app/.heroku/python/lib/python3.6/site-packages/django/core/management/__init__.py", line 395, in execute
           self.fetch_command(subcommand).run_from_argv(self.argv)
         File "/app/.heroku/python/lib/python3.6/site-packages/django/core/management/base.py", line 330, in run_from_argv
           self.execute(*args, **cmd_options)
         File "/app/.heroku/python/lib/python3.6/site-packages/django/core/management/base.py", line 371, in execute
           output = self.handle(*args, **options)
         File "/app/.heroku/python/lib/python3.6/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 194, in handle
           collected = self.collect()
         File "/app/.heroku/python/lib/python3.6/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 138, in collect
           raise processed
       whitenoise.storage.MissingFileError: The file 'css/owl.video.play.png' could not be found with <whitenoise.storage.CompressedManifestStaticFilesStorage object at 0x7fab586a2710>.
       The CSS file 'css/owl.carousel.min.css' references a file which could not be found:
         css/owl.video.play.png
       Please check the URL references in this CSS file, particularly any
       relative paths which might be pointing to the wrong location.
 !     Error while running '$ python manage.py collectstatic --noinput'.
       See traceback above for details.
       You may need to update application code to resolve this error.
       Or, you can disable collectstatic for this application:
          $ heroku config:set DISABLE_COLLECTSTATIC=1
       https://devcenter.heroku.com/articles/django-assets
 !     Push rejected, failed to compile Python app.
 !     Push failed
Enter fullscreen mode Exit fullscreen mode

As you can see, the error is caused because of a css file pointing to another file that doesn't exist.

Heroku and Django are very sensitive with static files so if a pointing file doesn't exist, an error will occur.

To fix this particular error, set the environment key, DISABLE_COLLECTSTATIC and run locally the collectstatic command.

# Root directory
heroku config:set DISABLE_COLLECTSTATIC=1

# collect static

python manage.py collectstatic
Enter fullscreen mode Exit fullscreen mode

Push the code and deploy the app, this problem should be solved.

Fixing other errors:

To fix an error in production, We will use a logger in Django.

Paste the code below, this will give you a Django logger in production, which you can access with the following command.

# Django logger

# Debugging in heroku live
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': ('%(asctime)s [%(process)d] [%(levelname)s] ' +
                       'pathname=%(pathname)s lineno=%(lineno)s ' +
                       'funcname=%(funcName)s %(message)s'),
            'datefmt': '%Y-%m-%d %H:%M:%S'
        },
        'simple': {
            'format': '%(levelname)s %(message)s'
        }
    },
    'handlers': {
        'null': {
            'level': 'DEBUG',
            'class': 'logging.NullHandler',
        },
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'verbose'
        }
    },
    'loggers': {
        'testlogger': {
            'handlers': ['console'],
            'level': 'INFO',
        }
    }
}

DEBUG_PROPAGATE_EXCEPTIONS = True
COMPRESS_ENABLED = os.environ.get('COMPRESS_ENABLED', False)

# Heroku logs
heroku logs --tail
Enter fullscreen mode Exit fullscreen mode

Now you will get a real time logger to debug your application on production.

Thanks for your time hopefully this tutorial will be useful for you πŸ€—.

Follow me in My blog,
to get more awesome tutorials like this one.
Please consider supporting me on Ko-fi you help me a lot to
continue building this tutorials!.
ko-fi

Top comments (3)

Collapse
 
izararoy profile image
izararoy

Good post!

Collapse
 
danidiaztech profile image
Daniel Diaz

Thanks, any kind of feedback?

Collapse
 
anandsharma98 profile image
AnandSharma98

with this blog and the blog about media files helped me to finally deploy my site.
Thanks a lot brother.