Skip to content

Instantly share code, notes, and snippets.

@tomdyson
Last active September 4, 2023 02:48
Show Gist options
  • Save tomdyson/025be30855262287ae048bf4371d26f8 to your computer and use it in GitHub Desktop.
Save tomdyson/025be30855262287ae048bf4371d26f8 to your computer and use it in GitHub Desktop.
New ways to deploy your Django app

New ways to deploy your Django app

https://cfp.2020.djangocon.eu/porto/talk/QQWUBW/

You'll need:

  • Python 3.6+
  • A fresh Linux VM, e.g. on Vultr or Digital Ocean (referral links with $100 credit)
  • A Github account
  • A Google account

Make a simple Django app

Install Wagtail locally (or in a browser):

python3 -m venv venv
source venv/bin/activate
pip install wagtail
wagtail start demo
cd demo

Install fakenews, a package to create dummy content:

pip install wagtail-fakenews
pip freeze > requirements.txt

Add 'fakenews' to INSTALLED_APPS:

echo "INSTALLED_APPS += ['fakenews']" >> demo/settings/base.py

Make some dummy content, update the home page template, and check it's working:

./manage.py migrate
./manage.py make_fake_items 50
echo "<br><h1><a href='/fake-news-index/'>Fake news index</a></h1>" > home/templates/home/welcome_page.html
./manage.py runserver

Try http://127.0.0.1:8000/

Dokku

Install Dokku on a Debian / Ubuntu server

e.g. Vultr or Digital Ocean (referral links with $100 credit). 1GB is the minimum that Dokku recommends, and should be enough to run a few Django apps. Use the latest version of Debian or Ubuntu. As root, on the server, install Dokku:

# on the server
wget https://raw.githubusercontent.com/dokku/dokku/v0.21.4/bootstrap.sh
DOKKU_TAG=v0.21.4 bash bootstrap.sh

Go to your server's IP address in a browser and follow the instructions.

Now prepare a new app on Dokku, along with a PostgreSQL database:

# on the server
dokku apps:create demo-app
dokku plugin:install https://github.com/dokku/dokku-postgres.git
dokku postgres:create demo-db
dokku postgres:link demo-db demo-app

Dokku apps are ephemeral (they are recreated every time you deploy), so we need to set up persistent storage for media (e.g. images and documents uploaded by users):

# on the server
mkdir /srv/demo-storage
chmod a+w /srv/demo-storage
dokku storage:mount demo-app /srv/demo-storage:/storage
dokku config:set demo-app MEDIA_ROOT=/storage/

Add PostgreSQL to your app

pip install psycopg2-binary
pip install dj-database-url
pip freeze > requirements.txt

Configure your app to use the database and media root environment variables. Add this to the bottom of demo/settings/base.py:

import dj_database_url

if os.environ.get("DATABASE_URL"):
    DATABASES["default"] = dj_database_url.config()
    
if os.environ.get("MEDIA_ROOT"):
    MEDIA_ROOT = os.environ.get("MEDIA_ROOT")

Deploy your app

Push your app to Dokku, using git:

git init
git add .
git commit -m "first commit"
git remote add dokku dokku@[Dokku server IP address]:demo-app
git push dokku master

Your site should be live at http://[Dokku server IP address]:8000

You need to create an admin user, and give your site some dummy content:

# on the server
dokku run demo-app python3 manage.py createsuperuser
dokku run demo-app python3 manage.py make_fake_items 50

Log in to your Wagtail admin at http://[Dokku server IP address]:8000/admin and see the fake news listing at http://[Dokku server IP address]:8000/fake-news-index/

Static site generation

Install Wagtail-Bakery, which is based on Django-Bakery from the LA Times:

pip install wagtail-bakery
pip freeze > requirements.txt

and update your demo/settings/base.py:

INSTALLED_APPS += ['bakery', 'wagtailbakery']
BUILD_DIR = '/tmp/dist'
BAKERY_VIEWS = (
	'wagtailbakery.views.AllPublishedPagesView',
)

Bakery gives you a new management command to generate your pages:

./manage.py build

Alternatively, if all your pages can be crawled, you can achieve similar results with the venerable wget:

wget -mkEpnp http://127.0.0.1:8000
mv 127.0.0.1:8000 /tmp/dist

Netlify

Install the Netlify CLI and deploy your generated static site. You'll need a free Netlify account, which you should set up with your Github user details.

npm install netlify-cli -g
cd /tmp/dist
netlify init
netlify deploy --prod

Google Cloud Run

Install the Google Cloud SDK:

curl https://sdk.cloud.google.com | bash

(see instructions for Windows)

Create or choose a project in the Google Cloud admin UI. Then:

  1. Tell gcloud which project you're using
gcloud config set project [your project ID]
  1. enable the minimum APIs
gcloud services enable run.googleapis.com cloudbuild.googleapis.com
  1. Set your project ID and region, choosing the nearest region to your users
PROJECT_ID=$(gcloud config get-value core/project)
REGION=europe-north1
  1. Turn on build caching, and tell Google Cloud to build and store an image for your app
gcloud config set builds/use_kaniko True
gcloud builds submit --tag gcr.io/$PROJECT_ID/demo-app-image
  1. Deploy the image on Cloud Run
gcloud run deploy demo-app-cloudrun --platform managed --region $REGION \
  --image gcr.io/$PROJECT_ID/demo-app-image \
  --allow-unauthenticated

Caveat

Your site is live, but doesn't have a persistent database, file storage or a way of running management commands, and the Dockerfile isn't optimised for rapid scaling. To solve these problems, see Google's tutorials:

Resources

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment