Django on K8s (Part IV: Adding Storage)
Tags: django, kubernetes, docker, ubuntu
Published: 2022-01-11 09:58:34

Welcome back,

So, at the last part, we deployed our application on Kubernetes and we were able to reach the web-app through the service.

There is a problem with containers that their storage is lost when the container dies, but users (admins included) assumes that the database changes in the application will life forever whatever happens.

**Note**: Storage is a complex topic and it depends on where are you running, so there is a StorageClass for AWS, GCE, or Azure, also other technologies like NFS and CEPH are supported natively in Kubernetes,so you shall work with your infrastructure team to know how the storage will be provisioned and/or claimed. In this tutorial, we will show the simplest method which is 'hostPath' (which isn't reliable on a real Kubernetes Cluster which has multiple hosts)


So In this part, we will see how to make the database file `db.sqlite` on a persistent storage so the app can handle being restarted.

This will include 
1. Create the directory and copy initial db to minikube node,
2. Attaching a the file from the hostPath to the container in  the deployment.


### 1. Create the directory and copy initial db to minikube node

As we will use hostPath and the host is the `minikube`, we need to create the folder and initial db so we can run.

```
django-on-k8s$ ssh -i $(minikube ssh-key)  docker@$(minikube ip) "sudo mkdir -p /storage/sqlite/example/; sudo chmod a+w /storage/sqlite/example/"
django-on-k8s$ scp -i $(minikube ssh-key) django_app/db.sqlite3 docker@$(minikube ip):/storage/sqlite/example/db.sqlite3
```

### 2. Attaching storage to new Container

Now see the new section `django-example_db_storage.yaml`
```yaml
...............
spec:
      volumes:                # <-------
        - name: sqlite-volume
          hostPath:
            path: /storage/sqlite/example/db.sqlite3
            type: File
      containers:
      - name: web-app
        image: django-example:v1.0
        ports:
        - containerPort: 80
        volumeMounts:     # <------
            - name: sqlite-volume
              mountPath: /app/db.sqlite3

```

Now apply the deployment 
```
django-on-k8s$ kubectl apply -f django-example_db_storage.yaml
```
Expose the service
```
kubectl expose deployment django-example
```

Next, Get IP of the service and connect to it, 
then go to django-admin ('/admin/') on the container (Refer to [Part III](url)), so you  and add new user, once added, Try to login with it, once succeed, kill the deployment, and start a new one with the following 2 commands

```
kubectl delete deploy/django-example
django-on-k8s$ kubectl apply -f django-example_db_storage.yaml
```
Finally, you can either login by the new user, or login with admin and check if the created user still exists.

## Wrap Up

In this part, we showed how to persist storage between container results, but we just barely scratched the surface,and your next step can be reading further about [Storage Classes](https://kubernetes.io/docs/concepts/storage/storage-classes/).

Finally, In real applications, no one uses SQLite to host the database, we use a DBMS like MySQL or Postgres, so in the next part, we will show how to use multi-container per pod of Kubernetes to add a DBMS container within the pod, The explanation will be based on MySQL.