Skip to main content

Command Palette

Search for a command to run...

Building a 2-Tier Application with Docker Compose (Flask + MySQL) — Step-by-Step Guide

Updated
3 min read
Building a 2-Tier Application with Docker Compose (Flask + MySQL) — Step-by-Step Guide

Introduction

After successfully deploying a Flask app using Docker, I wanted to go one step further.

In real-world applications, we don’t just run a single container — we connect multiple services.

So in this project, I built a 2-tier application:

  • Flask (Backend)

  • MySQL (Database)

And honestly… this is where things got interesting.

Containers didn’t connect, services crashed, and debugging became the main learning.

In this blog, I’ll walk you through everything step-by-step — including real issues and fixes.


🎯 What You Will Learn

  • What is a 2-tier architecture

  • How to connect multiple containers

  • How Docker Compose works

  • How to use volumes for persistence

  • How to debug container communication issues


🏗️ Architecture Overview

User → Flask Container → MySQL Container

👉 Flask handles requests 👉 MySQL stores data


⚙️ Prerequisites

  • Docker installed

  • Basic Flask knowledge

  • Linux terminal basics


🚀 STEP-BY-STEP IMPLEMENTATION


🔵 Step 1: Project Structure

app.py
requirements.txt
Dockerfile
docker-compose.yml

🔵 Step 2: Flask App Code

Basic Flask app connecting to MySQL.

👉 Important part:

app.config['MYSQL_HOST'] = 'mysql'

⚠️ NOT localhost


🔵 Step 3: Create Dockerfile

FROM python:3.9-slim

WORKDIR /app

COPY requirements.txt .

RUN pip install -r requirements.txt

COPY . .

CMD ["python", "app.py"]

🔵 Step 4: Create docker-compose.yml

services:
  mysql:
    image: mysql:5.7
    environment:
      MYSQL_DATABASE: devops
      MYSQL_ROOT_PASSWORD: root
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql

  flask:
    build: .
    ports:
      - "5000:5000"
    environment:
      MYSQL_HOST: mysql
      MYSQL_USER: root
      MYSQL_PASSWORD: root
      MYSQL_DB: devops
    depends_on:
      - mysql

volumes:
  mysql-data:

🔵 Step 5: Run Application

docker compose up -d

🔵 Step 6: Access Application

http://your-ip:5000

🔥 REAL PROBLEMS I FACED

(MOST IMPORTANT)


❌ Problem 1: Flask Couldn’t Connect to MySQL

Error:

Can't connect to server on 'mysql'

Cause:

  • MySQL not ready yet

Fix:

  • Add retry logic OR restart policy

❌ Problem 2: Using localhost

Wrong:

localhost ❌

Correct:

mysql (service name) ✅

❌ Problem 3: Data Loss

Cause:

  • No volume

Fix:

volumes:
  - mysql-data:/var/lib/mysql

❌ Problem 4: YAML Errors

Cause:

  • Wrong indentation

  • Wrong keys

Fix:

  • Proper formatting

❌ Problem 5: Container Restart Loop

Cause:

  • Dependency issue

Fix:

  • restart policy

  • proper service handling


🧠 KEY LEARNINGS

  • Containers are isolated but connected via network

  • Docker Compose simplifies multi-container apps

  • Volumes are critical for databases

  • Debugging is the most important skill


🚀 FINAL OUTPUT

  • Flask app running

  • MySQL connected

  • Data stored successfully

  • Multi-container system working


🚀 WHAT’S NEXT

  • Add Nginx (reverse proxy)

  • Deploy using ECS

  • Move to Kubernetes


💡 FINAL THOUGHTS

This project taught me:

“Running multiple services is not just about starting containers — it’s about making them communicate properly.”

If you’re learning DevOps: 👉 Start small 👉 Then build systems 👉 Then break and debug


🙌 Connect With Me

More DevOps projects coming soon 🚀