All Articles
DevOps

Deploying a Django Application on Kubernetes

S
Seema Durrani
Instructor, beCloudReady
May 3, 20254 min read
Deploying a Django Application on Kubernetes

A step-by-step walkthrough for containerizing and deploying a Django application to a Kubernetes cluster.

In this project, you'll learn how to deploy a Django application on a Kubernetes (k8s) cluster. We'll be using a sample app available on GitHub:

๐Ÿ‘‰ Django Kubernetes Sample

This is a great hands-on exercise to solidify your understanding of Kubernetes concepts like Deployments, Services, ConfigMaps, and more.

๐Ÿ”ง Prerequisites

Before getting started, make sure you have the following set up:

  • A running Kubernetes cluster โ€” you can use Minikube for local testing or any cloud-hosted cluster (like GKE, EKS, AKS, or DigitalOcean).

  • kubectl installed and configured to interact with your cluster.

  • Docker installed on your local machine.

  • A Docker Hub account to push your custom Docker image.

Setup Architecture

Django deployment architecture on Kubernetes

Django deployment Architecture

๐Ÿ› ๏ธ Build the Django Application

We'll start by cloning the sample Django app and running it locally.

๐Ÿ“ฅ Step 1: Clone the Repository

Use the following commands to clone the code and navigate to the Django project directory:

git clone [_https://github.com/becloudready/kubernetes-tutorials.git_](<https://github.com/becloudready/kubernetes-tutorials.gitcd>)
cd kubernetes-tutorials/practice-problems/django-application

โ–ถ๏ธ Step 2: Run the Django App Locally

You can start the Django application locally using:

python manage.py runserver

Or, if you're running it on a remote host:

python manage.py runserver 0.0.0.0:8000

This will launch the app and make it accessible on port 8000.

๐Ÿ” Login to Docker Hub

Before pushing the Docker image, you'll need to log in to your Docker Hub account.

๐Ÿ”‘ Step 3: Login to Docker Hub

Run the following command in your terminal:

docker login

You'll be prompted to enter your Docker Hub username and password.Once authenticated, Docker will save your credentials locally so you can push images without needing to re-enter them every time.

๐Ÿ’ก If you're using Docker Hub with 2FA enabled, make sure to use a Personal Access Token instead of your password.

Now we will write a Dockerfile

# Use official Python image
FROM python:3.11-slim

# Set environment variables
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1

# Set working directory
WORKDIR # Install system dependencies
RUN apt-get update && apt-get install -y \
build-essential \
libpq-dev \
gcc \
default-libmysqlclient-dev \
pkg-config \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

# Install Python dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy project files
COPY . .

# Expose port 8000
EXPOSE 8000

# Start the Django server
CMD ["sh", "-c", "python manage.py migrate && python manage.py runserver 0.0.0.0:8000"]

Do a Docker build of the image:

docker build -t becloudready/django-app:2.0.0 .

docker push becloudready/django-app:2.0.0 ## use your registry to push the image

Once the image is built and pushed, it will be available on your Docker Hub dashboard.

๐Ÿ“ก Connect to Your Kubernetes Cluster

To connect to your Kubernetes cluster and apply the manifests:

  1. Save the kubeconfig file locally.

  2. Set the KUBECONFIG environment variable to point to the file:

export KUBECONFIG=/path/to/your/kubeconfig

Kubernetes Manifests:

configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: django-config
data:
  MYSQL_HOST: mysql
  MYSQL_PORT: "3306"
  MYSQL_DATABASE: django_db 
secret.yaml
apiVersion: v1
kind: Secret
metadata:
 name: django-secret
type: Opaque
stringData:
  MYSQL_USER: django
  MYSQL_PASSWORD: securepassword
mysql.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:8
        env:
          - name: MYSQL_ROOT_PASSWORD
            value: rootpass
          - name: MYSQL_DATABASE
            valueFrom:
               configMapKeyRef:
                  name: django-config
                  key: MYSQL_DATABASE
          - name: MYSQL_USER
            valueFrom:
              secretKeyRef:
                name: django-secret
                key: MYSQL_USER
          - name: MYSQL_PASSWORD
            valueFrom:
              secretKeyRef:
                name: django-secret
                key: MYSQL_PASSWORD
        ports:
          - containerPort: 3306

django.yaml

apiVersion: apps/v1
kind: Deployment
metadata:  
  name: django
spec:
  replicas:1
  selector:
    matchLabels:  
      app: django  
  template:
    metadata:
      labels:
        app: django
    spec:
      containers:  
        - name: django
          image: becloudready/django-app:2.0.0 ## Use the image built in above steps
          ports:
            - containerPort: 8000
          envFrom:
            - configMapRef:  
                 name: django-config
            - secretRef:
                  name: django-secret       

services.yaml

---
apiVersion: v1
kind: Service
metadata:
   name: mysql
spec:
  selector:
    app: mysql
  ports:
    - port: 3306
      targetPort: 3306
  clusterIP: None
---
apiVersion: v1
kind: Service
metadata:
  name: django
spec:
  type: LoadBalancer
  selector:
    app: django
  ports:
    - port: 80
      targetPort: 8000

Deploy to Kubernetes

  • Deploy ConfigMaps and Secrets:

    kubectl apply -f configmap.yaml kubectl apply -f secret.yaml

  • Deploy MySQL:

    kubectl apply -f mysql.yaml

  • Deploy Django App:

    kubectl apply -f django.yaml kubectl apply -f services.yaml

  • Test the Application

    kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP django LoadBalancer 10.109.28.59

Troubleshooting

๐Ÿงช Check Logs for Potential Errors

To troubleshoot and identify any potential issues with your deployments, view the logs for both the Django and MySQL pods:

  1. Get the pod names:

    kubectl get pods -A

**** 2**. Check logs for the Django deployment:**

 kubectl logs <django-pod-name>

3. Check logs for the MySQL deployment:

 kubectl logs <mysql-pod-name>
DjangoKubernetesPythonDockerDeployment