Python Dokku Guide

Preparing the App

This walk-through is for a Django app but can be easily adapted to other Python-based apps.

Create a requirements.txt in your project's root directory.

django
django-environ
django-heroku
gunicorn

Create a local virtual environment for your app:

python3 -m venv venv

Activate the virtual environment:

# Mac/Linux
source venv/bin/activate

# Windows
.\venv\Scripts\activate

Install the requirements locally:

pip install -r requirements.txt

Create a file named Procfile in your project's root directory to define the command used to start your app (in a production environment, in most cases):

web: gunicorn myapp.wsgi

This declares a single process type, web, and the command needed to run it. The name web is important here - this process type will be able to receive web traffic when deployed. 

Procfiles can contain additional process types. For example, you might declare one for a background worker process that processes items off of a queue.

Specify a Python runtime version by creating a file named runtime.txt in your project's root directory and adding a single line equal to the desired version. Supported versions are listed on the Python buildpack's README page. If you do not create this file, the buildpack defaults to the latest stable version listed on that page.

python-3.10.4

Create the Dokku App on the Server

Connect to the Healthcare Blocks virtual machine:

ssh username@server-id.healthcareblocks.com

Tip: alternately, use the Dokku Client directly from your local machine instead of connecting to the server.

Create a new Dokku app:

dokku apps:create my-app

Configure Environment Variables

Define app-specific environment variables that your framework can use to control environment-specific behavior:

dokku config:set my-app FOO=value

Django apps can use the django-environs package to pull environment variables. Other Python apps can use the os module:

os.environ.get('FOO')

Healthcare Blocks recommends storing sensitive values, including database credentials, in an .env file or equivalent on the server. See this topic for details.

Be sure your application is configured to communicate with any non-local databases using SSL/TLS. Details here.

Configure a Buildpack

Dokku uses an auto-detect function to identify which buildpack is best suited for your application type, however, Healthcare Blocks recommends explicitly configuring the buildpack to avoid any issues.

If you'd like to always use the latest version of the Python buildpack, use the following format:

dokku buildpacks:add my-app \
  https://github.com/heroku/heroku-buildpack-python.git

If you'd like to lock in a specific buildpack release, append the GitHub tag name to the end of the URL:

dokku buildpacks:add my-app \
  https://github.com/heroku/heroku-buildpack-python.git#v210

Release tags can be found here, and the corresponding change log is here.

Reference

Deploy your App

On your local machine, ensure you've initialized your local git repository and committed all files that will be deployed to the server. Development logs and assets and temporary files should be excluded in your .gitignore file.

Define a local git remote that references the Healthcare Blocks server and the app you created above:

git remote add hcb \
 dokku@server-id.healthcareblocks.com:my-app

Notice the "dokku" username. Even though you have a dedicated Linux user on the server, your SSH key is also associated with a dokku user that is used for handling deployments and remote commands.

To deploy the app:

git push hcb main

Main (or master in older git repositories) is the name of the branch you are pushing to on the server and should not be changed. To deploy a different local branch, for example, "integration":

git push hcb integration:main

Alternative Deployment Methods

Dokku is flexible and supports additional options besides buildpacks / git push:

Using Dockerfiles instead of Buildpacks

See Dockerfile Deployment.

Using External Docker Images

If you are already building a Docker image externally and want to use it as the basis for your Dokku app, see Initializing an app repository from a Docker image.

Other External Sources

Instead of using git push from a local machine, you can initialize/update a Dokku app using an archive file or external repository (including private ones).

Frequently Asked Questions

How do I automatically run database migrations during a release?
Add a release statement to your Procfile with the proper command. See this page for details.

How do I run background jobs?
Add support for the celery package in your app. 

Update your Procfile with the following startup command::

worker: celery worker --app=tasks.app

On the server, install the Dokku Redis plugin and start an instance of Redis, linking it to your app.

Deploy your app and scale up your worker process:

dokku ps:scale my-app worker=1

Reference Application

The following Django app is compatible with Dokku:

https://github.com/heroku/python-getting-started