5. Simple Python + Flask + MySQL microservice, containerize it with Docker

Description: Build a simple Python + Flask + MySQL microservice, containerize it with Docker, and demonstrate container monitoring and log management

Objective

Learn to:

  1. Build a simple Python web app (Flask)
  2. Containerize it using Docker
  3. Connect it with a MySQL database container
  4. Monitor logs, running containers, and troubleshoot errors

🧰 1. Prerequisites

Ensure the following are installed on your Ubuntu system:

docker -v
docker-compose -v
python3 -V

If docker-compose is missing, install:

sudo apt install docker-compose -y

πŸ“ 2. Project Folder Structure

python-docker-demo/
β”‚
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ app.py
β”‚   β”œβ”€β”€ config.py
β”‚   β”œβ”€β”€ requirements.txt
β”‚   β”œβ”€β”€ Dockerfile
β”‚
β”œβ”€β”€ docker-compose.yml
└── README.md

🐍 3. Create Application Files

a. app.py

from flask import Flask, jsonify
import mysql.connector
import os

app = Flask(__name__)

db_config = {
    "host": os.getenv("DB_HOST", "mysql"),
    "user": os.getenv("DB_USER", "root"),
    "password": os.getenv("DB_PASS", "password"),
    "database": os.getenv("DB_NAME", "quotesdb")
}

@app.route('/')
def home():
    return jsonify({"message": "Welcome to Python + Docker Demo!"})

@app.route('/quotes')
def get_quotes():
    try:
        conn = mysql.connector.connect(**db_config)
        cursor = conn.cursor()
        cursor.execute("SELECT text, author FROM quotes")
        result = cursor.fetchall()
        cursor.close()
        conn.close()
        return jsonify(result)
    except Exception as e:
        return jsonify({"error": str(e)}), 500

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

b. config.py

DB_HOST = "mysql"
DB_USER = "root"
DB_PASS = "password"
DB_NAME = "quotesdb"

c. requirements.txt

flask
mysql-connector-python

🐳 4. Create Dockerfile

FROM python:3.9-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 5000

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

🧩 5. Create docker-compose.yml

This will bring up both the Python app and MySQL containers together.

version: '3.8'

services:
  app:
    build: ./app
    container_name: python_app
    ports:
      - "5000:5000"
    environment:
      - DB_HOST=mysql
      - DB_USER=root
      - DB_PASS=password
      - DB_NAME=quotesdb
    depends_on:
      - mysql
    restart: always

  mysql:
    image: mysql:5.7
    container_name: mysql_db
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: quotesdb
    ports:
      - "3306:3306"
    volumes:
      - mysql_data:/var/lib/mysql

volumes:
  mysql_data:

βš™οΈ 6. Initialize the Database

Once containers are up, create the table and insert sample data.

docker exec -it mysql_db mysql -uroot -ppassword -e "CREATE DATABASE IF NOT EXISTS quotesdb;"

docker exec -it mysql_db mysql -uroot -ppassword -e "USE quotesdb; CREATE TABLE quotes (id INT AUTO_INCREMENT PRIMARY KEY, text VARCHAR(255), author VARCHAR(100));"

docker exec -it mysql_db mysql -uroot -ppassword -e "USE quotesdb; INSERT INTO quotes (text, author) VALUES ('Life is what happens when you’re busy making other plans.', 'John Lennon');"

▢️ 7. Build and Run

docker-compose up --build

Access app:
πŸ‘‰ http://localhost:5000
πŸ‘‰ http://localhost:5000/quotes


🧾 8. Log Monitoring and Container Management

TaskCommandDescription
List running containersdocker psShows container IDs and names
View logsdocker logs python_appView app logs
Follow logs livedocker logs -f python_appMonitor real-time logs
Enter container shelldocker exec -it python_app /bin/bashAccess running container
Restart containerdocker restart python_appRestart service
View resource usagedocker statsCPU, memory, network stats
Remove stopped containersdocker container pruneClean up
Stop all containersdocker stop $(docker ps -q)Gracefully stop everything

🚨 9. Troubleshooting Common Issues

IssueCauseFix
Flask app not accessiblePort not exposedCheck Dockerfile & Compose port mapping
Database connection failedWrong env vars or DB not readyAdd depends_on and retry logic
CrashLoop or container exitsSyntax / runtime errorRun docker logs python_app
MySQL permission deniedWrong credentialsCheck env vars & MySQL logs

πŸ“Š 10. Clean Up

docker-compose down

docker system prune -a

Scroll to Top