My Journey with Docker: Containerizing a Notes App

·

3 min read

My Journey with Docker: Containerizing a Notes App

My Journey with Docker: Containerizing a Django Notes App

Introduction

Learning Docker has been an exciting journey, and I wanted to apply it to a real-world project. I followed Londhe Shubham’s YouTube channel, which helped me understand containerization and its role in DevOps. To solidify my learning, I cloned a Django-based Notes App from GitHub and focused on containerizing it using Docker and Docker Compose.

In this blog, I’ll walk you through how I Dockerized the application and the challenges I faced.

Technologies Used

For this project, I used the following technologies:

  • Backend: Django, Django REST Framework (Cloned from GitHub)

  • Database: MySQL

  • Deployment: Docker, Docker Compose, Nginx

Dockerizing the App

1. Writing the Dockerfile

To containerize the Django application, I created a Dockerfile that:

  • Uses a Python base image

  • Copies application files into the container

  • Installs dependencies

  • Runs the Django app with Gunicorn using the following Dockerfile:

# Use official Python image as base
FROM python:3.9

# Set the working directory
WORKDIR /app

# Copy application files
COPY requirements.txt /app/backend

# Install dependencies
RUN apt-get update \
    && apt-get upgrade -y \
    && apt-get install -y gcc default-libmysqlclient-dev pkg-config \
    && rm -rf /var/lib/apt/lists/*

# Install app dependencies
RUN pip install mysqlclient
RUN pip install --no-cache-dir -r requirements.txt

COPY . /app/backend

# Expose the application port
EXPOSE 8000

# Run Django with Gunicorn
#RUN python manage.py migrate
#RUN python manage.py makemigrations

2. Setting up Docker Compose

I used Docker Compose to manage multiple services. Below is a breakdown:

version: "3.8"

services:
  nginx:
    build: ./nginx 
    image: nginx
    container_name: nginx_cont
    ports:
      - "80:80"
    restart: always
    depends_on:
      - django 
    networks:
      - notes-app

  db: 
    image: mysql
    container_name: "db_cont"
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: test_db
    volumes:
      - ./mysql-data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-proot"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 60s
    networks:
      - notes-app

  django:
    build:
      context: .
    container_name: "django_cont"
    command: sh -c "python manage.py migrate --no-input && gunicorn notesapp.wsgi --bind 0.0.0.0:8000"
    ports:
      - "8000:8000"
    env_file:
      - ".env"
    restart: always
    depends_on:
      - db
    networks:
      - notes-app
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:8000/admin || exit 1"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 60s

networks:
  notes-app:

This setup ensures that:

  • Django runs inside a container and connects to MySQL.

  • MySQL data is persisted using Docker volumes.

  • Nginx acts as a reverse proxy for the Django app.

3. Managing Environment Variables

I stored sensitive database credentials in a .env file:

DB_NAME=test_db
DB_USER=root
DB_PASSWORD=root
DB_PORT=3306
DB_HOST=db_cont

Running the App with Docker

To spin up the entire stack, I used:

docker-compose up -d

This command launches all services in the background, making the application accessible via Nginx.

Challenges Faced & Solutions

  1. Database Connection Issues

    • Solution: Used Docker networks to ensure MySQL and Django containers could communicate.
  2. Docker Volumes for Data Persistence

    • Solution: Mounted a volume for MySQL data to avoid data loss when restarting containers.
  3. Django Migrations in Containers

    • Solution: Added python manage.py migrate to the startup command in docker-compose.yml.

Conclusion & Next Steps

This project helped me understand how to containerize an existing web application with Docker. Next, I plan to work on another 3-tier Docker project to deepen my understanding of containerized applications. After that, I'll start exploring Kubernetes and CI/CD integration.

If you’re also learning Docker, I highly recommend applying it to a project like this. Feel free to check out the original repo and try containerizing it yourself!

What’s next on your DevOps learning journey? Let’s connect and discuss!