Deploying a Django App to Kubernetes with Amazon ECR and EKS
Published: 2024-07-12 20:37:48

Today, I'll be deploying a simple Django App to practice using Docker and Kubernetes.

I have a simple setup. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4n8h5mehpkwtyy5fkwps.png)

A directory with cloned git repo and a virtual environment.



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tykkpg12x5kouv9syxdg.png)

"kubesite" is the django project.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wll87rm6wz2bzxrmv7r7.png)

And within it, I created an app that displays "Hello, world!", routed to the /hello path.

Once I verified that the application works, I created my requirements.txt file

```
pip freeze > requirements.txt
``` 

This lists all the dependencies within the virtual environment. 

I then downloaded [Docker](https://docs.docker.com/get-docker/) and created my docker file.

* touch Dockerfile

```
# Use the official Python image from the Docker Hub
FROM python:3.12-slim

# Set environment variables
ENV PYTHONUNBUFFERED=1

# Set the working directory
WORKDIR /app

# Copy the requirements file into the container
COPY requirements.txt /app/

# Install any needed packages specified in requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

# Copy the current directory contents into the container at /app
COPY . /app/

# Expose port 8000
EXPOSE 8000

# Run the Django server
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

```
I run the command `docker build -t my-django-app .
`
which creates the Docker image shown on the desktop application.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uynqntx6w04fz8w4a6xc.png)

Running `docker run -p 8000:8000 my-django-app
`
I can open the url path and see that my application is successfully running on Docker.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a9r1qaaiylj3xvuszdec.png)

Now, to deploy the application over Kubernetes, we can utilize Amazon ECR and EKS.

Amazon Elastic Compute Registry will store the Docker container image. Amazon Elastic Kubernetes Service will deploy Kubernetes clusters and allows AWS to handle control plane operations.

In my CLI, I run

```
aws ecr get-login-password --region <my-region> | docker login --username AWS --password-stdin <my-account-id>.dkr.ecr.<my-region>.amazonaws.com
```

to authenticate Docker with my ECR registry.

I run 

```
docker tag my-django-app:latest <my-account-id>.dkr.ecr.<my-region>.amazonaws.com/my-django-app:latest
```

to tag the docker image.

Finally, I push the image to ECR 

```
docker push <your-account-id>.dkr.ecr.<your-region>.amazonaws.com/my-django-app:latest
```

## EKS

Now, I navigate to Amazon EKS in the AWS console and create a cluster with the name "my-django-app". I kept default settings, but also created a security group with this permission


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3zwyznqsowo0hec45ce0.png)

This will allow the Kubernetes control plane access to AWS Resources.

The clusters take awhile to create, but once that is finished, I connect to the EKS cluster with the following command:

```
aws eks update-kubeconfig --region <my-region> --name <my-cluster-name>
```

I created this yaml file in my project, which will set the configurations for my deployment

```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-django-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-django-app
  template:
    metadata:
      labels:
        app: my-django-app
    spec:
      containers:
      - name: my-django-app
        image: <my-account-id>.dkr.ecr.<my-region>.amazonaws.com/my-django-app:latest
        ports:
        - containerPort: 8000
---
apiVersion: v1
kind: Service
metadata:
  name: my-django-app
spec:
  type: LoadBalancer
  selector:
    app: my-django-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8000

```

I then apply the deployment to the EKS cluster

```
kubectl apply -f deployment.yaml
```

Check the pods are running

```
kubectl get pods
```


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u7sv3uv5axbl6vhrh7p2.png)

My pods are not currently running as I need to configure a worker node group in the EKS console.

I specified min=1, max=3, desired=2 using a t2.medium and a security group that allowed inbound SSH from my IP. 

I have to re-run the deployment and then run `kubectl get pods` again.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/80kprscgzxyci11cnbto.png)


And verify the service's external IP

```
kubectl get svc
```

I can now access my app through the IP.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h5w8cbebric9ak550fxi.png)

And here it is!


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/axjstft2wha5qegr2bqa.png)

## Cleanup

Delete the deployment

```
kubectl delete -f deployment.yaml
```

and verify the deletion

```
kubectl get pods
kubectl get svc
```

The EKS Cluster, the attached node group and ECR repository were deleted manually through the AWS console.

Deploying a simple Django application using Docker and Kubernetes has been a practical and useful experience. This process, from building a Docker image to pushing it to Amazon ECR and deploying it on Amazon EKS, shows how these tools work together to manage application deployment.

Starting from a local setup and moving to a cloud deployment gives you a clear understanding of current DevOps practices. Cleaning up the resources afterward ensures you avoid unnecessary costs and keeps your AWS environment tidy. This project not only enhances your understanding of Docker and Kubernetes but also prepares you for deploying more complex applications in the future.