A lot of articles seem to be different from what Heroku's documentation provides, and even with Heroku's documentation I had a little bit of trouble on my last deployment. I decided I'd create a checklist for my deployment as a baseline to work with.
This is a working document and not currently meant to serve as a How-To or guaranteed to be exhaustive/bug free, but rather give myself a centralized set of steps to draw from.
-
Ensure any secret keys are outside of git repo, scrub them from history if needed and store in .env file.
- Its good practice to never commit these, but if you did BFG-repo-cleaner gets the job done.
- I use python-dotenv to access environment variables. python-dotenv documentation
In
settings.py
set DEBUG to False, Set ALLOWED_HOSTS and CORS_ALLOWED_ORIGINS (if running front end from a separate deployment)
DEBUG = False
ALLOWED_HOSTS = ['your-app-name.herokuapp.com']
CORS_ALLOWED_ORIGINS = ['https://your-frontend-app-name.herokuapp.com']
RunHeroku will run collectstatic during build.python manage.py collectstatic
to collect static files. Not doing this will cause a server 500 error.Install gunicorn, whitenoise, cloudinary, django-cloudinary-storage (we install the cloudinary apps if using uploaded media) and add to requirements.txt
pip install gunicorn whitenoise cloudinary
pip freeze > requirements.txt
- Add Procfile to root folder with following contents:
web: gunicorn myProjectName.wsgi
myProjectName will be identical to the name of the folder that contains your settings.py and wsgi.py file
- Add whitenoise to middleware in settings.py and ensure settings are properly set. According to http://whitenoise.evans.io/en/stable/django.html# whitenoise middleware should be listed immediately after Django's security middleware, before all other middleware.
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
# ...
]
# According to whitenoise docs, we must specify a STATIC_ROOT
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
If we're using uploaded media, we can use Cloudinary for hosting for said media
https://devcenter.heroku.com/articles/cloudinary#using-with-django
https://pypi.org/project/django-cloudinary-storage/#requirements
Add Cloudinary to installed apps and config details. The docs say to put cloudinary_storage above django.contrib.staticfiles
but that gave me build errors, probably because cloudinary says to do things differently if you are using their hosting for static, media, or both.
INSTALLED_APPS = [
'cloudinary',
'cloudinary_storage',
# other apps
]
"""
I'm storing these keys in local .env for local testing,
but don't forget to add these keys to your Heroku environment
variables so that it can populate these values when running live.
"""
CLOUDINARY_STORAGE = {
'CLOUD_NAME' : str(os.getenv('CLOUDINARY_CLOUD_NAME')),
'API_KEY' : str(os.getenv('CLOUDINARY_API_KEY')),
'API_SECRET' : str(os.getenv('CLOUDINARY_API_SECRET'))
}
DEFAULT_FILE_STORAGE = 'cloudinary_storage.storage.MediaCloudinaryStorage'
- Install Django-Heroku https://devcenter.heroku.com/articles/django-app-configuration
pip install django-heroku
Add the following import statement to the top of settings.py:
import django_heroku
...
Then add the following to the bottom of settings.py:
# Activate Django-Heroku.
django_heroku.settings(locals())
- Follow instructions to deploy via Heroku CLI or GitHub
- I had a problem once where Heroku wasn't properly installing dependencies including gunicorn. Removing pipfile and providing only requirements.txt seemed to solve this. I'm not actually sure where the pipfiles came from since I used virtualenv and not pipenv to create my virtual environment, and I could only find docs of pipfile coming from pipenv.
You may need to run migrations once the application is deployed in order for the application to work. Access your app's developer console through Heroku (currently accessible via the "More" button next to the "Open App" button on the dashboard) and run
python manage.py make migrations
python manage.py migrate
Top comments (0)