Skip to content
The simplest possible Wagtail site on Google Cloud
CSS JavaScript Python HTML
Branch: master
Clone or download
Latest commit 93192ed Oct 24, 2017
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
home home page template Oct 23, 2017
static Include Tachyons Oct 23, 2017
wagae Embed styling Oct 24, 2017
.gitignore .gitignore: add vim .sw?, local.py Oct 18, 2017
LICENSE Initial commit Oct 17, 2017
README.md README fixup Oct 24, 2017
app.yaml Python 2.7 :( Oct 20, 2017
cors.json Import skeleton app Oct 17, 2017
generate_key.py Print the key Oct 20, 2017
manage.py Use base settings, don't include search URLs Oct 17, 2017
requirements.txt

README.md

Wagtail on Google App Engine demonstration

This is the simplest possible Wagtail site on Google Cloud, using App Engine Flexible and Cloud SQL.

Assumptions

  1. A project has been created in the Google Cloud Platform Console
  2. Billing has been enabled for your project
  3. The Cloud SQL API has been enabled

These steps are detailed in the Google Cloud documentation.

Install this app in Cloud Shell

git clone https://github.com/torchbox/wagtail-appengine-demo
cd wagtail-appengine-demo
virtualenv env
source env/bin/activate
sudo apt-get install libmysqlclient-dev
pip install -r requirements.txt

Configure Cloud SQL

Create a new Cloud SQL database

Create a new Cloud SQL instance, using MySQL:

gcloud sql instances create wagae   \
    --assign-ip                     \
    --database-version=MYSQL_5_7    \
    --region=europe-west2           \
    --gce-zone=europe-west2-c       \
    --storage-size=50               \
    --storage-type=HDD              \
    --tier=db-f1-micro

Adjust region, zone storage and machine size (tier) options as necessary. While PostgreSQL is a more common option for Django and Wagtail developers, it is currently only available in beta on Google Cloud SQL.

Create a new user and database, substituting a secure password for [DB_PASSWORD]:

gcloud sql users create wagtail % --instance=wagae --password=[DB_PASSWORD]
gcloud sql databases create wagtail --instance=wagae

Fetch the instance connection name for the database you created:

gcloud sql instances describe wagae --format='value(connection_name)'
your-project-id:europe-west2:wagae

We will refer to this as [CONNECTION_NAME] later.

Create Google Storage buckets

GCS will be used to store static assets and uploaded media. Create two new buckets, using a common prefix. Note that bucket names must be globally unique - you may want to use your project ID as the prefix.

gsutil mb gs://my-wagtail-site-static
gsutil mb gs://my-wagtail-site-media

Configure CORS headers on the static bucket so fonts can be loaded from the site's domain, and make the contents of both buckets readable by default:

gsutil cors set cors.json gs://my-wagtail-site-static
gsutil defacl set public-read gs://my-wagtail-site-static
gsutil defacl set public-read gs://my-wagtail-site-media

Configure local settings

Create a file called wagae/settings/local.py, and add your site-specific settings:

DB_CONNECTION_NAME = '[CONNECTION_NAME]'
DB_PASSWORD = '[DB_PASSWORD]'
GS_BUCKET_PREFIX = '[BUCKET_PREFIX]'
GS_PROJECT_ID = '[GCP_PROJECT_ID]'
SECRET_KEY = '[SECRET_KEY]'

[GCP_PROJECT_ID] is the name of your GCP project. [BUCKET_PREFIX] is the common prefix of the two GCS buckets you created, e.g. my-wagtail-site.

[SECRET_KEY] can be generated by running python generate_key.py.

Install the database tables

Run Cloud SQL Proxy in a new shell (press '+' in the header of your Cloud Shell):

cloud_sql_proxy -instances="[CONNECTION_NAME]=tcp:3306"

Replace [CONNECTION_NAME] with the connection name.

Create Wagtail's database tables and an initial user:

./manage.py migrate
./manage.py createsuperuser

Upload static files

Collect the static files locally and upload them:

./manage.py collectstatic --noinput
gsutil -m rsync -R static/ gs://my-wagtail-site-static/

Check everything works

./manage.py runserver 0.0.0.0:8080

Click on the 'Web preview' button in the header of your Cloud Shell. You should be able to log in to the Wagtail admin interface, using the user details you have just created.

Deploy to App Engine

Edit app.yaml, setting [CONNECTION_NAME] to the Cloud SQL database connection name.

Then deploy the application:

gcloud app deploy

Hardening

  1. Once you know the production domain for your site, specify this in ALLOWED_HOSTS and BASE_URL.
  2. Update the origin in cors.json and rerun gsutil cors set cors.json
  3. Increase SECURE_HSTS_SECONDS (e.g. to 2592000, which is 30 days) after testing
  4. Change the ^admin/ entrypoint to a less guessable alternative

High security options

Separate instances

Run two (clustered) instances of Wagtail: one for editors, with firewalled access to the domain; one from a read-only replica of the database, with the admin UI disabled (remove url(r'^admin/', include(wagtailadmin_urls)), from urls.py).

Static site generation

Use wagtail-bakery to export the pages and assets at page publish time. Upload incremental changes to a CDN, e.g. using Firebase hosting. This approach provides the highest levels of performance and security, but more 'dynamic' features (e.g. search, form submissions, server-side A/B testing and personalisation) may become harder to implement. See wagtail-netlify for a similar process using an alternative static hosting provider.

Notes

App Engine Standard

While it is possible to run Wagtail on App Engine Standard, we don't recommend this. App Engine Standard currently only supports Python 2.7, which will not be supported in the imminent releases of Django 2.0 and Wagtail 2.0.

Email

Wagtail sends email notifications to authors and editors, e.g. to prompt reviews when pages have been submitted for moderation. The Google App Engine documentation suggests three third party providers of secure SMTP services:

Search

Wagtail supports three backends for full-text search, each of which can power both the admin UI and public-facing search. These are Elasticsearch, PostgreSQL FTS and a simple database search. For simplicity's sake, this demo uses the latter. For more performant and feature-rich search, we currently recommend the Elasticsearch backend. Elasticsearch is available on Google Cloud either as a Cloud Launcher App or through Elastic.co's service.

You can’t perform that action at this time.