Django on Dokku

I’ve been experimenting a bit with Dokku a bit recently, with a view to automating deployment of some small services.

Getting a Django app up and running using Dokku is fairly easy…

I’m using dokku-alt here, as it preconfigures some useful plugins and has some feature improvements over the original.

1) Create virtual machine.

Start a virtual machine wherever you can (I used a .5GiB host in Digital Ocean for this.)

2) Configure DNS entries

Configure a wildcard DNS entry for IP for your virtual machine, I run bind in my internal network at home so, for me this was a simple as creating a zone for it internally.

3) Install Dokku

Follow the dokku-alt instructions for installation.

$ curl -s https://raw.githubusercontent.com/dokku-alt/dokku-alt/master/bootstrap.sh | sudo sh

From now on, it mostly follows the “Getting started with Django on Heroku” article.

4) Prepare local virtualenv

Create a new virtualenv locally (I use virtualenvwrapper), to test your first app, and install the django-toolbelt package from the Cheeseshop.

$ mkvirtualenv djangokku && pip install django-toolbelt

5) Create a new Django app…

$ django-admin.py startproject djangokku

6) Setup the requirements

Change to the djangokku project directory and write a requirements.txt file.

$ cd djangokku
$ pip freeze > requirements.txt

7) Configure Django settings

Update the djangokku/settings.py per the instructions per the Heroku instructions.

Note, for Django 1.6 onwards, you don’t need to set the BASE_DIR as it’s already in the settings.py by default.

Also, I found the STATICFILES_DIRS settings were unnecessary.

8) Configure WSGI to serve static

This would be better done from Nginx.

Configure the WSGI file per the Heroku instructions

I left in the code to configure the environment for the correct settings that’s written out in Django, thus my djangokku/wsgi.py file looks like this:

"""
WSGI config for djangokku project.

It exposes the WSGI callable as a module-level variable named ``application``.

For more information on this file, see

https://docs.djangoproject.com/en/1.6/howto/deployment/wsgi/

"""

import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djangokku.settings")

from django.core.wsgi import get_wsgi_application
from dj_static import Cling

application = Cling(get_wsgi_application())

9) Add a Procfile

The Procfile file “is a mechanism for declaring what commands are run by your application’s dynos on the [Dokku] platform.”

$ echo "web: gunicorn djangokku.wsgi" > Procfile

10) Setup for using git to deploy

Add at least this to your .gitignore file.

*.pyc

Then setup your Django project as a git repository.

$ git init .
$ git add .
$ git commit -am "Initial commit."

11) Configure git for deployments

Add a git remote to deploy directly to the Dokku instance, note that my internal DNS resolves www.dokku via the wildcard to my Digital Ocean instance.

$ git remote add dokku dokku@www.dokku:djangokku

12) Deploy!

$ git push dokku master

This should push your code to your server, and deploy it…

         Running setup.py install for pystache
           pystache: using: version '2.1' of 

           Installing pystache script to /app/.heroku/python/bin
           Installing pystache-test script to /app/.heroku/python/bin
         Running setup.py install for static

           Installing static script to /app/.heroku/python/bin
       Successfully installed Django dj-database-url dj-static django-toolbelt gunicorn psycopg2 pystache static
       Cleaning up...
-----> Preparing static assets
       Running collectstatic...
       69 static files copied to '/app/staticfiles'.

-----> Discovering process types
       Procfile declares types -> web
remote: Sending build context to Docker daemon 2.048 kB
remote: Sending build context to Docker daemon
Step 0 : FROM dokku/djangokku:build
 ---> d158b4a7afb4
Step 1 : ENV GIT_REV 981b43800b11a07eaadd7fbed628bffbc2dc9507
 ---> Running in b4fb0b26d961
 ---> 65ad2d564bb6
Removing intermediate container b4fb0b26d961
Successfully built 65ad2d564bb6
-----> Releasing djangokku ...
-----> Injecting Supervisor ...
-----> Deploying djangokku ...
=====> Application deployed:

http://djangokku.dokku

-----> Cleaning up ...
To dokku@www.dokku:djangokku
 * [new branch]      master -> master

Visiting your newly deployed app should get the familiar “Congratulations on your first Django-powered page.”

13) Databases!

Django apps require Databases…in our case, we’ll connect djangokku to a PostgreSQL database server…

To do this, we need to ssh to the server that’s hosting dokku and create a database using dokku.

$ dokku postgresql:create testing

And link this database to our djangokku application.

dokku postgresql:link djangokku testing

This will redeploy the app, connected to the database:

CREATE ROLE
GRANT
-----> Releasing djangokku ...
-----> Injecting Supervisor ...
-----> Deploying djangokku ...
=====> Application deployed:

http://djangokku.dokku

You can now run the database sync just as you would locally:

$ dokku run djangokku python ./manage.py syncdb

Creating tables ...
Creating table django_admin_log
Creating table auth_permission
Creating table auth_group_permissions
Creating table auth_group
Creating table auth_user_groups
Creating table auth_user_user_permissions
Creating table auth_user
Creating table django_content_type
Creating table django_session

You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no): yes
Username (leave blank to use 'root'): kevin
Email address: kevin@bigkevmcd.com
Password:
Password (again):
Superuser created successfully.
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)

That’s the basics of getting a Django app up and running in Dokku.