Deploying Python websites is hard. I don't care what anybody says, it's always been the hardest part about Python development in my opinion.
So today I'm going to show you how to deploy your Wagtail website to Heroku fairly easily and for free.
We will be launching a website using:
- Wagtail 2.16
- Python 3.10
- Django 4.0
By the end of this tutorial you will have deployed your Wagtail CMS website to the web.
Ultra fast steps to creating a Wagtail 2.16 website on your computer.
pip install wagtail wagtail start your_app
This will give you most of the file you need. If you already have a Wagtail project then please ignore the above code snippet 😎
You will need a couple files for Heroku to read. The first one is the
runtime.txt file which tells Heroku which version of Python to use.
Looking for other Python versions? Check them out here.
Then we need a Procfile. This is going to tell Heroku's dynos how to run your website.
web: gunicorn your_app.wsgi --log-file -
your_app.wsgi is mapping to the
your_app/ folder and the
wsgi.py file. If your project is called
my_awesome_app, then change:
We need a few new dependencies for this to work. Open up your
requirements.txt file and add these three packages:
django-toolbelt psycopg2 whitenoise
base.py settings, add the whitenoise middleware below your security middleware, like so:
MIDDLEWARE = [ # ... 'django.middleware.security.SecurityMiddleware', 'whitenoise.middleware.WhiteNoiseMiddleware', ]
Note: You could overwrite your
production.pysettings instead of using whitenoise in in
base.py- any settings that go into
base.pyare also used in local development, and that's not always what you want to do.
By default your
production.py file is relatively empty. That's because Wagtail doesn't know what tools you'll be using in production, so it makes no assumptions.
We can make some assumptions now that we know we're deploying to Heroku.
from __future__ import absolute_import, unicode_literals from .base import * import os import dj_database_url DEBUG = False env = os.environ.copy() # It's a GOOD idea to lock this down. ALLOWED_HOSTS = ['*'] DATABASES['default'] = dj_database_url.config() # Honor the 'X-Forwarded-Proto' header for request.is_secure() SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') SECRET_KEY = env['SECRET_KEY'] STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' COMPRESS_OFFLINE = True COMPRESS_CSS_FILTERS = [ 'compressor.filters.css_default.CssAbsoluteFilter', 'compressor.filters.cssmin.CSSMinFilter', ] COMPRESS_CSS_HASHING_METHOD = 'content' try: from .local import * except ImportError: pass
You'll need the Heroku CLI tool. Once you've downloaded and installed the Heroku CLI, open your command line tool and write:
Login to your Heroku account and you'll be ready to start creating new Heroku apps.
Next, you'll need Git. If you don't have Git, make sure you download and install it. Git is the version control system we'll be using to tell Heroku we have new code for our future website. Continue once you have Git installed.
If you are not using git for your project already, initialize a new local repo with (ignore if you are already using git):
git init git add . git commit -m "First commit"
That will create a new local repository, add all your files, and create a commit message.
Then create a new Heroku app and connect it to your new git repo with:
Then push your committed codebase to Heroku with:
git push heroku master
Now at this point your Wagtail site is in the cloud, but it needs a couple things for the rest of this to work. And this is absolutely vital.
DJANGO_SETTINGS_MODULE should point to your production settings. In the image above you see
testapp.settings.production. That would map to
testapp/settings/production.py - your path will certainly be different from mine.
Also you can click here to generate a secret key.
I usually restart all my dynos after this just to make sure these environment variables become available to the website.
Lastly, you can run each of these commands one by one:
heroku plugins:install heroku-config heroku config:push heroku run python manage.py migrate heroku run python manage.py createcachetable heroku run python manage.py createsuperuser heroku ps:scale web=1
Now your website is available on the internet! Here's the example website I deployed.
Anytime you need to deploy new changes, all you need to do is:
git add yourfile.ext git commit -m "Some new commit message" git push heroku master
Media (files uploaded by the users through the Wagtail admin) are not supported in this tutorial. Heroku doesn't come with file storage and it's best to use something like AWS S3 for that purpose. All your static assets will be served using whitenoise, but your uploaded files won't work - here's a blog post on getting started with S3 on Heroku with Wagtail
If you found this article helpful please let me know on Twitter @KalobTaulien - I'm always interested in hearing from the Wagtail community.