Django Todo App - Complete DevOps CI/CD Pipeline

Neha SawantNeha Sawant
6 min read

Run the Django Project Locally

Steps:

1️⃣ Open project in VS Code

2️⃣ Create a virtual environment

  • Python projects often use different versions of libraries.

    • Example: Project A uses Django 2.2, Project B uses Django 3.2.
  • If you install packages globally (pip install django), they overwrite each other.

    Thats why we need virtual environment.

# Install virtualenv if you don’t have it
python -m pip install virtualenv

# Create env with Python 3.13
virtualenv -p python3.13 env

# Activate (Windows)
.\env\Scripts\activate

cd django-todo

3️⃣ Install Django

pip install django

4️⃣ Run migrations

python manage.py makemigrations
python manage.py migrate

5️⃣ Create superuser

python manage.py createsuperuser
# username: neha
# email: n@gmail.com
# password: neha@123

6️⃣ Run server

python manage.py runserver

Visit the link Django provides — usually:
http://127.0.0.1:8000

Note:
Save installed packages:

pip freeze > requirements.txt

Note:
Never push directly to main!
Create a new branch for any changes.

git checkout -b devlop

Way 1: Run Django app on AWS EC2

1️⃣ Create & connect to EC2

  • You launch an EC2 instance (e.g., Ubuntu) → connect it.

2️⃣ Prepare project directory

mkdir project
cd project
git clone https://github.com/shreys7/django-todo.git
cd django-todo/

3️⃣ Install Python & pip

sudo apt update
sudo apt upgrade -y
sudo apt install software-properties-common -y
sudo apt install python3-pip -y

Why?

  • apt update/upgrade: Update system packages.

  • software-properties-common: Adds tools to manage repos.

  • python3-pip: Installs pip to manage Python packages.

4️⃣ Install project dependencies

python3 -m pip install virtualenv
virtualenv env
source env/bin/activate
pip install django

Why?

  • Create and activate a virtual environment so your app’s dependencies don’t mess up the system Python.

  • Install Django inside the virtual environment.

5️⃣ Allow server to listen on any IP

By default:

python3 manage.py runserver

runs on 127.0.0.1:8000 → only accessible inside the instance.

To make it accessible from your browser, run:

python3 manage.py runserver 0.0.0.0:8001

6️⃣ Allow external traffic

In AWS Security Group (SG):

  • Go to EC2 console → your instance → Security → SG.

  • Edit inbound rules:

    • Type: Custom TCP

    • Port: 8001

    • Source: 0.0.0.0/0 (anyone) or your IP only.


7️⃣ Update ALLOWED_HOSTS

Inside settings.py:

ALLOWED_HOSTS = ['*']

Why?

  • Django blocks requests from unknown hosts.

  • ['*'] means allow any host.

  • For production, use specific domains/IPs, not * (unsafe).


8️⃣ Run the server

python3 manage.py runserver 0.0.0.0:8001

Open:

http://your-ec2-public-ip:8001

✅ Your Django app is live!

9️⃣ Run in background

If you close SSH, the server stops.

Solution: nohup or screen:

nohup python3 manage.py runserver 0.0.0.0:8001 &
  • nohup → ignores hangup signals.

  • & → run in background.

10️⃣ Check if server is running

lsof -i:8001
  • Shows which process is using port 8001.

11️⃣ Stop the server

kill -9 <pid>
  • Kills the process by PID (process ID).

Common problem while running app on ec3 instance:

ALLOWED_HOSTS not set , Process stops when you exit SSH, Database not migrated, Static files not served, Wrong IP/Port, Permissions Issues, EC2 stops after you close terminal.

solution:

Docker is the modern, clean solution for:

  • Making your app repeatable

  • Reducing “it works locally” bugs

  • Running it safely on EC2


Way 2: Run Django app on AWS EC2 with Docker

Without Docker:

  • You’d need many EC2 instances (or run multiple apps on the same OS, but then they can conflict).

  • Each app needs its own Python version, dependencies, ports — they can clash.

  • Managing them becomes a headache: more servers = more cost + more ops work.

With Docker:

  • You run multiple isolated containers on one EC2 instance.

Steps

1️⃣Create Docker:

sudo apt install docker.io

2️⃣ Create Dockerfile

#vi Dockerfile

# Use Python image
FROM python:3

# Install Django
RUN pip install django==3.2

# Copy code
COPY . .

# Run migrations
RUN python manage.py migrate

# Expose port 8001
EXPOSE 8001

# Run server
CMD ["python","manage.py","runserver","0.0.0.0:8001"]

2️⃣ Build Docker image

sudo docker build . -t todo-app

3️⃣ Run container

# List containers
sudo docker ps

# Run interactively
sudo docker run -p 8001:8001 todo-app

# OR run in background
sudo docker run -d -p 8001:8001 todo-app

Visit: http://18.218.50.127:8000


Jenkins installation and setup:

👉 Install Jenkins on EC2

sudo apt update
sudo apt install openjdk-17-jre
java -version

# Add Jenkins key & repo
curl -fsSL https://pkg.jenkins.io/debian/jenkins.io.key | sudo tee \
  /usr/share/keyrings/jenkins-keyring.asc > /dev/null 
echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
  https://pkg.jenkins.io/debian binary/ | sudo tee \
  /etc/apt/sources.list.d/jenkins.list > /dev/null

sudo apt update
sudo apt install jenkins

sudo systemctl enable jenkins
sudo systemctl start jenkins
sudo systemctl status jenkins

Note:

  • Allow inbound TCP port 8080 in your EC2 Security Group.

👉Install Jenkins on EC2 using docker.

sudo docker pull jenkins/jenkins

sudo docker run -d -p 80:8080 docker.io/jenkins/jenkins:latest
// if any container is running on port 80 then kill it using docker kill command.

Run this url: http://34.20.103.1:8080

👉 Jenkins Initial Setup

1️⃣ Open: http://34.20.103.1:8080

sudo cat /var/lib/jenkins/secrets/initialAdminPassword
//you will get password.

2️⃣ Copy admin password:

3️⃣ Install suggested plugins, create admin user.

  • you will get url for jenkins

Go to ec2 instance → check jenkins is installed or not.s

sudo systemctl status jenkins

👉 Jenkins set up an agent.

dashboard → setup an agent → new node → node name → permanent Agent → Create

Name → description → number executors → remote root directory → /home/ubuntu (ec2 → pwd) → label → launch method -use websocket → save


Way 3: Jenkins deployment of Django-todo using AWS EC2

👉 Create Job

1️⃣ New Job → Freestyle project nam

2️⃣ go to ec2 → go inside project → pwd → cd/home/ubuntu/projects/django-todo

3️⃣ go to → ec2 shell → chmod 777 django-todo/

4️⃣ we dont have permission of project to jenkins . so we gave permission

# Example shell commands:
cd/home/ubuntu/projects/django-todo
docker build -t todo-app .
docker run -d -p 8000:8000 todo-app

save it. -> build now

✅ Make sure port 8000 is free:

doc
ker ps
docker kill <container_id>

Run:http://18.218.50.127:8000

Redeploy?

  • If you make any change in code.

    Go to github → do changes → commit changes in gihub/ Push code to GitHub → Jenkins → Build now.


Way 4: Jenkins CI/CD pipeline with github Integration:

👉 GitHub Personal Access Token (PAT)

1️⃣ GitHub → Settings → Developer settings → Personal access tokens

2️⃣ Generate → Name: jenkins-cicd → Select repo, workflow → Copy token.

👉Go to Jenkin URL:

login Jenkin.

👉 Install Plugins

1️⃣ Go to Manage Jenkins → Plugin Manager
2️⃣ Install: Git plugin

👉 Give Jenkins person access token

  • Manage Jenkins → Configure system

  • Add GitHub server → Add credentials →
    Kind: Username with secret → secret text → secret will github access token
    ID: ygive any id.

  • Select creditials → save

    Jenkins and github is connected.

👉 Create Yaml file:

docker-compose.yml and push it to github.

version: "3.3"
services:
  web:
    build: .
    ports:
      - "8000:8000"

👉 Install docker compose:

docker-compose -v
docker-compose config

# Add Jenkins user to Docker group:
sudo usermod -aG docker jenkins

👉 Create a job:

1️⃣ New Job → Freestyle project

2️⃣ SCM: Git → Repo URL → Branch name - develop → Build step → Execute shell:

sudo docker-compose down
docker-compose up -d --force-recreate --no-deps --build web
to not shut down docker container and again not to up for that.

save it. Build now.

Make sure on port 8000 is anything running or not. If running kill it.

Run: http://18.218.50.127:8000

0
Subscribe to my newsletter

Read articles from Neha Sawant directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Neha Sawant
Neha Sawant