Docker: Full-Stack Development with Flask & MySQL

Project Overview

This project involves creating a Flask-based web application that connects to a MySQL database running in a Dockerized environment. The project is structured with a Flask application in Python, utilizing Docker to manage the MySQL service and the web application.

Technologies Used

  • Flask: A micro web framework for Python used to create the web application.

  • MySQL: A relational database management system used to store data.

  • Docker: Containerization platform used to package and run the application and MySQL in isolated environments.

  • Python 3: The programming language for building the Flask web application.

  • Red Hat Universal Base Image 8 (UBI8): A lightweight, stable base image used for creating a customized Docker image.


Project Workflow

The project is organized as follows:

  1. Backend:

    • MySQL container to host the lwdb database and a students table.

    • The database contains sample data about students.

  2. Frontend:

    • Flask web application is responsible for handling HTTP requests and interacting with the MySQL database.
  3. Dockerization:

    • The Flask application is dockerized using a custom Docker image built from the Red Hat UBI8 base image.

    • MySQL is run in a separate Docker container.

    • Docker networking is used to enable communication between the Flask application and the MySQL container.


File Structure

/myapp
    ├── app.py
    └── Dockerfile

Flask Web Application (app.py)

The app.py file is the main Python script that runs the Flask application. It connects to the MySQL database and performs basic CRUD operations.

from flask import Flask
from flaskext.mysql import MySQL

app = Flask(__name__)

# Database connection configurations
ip = "172.17.0.2"  # MySQL container's IP
user = "aman"
password = "redhat"
dbname = "lwdb"

# Configuring Flask to use MySQL
app.config["MYSQL_DATABASE_USER"] = user
app.config["MYSQL_DATABASE_HOST"] = ip
app.config["MYSQL_DATABASE_PASSWORD"] = password
app.config["MYSQL_DATABASE_DB"] = dbname

# Initialize MySQL
mysql = MySQL()
mysql.init_app(app)

@app.route("/data")
def lwdata():
    # Connect to MySQL and retrieve data from 'students' table
    conn = mysql.connect()
    cursor = conn.cursor()
    cursor.execute("SELECT * FROM students")
    data = cursor.fetchall()
    return str(data)

# Run the application
app.run(host='0.0.0.0')

Explanation:

  • The Flask app is configured to connect to a MySQL database using flask-mysql.

  • The database host is defined as 172.17.0.2, which is the IP address of the MySQL container.

  • The /data route retrieves all records from the students table and returns them as a string.


Dockerfile

The Dockerfile is used to create a custom Docker image for the Flask web application. Below is the content of the Dockerfile:

FROM redhat/ubi8

# Install Python 3 and necessary packages
RUN yum install python3 -y

# Install Python dependencies for Flask and MySQL
RUN pip3 install flask
RUN pip3 install flask-mysql

# Set working directory in container
WORKDIR /myapp

# Copy the Flask app code from local to container
COPY app.py aman.py

# Set the entry point to run the Flask app
ENTRYPOINT [ "python3", "aman.py" ]

Explanation:

  • The FROM redhat/ubi8 line pulls the Red Hat Universal Base Image (UBI8) for a stable and lightweight base.

  • Python 3 is installed via yum.

  • Flask and the flask-mysql library are installed via pip3.

  • The working directory in the container is set to /myapp, where the Flask app resides.

  • The COPY command copies app.py from the local system to the Docker container and renames it aman.py.

  • The ENTRYPOINT runs aman.py when the container starts.


Steps to Set Up and Run the Application

1. Set Up MySQL Container

First, set up the MySQL container to host the database. The following commands are used to run the MySQL container:

docker run -dit --name db -e MYSQL_ROOT_PASSWORD=redhat -e MYSQL_USER=aman -e MYSQL_PASSWORD=redhat -e MYSQL_DATABASE=lwdb mysql

Explanation:

  • --name db: Assigns a name (db) to the container.

  • -e MYSQL_ROOT_PASSWORD=redhat: Sets the MySQL root password.

  • -e MYSQL_USER=aman: Creates a MySQL user (aman).

  • -e MYSQL_PASSWORD=redhat: Sets the password for the user aman.

  • -e MYSQL_DATABASE=lwdb: Creates the lwdb database.

2. Access MySQL and Set Up the Database

Once the MySQL container is running, you can log into the MySQL CLI:

docker exec -it db bash
mysql -u aman -p

In the MySQL prompt, run the following commands to create the students table:

USE lwdb;
CREATE TABLE students (
    id INT(5),
    name CHAR(200),
    city CHAR(10)
);
INSERT INTO students VALUES (1, "aman", "ranchi");
INSERT INTO students VALUES (2, "hemant", "jamshedpur");

3. Build the Docker Image for Flask App

To build the Docker image for the Flask app, navigate to the /myapp directory and run the following command:

docker build -t lwweb:v1 .

4. Run the Flask Web Application

After building the Docker image, run the Flask web app:

docker run -dit --name aman lwweb:v1

This will run the Flask application inside a container, which can be accessed via the IP address of the container (172.17.0.3 in this example) and port 5000.

5. Access the Application

You can access the Flask application in your web browser:

curl http://172.17.0.3:5000/data

This will return all records from the students table in the MySQL database.


Common Commands Used

MySQL Commands:

  • USE lwdb; — Selects the lwdb database.

  • SHOW TABLES; — Lists all tables in the database.

  • CREATE TABLE students (...); — Creates the students table.

  • SELECT * FROM students; — Retrieves all records from the students table.

  • INSERT INTO students VALUES (...); — Inserts data into the students table.

Docker Commands:

  • docker run -dit --name db mysql — Runs MySQL container.

  • docker ps -a — Lists all containers.

  • docker exec -it db bash — Opens a bash shell inside the MySQL container.

  • docker build -t lwweb:v1 . — Builds the Flask app Docker image.

  • docker run -dit --name aman lwweb:v1 — Runs the Flask app container.


Conclusion

This project successfully demonstrates a full-stack approach using Flask for the frontend, MySQL for the backend database, and Docker to manage both the MySQL and Flask containers. The Dockerized environment allows for an isolated, consistent deployment process.