Wagtail is a powerful and highly extensible open-source CMS based on Django web framework.
In this tutorial you will read how to prepare your project for production deployment and how to get your site deployed on AWS EC2 and Digital Ocean.
If you are looking for other deployment tutorials checkout out one of these:
- Deploy Django on Hetzner Cloud
- Deploy Django to Digital Ocean Droplet
- Deploy Django to AWS Lightsail
- Deploy Django to AWS EC2
- Deploy Django on Linode
- Deploy Django to Google Cloud Platform
In this post:
In order to create a blog project let's run these commands in terminal.
They will create a directory, python virtual environment and spin up a wagtail project from the template in the current directory.
mkdir myblog
cd myblog
python3 -m venv env
source env/bin/activate
pip install wagtail
wagtail start myblog .
Before we continue with installing dependencies open the requirements.txt
in your code editor and add 2 new lines: whitenoise
and django-environ
.
Your requirements.txt
would look like this:
Django>=4.2,<5.1
wagtail>=6.1,<6.2
whitenoise==6.6.0
django-environ==0.11.2
psycopg2-binary==2.9.9
gunicorn==22.0.0
Then run this to install all dependencies:
pip install -r requirements.txt
Now open the file myblog/settings/base.py
Find the MIDDLEWARE
and let's add whitenoise
middleware right after SecurityMiddlware
.
MIDDLEWARE = [
"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",
"django.middleware.security.SecurityMiddleware",
"whitenoise.middleware.WhiteNoiseMiddleware", # new
"wagtail.contrib.redirects.middleware.RedirectMiddleware",
]
Also add WHITENOISE_USE_FINDERS=True
line to the same file, you can add it to the end of the file.
Now open the myblog/settings/production.py
and add these lines to make sure our project respects environment variables when deployed in production.
We need to make sure that ALLOWED_HOSTS, SECRET_KEY and DATABASES are set correctly according to environment variables, because you never should hardcode any of those values and place them in version control.
Your myblog/settings/production.py
should now look like this:
import environ
import os
from .base import *
DEBUG = False
try:
from .local import *
except ImportError:
pass
env = environ.Env(
# set casting, default value
DEBUG=(bool, False)
)
SECRET_KEY = env('SECRET_KEY')
ALLOWED_HOSTS = env.list('ALLOWED_HOSTS', default=['*'])
DATABASES = {
'default': env.db(),
}
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
MEDIA_ROOT = env('MEDIA_ROOT', default=os.path.join(BASE_DIR, 'media'))
MEDIA_URL = env('MEDIA_URL', default='/media/')
In the home/
directory create a directory management
and an empty file __init__.py
.
In management directory create a directory commands
and an empty file __init__.py
in it.
Empty __init__.py
make these directories a python package and allows importing from them.
In commands
directory create a file makesuperuser.py
with the following content:
from django.contrib.auth import get_user_model
from django.core.management.base import BaseCommand
from django.utils.crypto import get_random_string
User = get_user_model()
class Command(BaseCommand):
def handle(self, *args, **kwargs):
email = 'admin@example.com'
new_password = get_random_string(10)
try:
u = None
if not User.objects.filter(is_superuser=True).exists():
self.stdout.write("No superusers found, creating one")
u = User.objects.create_superuser(username='admin', email=email, password=new_password)
self.stdout.write("=======================")
self.stdout.write("A superuser admin has been created")
self.stdout.write(f"Email: {email}")
self.stdout.write(f"Password: {new_password}")
self.stdout.write("=======================")
else:
self.stdout.write("A superuser exists in the database. Skipping.")
except Exception as e:
self.stderr.write(f"There was an error {e}")
This is a Django management command. It will check if a superuser already exists in a database. If it is not present, then it will create one with a generated password and print the password in logs. This automates the process of creation of the initial superuser, and doesn't require SSHing into a server to run the built-in createsuperuser
command.
In the root of the project create a file release.sh
:
#!/bin/bash
set -e
python manage.py migrate
python manage.py makesuperuser
This file will be used to apply migrations and check for super user existence and will be executed on each deployment(release phase).
Also create .gitignore
file, which is useful to avoid cluttering our git repository with files that shouldn't be committed to version control.
env/
.idea/
__pycache__/
*.py[cod]
*$py.class
.vscode/
.DS_Store
.AppleDouble
.LSOverride
Now initialize the repository, add and commit the code.
git init
git add .
git commit -m'Initial commit'
Create a GitHub or GitLab repository, add the remote and let's deploy it with Appliku.
Deploy Wagtail on AWS EC2¶
In order to deploy Wagtail project on AWS EC2 you need to generate AWS keys first. Follow instructions in this guide
After you have keys setup open Appliku dashboard and go to the "Servers" tab.
Select AWS provider.
Select the region, instance type and the disk size. To fit in AWS Free Tier make sure the disk size to be <30GB.
Click "Create EC2 Instance".
You will be taken to the server page where you will see the setup process. When it is finished, go to Applications tab and create a new app from GitHub (or GitLab if you hosted your repository there).
Deploy Wagtail on Digital Ocean¶
If you choose to go with Digital Ocean first make sure to create a DO account.
You will need to generate a token here https://cloud.digitalocean.com/account/api/tokens/new
Make sure to select scopes both "Read" and "Write". We recommend to setup expiration to "Never" or "1 Year" to avoid service interruptions.
In Appliku dashboard go to Servers tab and click "Setup Credentials" for Digital Ocean. Paste and save the token and go back to Servers tab. You will be able to select Digital Ocean provider now.
Select the region and Droplet Type. For Droplet Size we strongly recommend to pick at least 1GB RAM instance so your server can build and run your app and the database.
Click "Create Droplet".
Appliku will call Digital Ocean API and create a server for you and begin setup.
When that is finished you will be able to create the app and the database.
Deploy Wagtail with Appliku¶
Click on the "Applications" menu link.
If you haven't setup connection to will need to do that by clicking Setup Credentials.
When you are done you will be able to select the service you prefer. For this tutorial we'll go with GitHub
Give your app a name, select repository, branch and the server you have just created and click "Create Application".
Click on "Manage" in the databases block and add a database "Postgres 15" on the server we have just created.
Wait for it to get to "Deployed" status.
Go back to the application overview and click "Settings"
Go to the "Environment variables" tab. You see that our database's connection string is already there.
Click "+ Add" and add variables:
- "ALLOWED_HOSTS" must consist of the app name and ".applikuapp.com" so in our example it will be "wagtaildemo.applikuapp.com"
- SECRET_KEY: any random long string. Must be kept secret
- DJANGO_SETTINGS_MODULE must be set to myblog.settings.production
Now click "Save And Deploy"
On the Processes tab go create two processes: web
and release
.
The command for the web
process: gunicorn myblog.wsgi --log-file -
(watch out for the trailing dash -
, it is important)
The command for the release
process: bash release.sh
On the volumes tab, create a volume for media files:
- Container path:
/volumes/media
(path on which files will be accessible for your app) - URL:
/media/
- Environment Variable:
MEDIA
Back on the "Build Settings" tab make sure that "Update Nginx Configuration on deploy" is checked and save changes.
You can go back to the application overview page and see that deployment has started.
The first deployment might take a bit longer, because the dependencies take some time to install at first run. Next deployments will take less time if you haven't changed requirements.txt
file.
Click on "View Application"
Congratulations! You have deployed your Wagtail app!