In a previous article we have seen how to build a “To Do” application using the Django REST Framework. In this article we will look on how we can use Minishift to deploy this application on a local OpenShift cluster.

Prerequisites

This article is the second part of a series, you should make sure that you have read the first part linked right below. All the code from the first part is available on GitHub.

Getting started with Minishift

Minishift allows you to run a local OpenShift cluster in a virtual machine. This is very convenient when developing a cloud native application.

Install Minishift

To install Minishift the first thing to do is to download the latest release from their GitHub repository.

For example on Fedora 29 64 bit, you can download the following release

$ cd ~/Download

$ curl -LO https://github.com/minishift/minishift/releases/download/v1.31.0/minishift-1.31.0-linux-amd64.tgz

The next step is to copy the content of the tarball into your preferred location for example ~/.local/bin

$ cp ~/Download/minishift-1.31.0-linux-amd64.tgz ~/.local/bin

$ cd ~/.local/bin

$ tar xzvf minishift-1.31.0-linux-amd64.tgz

$ cp minishift-1.31.0-linux-amd64/minishift .

$ rm -rf minishift-1.31.0-linux-amd

$ source ~/.bashrc

You should now be able to run the minishift command from the terminal

$ minishift version

minishift v1.31.0+cfc599

Set up the virtualization environment

To run, Minishift needs to create a virtual machine, therefore we need to make sure that our system is properly configured. On Fedora we need to run the following commands:

$ sudo dnf install libvirt qemu-kv

$ sudo usermod -a -G libvirt $(whoami)

$ newgrp libvirt

$ sudo curl -L https://github.com/dhiltgen/docker-machine-kvm/releases/download/v0.10.0/docker-machine-driver-kvm-centos7 -o /usr/local/bin/docker-machine-driver-kvm

$ sudo chmod +x /usr/local/bin/docker-machine-driver-kv

Starting Minishift

Now that everything is in place we can start Minishift by simply running:

$ minishift start

-- Starting profile 'minishift'

....

....



The server is accessible via web console at:

https://192.168.42.140:8443/console



Using the URL provided (make sure to use your cluster IP address) you can access the OpenShift web console and login using the username developer and password developer.

If you face any problem during the Minishift installation, it is recommended to follow the details of the installation procedure.

Building the Application for OpenShift

Now that we have a OpenShift cluster running locally, we can look at adapting our “To Do” application so that it can deployed on the cluster.

Working with PostgreSQL

To speed up development and make it easy to have a working development environment in the first part of this article series we used SQLite as a database backend. Now that we are looking at running our application in a production like cluster we add support for PostgreSQL.

In order to keep the SQLite setup working for development we are going to create a different settings file for production.

$ cd django-rest-framework-todo/todo_app

$ mkdir settings

$ touch settings/__init__.py

$ cp settings.py settings/local.py

$ mv settings.py settings/production.py

$ tree settings/

settings/

├── __init__.py

├── local.py

└── production.py

Now that we have 2 settings files — one for local development and one for production — we can edit production.py to use the PostgreSQL database settings.

In todo_app/settings/productions.py replace the DATABASE dictionary with the following:

DATABASES = {

"default": {

"ENGINE": "django.db.backends.postgresql",

"NAME": "todoapp",

"USER": "todoapp",

"PASSWORD": os.getenv("DB_PASSWORD"),

"HOST": os.getenv("DB_HOST"),

"PORT": "",

}

}

As you can see, we are using Django PostgreSQL backend and we are also making use of environment variables to store secrets or variables that are likely to change.

While we are editing the production settings, let’s configure another secret the SECRET_KEY, replace the current value with the following.

SECRET_KEY = os.getenv("DJANGO_SECRET_KEY")

ALLOWED_HOSTS = ["*"]

DEBUG = False



REST_FRAMEWORK = {

'DEFAULT_RENDERER_CLASSES': (

'rest_framework.renderers.JSONRenderer',

)

}

We edited the ALLOWED_HOSTS variable to allow any host or domain to be served by django and we have also set the DEBUG variable to False. Finally we are configuring the Django REST Framework to render only JSON, this means that we will not have an HTML interface to interact with the service.

Building the application

We are now ready to build our application in a container, so that it can run on OpenShift. We are going to use the source-to-image (s2i) tool to build a container directly from the git repository. That way we do not need to worry about maintaining a Dockerfile.

For the s2i tool to be able to build our application, we perform a few changes to our repository. First, let’s create a requirements.txt file to list the dependencies needed by the application.

Create django-rest-framework-todo/requirement.txt and add the following:

django

djangorestframework

psycopg2-binary

gunicorn

psycopg2-binary is the client use to connect to PostgreSQL database, and gunicorn is the web server we are using to serve the application.

Next we need to make sure to use the production settings. In django-rest-framework-todo/manage.py and django-rest-framework-todo/wsgi.py edit the following line:

os.environ.setdefault('DJANGO_SETTINGS_MODULE','todo_app.settings.production')

Application Deployment

That’s it, we can now create a new project in OpenShift and deploy the application. First let’s login to Minishift using the command line tool.

$ oc login

Authentication required for https://192.168.42.140:8443 (openshift)

Username: developer

Password: developer

Login successful.

....

$ oc new-project todo

Now using project "todo" on server "https://192.168.42.140:8443".

....

After login in the cluster we have created a new project “todo” to run our application. The next step is to create a PostgreSQL application .

$ oc new-app postgresql POSTGRESQL_USER=todoapp POSTGRESQL_DATABASE=todoapp POSTGRESQL_PASSWORD=todoapp

Note that we are passing the environment variable needed to configure the database service, these are the same as our application settings.

Before we create our application, we need to know what is the database host address.

$ oc get service

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

postgresql ClusterIP 172.30.88.94 5432/TCP 3m

We will use the CLUSTER-IP to configure the DB_HOST environment variable of our Django application.

Let’s create the application:

oc new-app centos/python-36-centos7~https://github.com/cverna/django-rest-framework-todo.git#production DJANGO_SECRET_KEY=a_very_long_and_random_string DB_PASSWORD=todoapp DB_HOST=172.30.88.9

We are using the centos/python-36-centos7 s2i image with a source repository from GitHub. Then we set the needed environment variable DJANGO_SECRET_KEY, DB_PASSWORD and DB_HOST.

Note that we are using the production branch from that repository and not the default master branch.

The last step is to make the application available outside of the cluster. For this execute the following command.

$ oc expose svc/django-rest-framework-todo

$ oc get route

NAME HOST/PORT

django-rest-framework-todo django-rest-framework-todo-todo.192.168.42.140.nip.io

You can now use the HOST/PORT address to access the web service.

Note that the build take couple minutes to complete.

Testing the application

Now that we have our service running we can use HTTPie to easily to test it. First let’s install it.

$ sudo dnf install httpie

We can now use the http command line to send request to our serivce.

$ http -v GET http://django-rest-framework-todo-todo.192.168.42.140.nip.io/api/todo/

....

[]



$ http -v POST http://django-rest-framework-todo-todo.192.168.42.140.nip.io/api/todo/ title="Task 1" description="A new task"

...

{

"description": "A new task",

"id": 1,

"status": "todo",

"title": "Task 1"

}

$ http -v PATCH http://django-rest-framework-todo-todo.192.168.42.140.nip.io/api/todo/1 status="wip"

{

"status": "wip"

}

$ http --follow -v GET http://django-rest-framework-todo-todo.192.168.42.140.nip.io/api/todo/1

{

"description": "A new task",

"id": 1,

"status": "todo",

"title": "Task 1"

}

Conclusion

In this article, we have learned how to install Minishift on a local development system and how to build and deploy a Django REST application on OpenShift. The code for this article is available on GitHub.

Photo by chuttersnap on Unsplash