Containerizing and Orchestrating of TaskZen

 Containerizing and Orchestrating a Full-Stack Task Management Application (TaskZen) with Docker and Docker Compose.  

 Introduction

  This document provides a detailed, step-by-step account of containerizing a modern, full-stack web application, "TaskZen." The application consists of a Python-based FastAPI backend and a React.js frontend. The primary goal of this exercise is to encapsulate each service into a portable, isolated Docker container, orchestrate their deployment using Docker Compose, and finally, publish the resulting images to a public container registry (Docker Hub). This process demonstrates a fundamental DevOps workflow for ensuring consistency, scalability, and ease of deployment across different environments.  

Objectives of Part 1: 

The primary objective of Part 1 is to achieve standalone containerization for the frontend and backend services. This involves: 

  • Creating a dedicated Dockerfile for the Python FastAPI backend to define its environment, dependencies, and execution command.
  • Creating a multi-stage Dockerfile for the React frontend to build the static assets and serve them efficiently using an Nginx web server.
  • Building Docker images for each service locally and verifying their integrity.
  • Running each container independently to confirm that the services operate correctly in isolation.

 

Objectives of Part 2:

The objective of Part 2 is to orchestrate the separately containerized services into a cohesive, single-command deployment. This is achieved by: 

  • Creating a docker-compose.yml file to define the multi-container application stack, including the backend and frontend services.
  • Establishing network communication between the frontend and backend containers.
  • Managing service dependencies to ensure the backend starts before the frontend attempts to connect.
  • Launching the entire application stack using a single docker-compose up command and verifying inter-container connectivity.

 

Objectives of Part 3

The final objective is to make the containerized application distributable and publicly accessible for deployment on any machine with Docker. This involves:

  • Authenticating with Docker Hub via the Docker CLI.
  • Correctly tagging the locally built frontend and backend images with the Docker Hub repository namespace.
  • Pushing the tagged images to the public Docker Hub registry.
  • Verifying the successful upload by checking the Docker Hub web interface and pulling the images on a different system.

 

Names of the containers involved and download links

 This project is built from original source code and does not use pre-existing containers from external sources. The base images used in the Dockerfile configurations are official, open-source images:

 

 

 Other software involved and purpose

Development and Orchestration Tools

Tool

Purpose

Version

Node.js

JavaScript runtime environment for frontend development and build processes.

22+

Python

Programming language for building the high-performance backend API.

3.11+

Docker Desktop

Core container platform for building, running, and managing isolated application environments.

N/A

Docker Compose

Multi-container orchestration tool for defining and running the full application stack (frontend + backend) with a single command.

3.9

Visual Studio Code

Integrated Development Environment (IDE) for code development and project management.

N/A

 

Frontend Technologies (React)

The frontend is a Single-Page Application (SPA) focused on performance and modern UI design.

Technology

Role

Version

React

Primary JavaScript library for building interactive user interfaces.

19.1.1

Vite

Next-generation frontend build tool and development server for rapid development.

7.1.2

Tailwind CSS

Utility-first CSS framework enabling rapid, highly customizable UI development.

4.1.12

React Router DOM

Declarative routing library essential for navigation in the React SPA.

7.8.2

Nginx Alpine

Lightweight production-grade web server used within the Docker container to serve static frontend assets.

N/A

Lucide React

Icon library providing beautiful and consistent SVG icons for the UI.

0.542.0

 

Backend Technologies (FastAPI/Python)

The backend is built as a fast, asynchronous REST API using Python's modern ecosystem.

Technology

Role

Version

FastAPI

Modern, high-performance Python web framework for building the REST APIs.

0.116.1+

Uvicorn

Lightning-fast ASGI server responsible for running the FastAPI application efficiently.

0.35.0+

SQLAlchemy

Python SQL toolkit and ORM for robust and efficient database interactions.

2.0.43+

Pydantic

Data validation library used by FastAPI to define data schemas and enforce type safety.

N/A

iCalendar

Library for parsing and generating iCalendar files (e.g., for task scheduling/export).

6.0.0+

python-dateutil

Provides powerful extensions to the standard Python datetime module for date handling.

2.8.2+

 

Database and Authentication

System/Tool

Purpose

Version

Supabase

Open-source platform acting as the primary backend-as-a-service, handling data and authentication.

2.18.1+

PostgreSQL

The core robust relational database system provided by Supabase.

N/A

Supabase Auth

Built-in system for user management, session handling, and secure authentication.

N/A

 

Supporting Tools

Tool

Role

Version

python-dotenv

Manages environment variables for secure configuration and credentials.

1.1.1+

ESLint

JavaScript linting tool ensuring code quality, style consistency, and catching errors early.

9.33.0

PostCSS

Tool used for transforming CSS with JavaScript plugins, often integrated with Tailwind CSS.

8.5.6

 

Overall architecture diagrams and explanations

Text Description of the Flow: 

The overall architecture follows a standard client-server model, externalized through Docker containers. 

  1. Part 1 (Containerization): The backend source code is the input to its Dockerfile, producing a taskzen-backend Docker image. Similarly, the frontend source code is the input to its Dockerfile, producing a taskzen-frontend image. The output is two independent, runnable Docker images stored locally. 
  2. Part 2 (Orchestration): The docker-compose.yml file takes the two build contexts (frontend and backend directories) as input. The docker-compose up command triggers the image builds and then starts two containers. The frontend container, upon receiving a user request from a web browser, makes an API call to the backend container over the Docker-managed network. The output is a fully functional, networked application running locally.
  3. Part 3 (Distribution): The locally built taskzen-frontend and taskzen-backend images are the input. The docker push command sends these images to Docker Hub. The output is the public availability of these images in a remote repository for anyone to pull and run. 

Full DA Input/Output Flow:

A user interacts with their web browser, which sends an HTTP request to the Nginx server in the taskzen-frontend container. Nginx serves the React application. The React app then makes API calls to the FastAPI server in the taskzen-backend container. The backend processes these requests, queries the external Supabase PostgreSQL database, and returns a response to the frontend, which then updates the UI for the user.

 

Logical Issues Found:

The provided architecture is logically sound for a modern web application. The separation of concerns between the frontend, backend, and database is clear. The use of Nginx to serve the static React build is a production-ready practice. The only potential point of failure is the network dependency on the external Supabase database; if the containers cannot reach the internet, the application will fail. This is an acceptable design choice for this architecture.

 

Architecture Diagram:

Architecture Explanation:

  The system employs a decoupled, service-oriented architecture implemented with Docker containers. The user-facing component is a taskzen-frontend container, which runs a lightweight Nginx server. This server's sole responsibility is to efficiently deliver the pre-built static files of the React.js single-page application (SPA) to the user's browser. This containerization ensures that the frontend's environment and dependencies are isolated and consistent.   All business logic, data processing, and database interactions are handled by the taskzen-backend container. This container runs a FastAPI application, exposing a RESTful API that the frontend consumes. By separating the backend, we can scale, update, and maintain it independently of the user interface. This backend container communicates with an external, cloud-hosted Supabase instance, which provides the PostgreSQL database for data persistence and handles user authentication, ensuring data is securely managed outside the containerized environment.  

Procedure — Part 1 (Dockerizing Frontend and Backend Separately)

In this part, we create Docker images for the frontend and backend applications individually. 

Step 1: Create Backend Dockerfile

A Dockerfile is created in the backend directory to define the steps for building the Python application image.

  

 

Step 2: Build the Backend Docker Image

Navigate to the project's root directory and run the build command. 

Bash:docker build -t taskzen-backend . 

 

Step 3: Run the Backend Container

Run the newly created image as a container to verify it works. 

Bash: docker run -p 8000:8000 taskzen-backend 

A screen shot of a computer

AI-generated content may be incorrect. 

Step 4: Create Frontend Dockerfile

A multi-stage Dockerfile is created in the frontend directory. The first stage builds the React app, and the second stage serves the build artifacts with Nginx.

Step 5: Build the Frontend Docker Image

From the root directory, build the frontend image.

 

Bash:  docker build -t taskzen-frontend . 

 


Step 6: Run the Frontend Container

Run the frontend container and map the port to access it from the browser.

 

Bash: docker run -p 5173:80 taskzen-frontend

 

Step 7 – Running Containers

Step 8 – Frontend

A screenshot of a computer

AI-generated content may be incorrect.

Step 9 – Backend

A screenshot of a computer

AI-generated content may be incorrect.

 

Procedure — Part 2 (Orchestrating with Docker Compose)

Here, we use Docker Compose to manage and run the multi-container application.

Step 1: Create docker-compose.yml File

Create a docker-compose.yml file in the project root to define both services.

Step 2: Launch the Application Stack

Run a single command from the root directory to build and start both containers. 

Bash: docker-compose up --build -d

 

Step 3: Verify Running Containers

Check the status of the running containers to ensure both are up and healthy.

 

Bash: docker-compose ps

 

Step 4: Basic Troubleshooting

To view logs for a specific service (e.g., the backend):

 

Bash:docker-compose logs backend

 

To stop and remove the containers:
 

Bash: docker-compose down


Procedure — Part 3 (Uploading to Docker Hub)

This part covers publishing the custom images to a public registry.

Step 1: Log in to Docker Hub

Use the Docker CLI to authenticate with your Docker Hub account.

 Bash: docker login

 A screen shot of a computer

AI-generated content may be incorrect. 


Step 2: Tag the Local Images

Tag your local images with your Docker Hub username and repository name. Replace your-dockerhub-username with your actual username. 

Bash:

docker tag taskzen-backend your-dockerhub-username /taskzen-backend:latest

docker tag taskzen-frontend your-dockerhub-username /taskzen-frontend:lates 

 


Step 3: Push the Images to Docker Hub

Push the tagged images to the remote repository.

Bash:

docker push your-dockerhub-username/taskzen-backend:latest

docker push your-dockerhub-username/taskzen-frontend:latest

A screenshot of a computer program

AI-generated content may be incorrect.


Step 4: Verify on Docker Hub 

Navigate to your Docker Hub profile in a web browser to confirm that both repositories (taskzen-backend and taskzen-frontend) have been created and contain the latest tag.

  A screenshot of a computer

AI-generated content may be incorrect.A screenshot of a computer

AI-generated content may be incorrect.A screenshot of a computer

AI-generated content may be incorrect. 

Modifications done to containers after downloading 

This project was developed from scratch, so no existing containers were downloaded and modified. The Dockerfiles were created to containerize original source code. The primary modifications involved:

 

  1. Base Image Selection: Choosing lightweight and official base images (python:3.11-slim, node:22-alpine, nginx:alpine) to keep the final image sizes small and secure.
  2. Multi-Stage Build (Frontend): Implementing a multi-stage build in the frontend Dockerfile was a key modification. This separates the build environment (with Node.js and npm) from the production environment (with Nginx), resulting in a much smaller and more secure final image that only contains the necessary static files and the web server.
  3. Nginx Configuration: A custom nginx.conf was added to the frontend container. This configuration is crucial for a Single-Page Application (SPA) as it redirects all routing requests to index.html, allowing the client-side React Router to handle them.

 

GitHub link / Docker Hub link of modified containers

 

Outcomes of your DA

  • Successfully created reproducible, isolated environments for both the frontend and backend services using Dockerfiles.
  • Demonstrated the ability to build and run each service as a standalone Docker container.
  • Orchestrated a multi-container application using Docker Compose, establishing a network bridge for inter-service communication.
  • Implemented a production-ready pattern for serving a React application using a multi-stage build with Nginx.
  • Successfully published the custom application images to Docker Hub, making them portable and easily distributable for deployment on any Docker-enabled host.
  • Gained practical experience in a core DevOps workflow, from source code to a distributable containerized application.

 

Conclusion

  This project successfully demonstrated the end-to-end process of containerizing and orchestrating a full-stack application. By leveraging Docker, we transformed a complex development setup into a simple, portable, and reproducible set of images. Docker Compose further simplified the process, allowing the entire application stack to be managed with a single command. The final step of publishing to Docker Hub completes the workflow, enabling seamless distribution and deployment. This exercise underscores the power of containerization in modern software development, providing a robust foundation for building scalable and maintainable systems.  


References 


Acknowledgements

I would like to express my sincere gratitude to Dr. T. Subbulakshmi for providing clear instructions and guidance throughout the completion of this Digital Assignment.
Special thanks to VIT SCOPE, under which this Cloud Computing course was offered, for enabling a practical understanding of containerization concepts through this project.

I also acknowledge the help of the official Docker and FastAPI documentation, which were invaluable resources during the development process.

Finally, I extend heartfelt thanks to my family, friends, and course instructor for their consistent support, motivation, and feedback throughout the project.


— Written by Dhilip Kumar P

Comments