How I Deployed a 2-Tier Flask App with MySQL Database

Junaid JavedJunaid Javed
3 min read

Introduction

Recently, I worked on deploying a 2-Tier Flask application with a MySQL database. The goal was to containerize both services using Docker and manage them with Docker Compose for easy deployment.

I started by creating a Dockerfile for the Flask application. I used a Python base image, created a working directory, and copied the application code from the src folder into it. Then, I installed all the required dependencies and libraries. Finally, I added a CMD instruction to run the app with python app.py.

After that, I created a docker-compose.yml file to manage both services—Flask and MySQL. This helped me avoid writing long docker commands manually and made it easier to define configurations in a key-value format.

Docker Compose Setup

In the docker-compose.yml file, I defined two services:

MySQL Container

  • Gave it a custom container name

  • Built the image

  • Set necessary environment variables (like root username/password)

  • Mounted volumes to persist data even if the container was removed

  • Added a healthcheck to verify if the MySQL container was alive by running mysqladmin ping with retries, intervals, and a startup period

  • Exposed the host port 3306 mapped to container port 3306

Flask Container

  • Set the container name and built the image

  • Tagged and pushed the image to Docker Hub, then pulled it back for deployment

  • Exposed the host port 5000 mapped to container port 5000

  • Set required environment variables

  • Added a depends_on condition for MySQL to ensure it only starts after the database is healthy

  • Added a healthcheck to hit localhost:5000/health and verify the response is 200 OK

  • Set restart policy to always

I also created a bridge network so that both containers could communicate internally. This allowed the Flask application to connect directly to the MySQL database.

Finally, I ran docker compose up to deploy the application.

The Challenge

Initially, the deployment didn’t work as expected. The Flask container didn’t respond on port 5000 when accessed publicly.

After some debugging, I realized the issue was with the AWS EC2 security group rules. I forgot to allow inbound traffic on port 5000, so the instance was blocking external requests.

The Fix

I went to my AWS EC2 instance Networking → Security Groups → Edit Inbound Rules and added a new rule:

  • Custom TCP Rule for port 5000

  • Source: Anywhere (0.0.0.0/0)

Once I updated the firewall rules, the application became accessible at:

http://public-ip:5000/health

And finally, the deployment was successful! ✅

Key Learnings

  • Always double-check security group rules when deploying apps on AWS EC2.

  • Docker healthchecks are very helpful to ensure services are running as expected.

  • Using Docker Compose makes multi-container deployments much easier and cleaner.

Tech Stack

  • AWS EC2 Instance

  • Docker

  • Docker Compose v2

  • Docker Hub Registry

🔗 GitHub Repository: (https://github.com/jj6977/two-tier-flask-app)

0
Subscribe to my newsletter

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

Written by

Junaid Javed
Junaid Javed