Easy Steps to Build a Two-Tier Flask Application with Docker

Easy Steps to Build a Two-Tier Flask Application with Docker

In this blog, we’ll walk through building a two-tier Flask app with a MySQL database using Docker. The project demonstrates two key Docker concepts: Docker Network and Docker Volume. These concepts are essential when dealing with multi-container applications, enabling communication and data persistence. Let’s dive in!


What Are Docker Volume and Docker Network?

Docker Volume
Volumes provide persistent storage for Docker containers. Think of them as a "data-safe zone" where files survive container deletions. For instance, you can store your database files in a volume so the data won’t disappear even if the database container stops or is removed.

Docker Network
Networks allow Docker containers to talk to each other securely. For example, in this project, the Flask app and the MySQL database will use a shared network to communicate seamlessly.


Setting Up the Two-Tier Flask App

Follow these steps to deploy the app:

Step 1: Create an EC2 Instance

  • Launch an EC2 instance to serve as the environment for our Docker setup.

Step 2: Install Docker

Run the following commands to install Docker on the EC2 instance:

sudo apt update
sudo apt install docker.io -y

Step 3: Pull the MySQL Docker Image

Fetch the MySQL image from the Docker Hub public registry and verify it:

docker pull mysql

Step 4: Grant User Permissions

Allow your user to access Docker without using sudo every time:

sudo usermod -aG docker $USER && newgrp docker

Step 5: Reboot the System

To apply the changes, restart your instance:

sudo reboot

Step 6: Clone the Project

Download the Flask app project files from a public repository.

Step 7: Create a Dockerfile

Set up a Dockerfile to containerize the Flask app.

# Use an official Python runtime as the base image
FROM python:3.9-slim

# Set the working directory in the container
WORKDIR /app

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

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

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

# Copy the rest of the application code
COPY . .

# Specify the command to run your application
CMD ["python", "app.py"]

Step 8: Build the Flask App Container

Build the container with this command:

docker build -t two-tier-backend:latest .

Step 9: Create a Docker Network

Create a bridge network for the app and database to communicate:

docker network create two-tier-nw

Step 10: Run the Containers

Run both containers (Flask and MySQL) on the same network.

  1. Run MySQL
    Start the MySQL container with environment variables:

     docker run -d --name mysql --network two-tier-nw \
     -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=devops mysql
    

  2. Run Flask App
    Start the Flask app container with the required environment variables:

     docker run -d -p 5000:5000 --network two-tier-nw \
     -e MYSQL_HOST=mysql -e MYSQL_USER=root \
     -e MYSQL_PASSWORD=root -e MYSQL_DB=devops two-tier-backend:latest
    

Step 11: Update Security Group

Allow inbound traffic on port 5000 in your EC2 security group.

Step 12: Access the App

Open your browser and access the Flask app using the public IP of your EC2 instance:

http://<EC2_IP>:5000


The Data Loss Problem

If the MySQL container is stopped or deleted, the database data will be lost. This is because, by default, container storage is ephemeral—it doesn’t persist after the container is gone.

Reproducing the Issue

  1. Stop and remove the MySQL container:

     docker stop mysql && docker rm mysql
    

  2. Re-run the containers and check the app. You’ll notice that the database is empty again.

    Access the site again - Data will get lost


The Solution: Docker Volumes

To ensure your data persists even after container crashes, bind a Docker Volume to the MySQL container. Volumes store data outside the container, on the host system.

Step 1: Create a Volume

Create a new Docker volume:

docker volume create mysql-data-backup

Step 2: Bind the Volume to the MySQL Container

Re-run the MySQL container, binding the volume to /var/lib/mysql (where MySQL stores its data):

docker run -d --name mysql --network two-tier-nw \
-v mysql-data-backup:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=devops mysql

Step 3: Verify Data Persistence

Now, even if the MySQL container is removed, the data will remain intact in the volume.


Conclusion

This project showcases how Docker Volumes and Networks simplify multi-container application management. You learned how to:

  1. Build and deploy a two-tier Flask app with MySQL.

  2. Set up container communication using Docker Network.

  3. Persist data with Docker Volume.

These concepts are foundational for anyone working with Docker in real-world applications. If you have any questions, feel free to ask in the comments!