Skip to content

davidahdy/flask-notes-compose

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

6 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Flask Notes Webapp β€” Docker Compose

A minimal note-taking web application built with Flask and MySQL, containerized using Docker and orchestrated with Docker Compose. This project provides both a simple web UI and a REST API for creating and listing notes, with persistent MySQL storage.

πŸ”— GitHub Repository: https://github.com/davidahdy/flask-notes-compose


πŸš€ Features

  • Flask-based web app with HTML UI and REST API endpoints
  • MySQL database with persistent storage using Docker volumes
  • Environment variables for secure configuration management
  • Docker Compose for multi-container orchestration
  • Health checks for both web and database services
  • Non-root container security implementation
  • AWS EC2 deployment ready

πŸ› οΈ Technologies Used

Technology Purpose
Flask Python microframework for web development
MySQL 8.x Relational database for data persistence
Docker Containerization platform
Docker Compose Multi-container orchestration
Gunicorn WSGI HTTP server for production

πŸ“‹ Prerequisites

Before running this project, ensure you have:

  • Docker (version 20.10+) and Docker Compose (v2) installed
  • Git for cloning the repository
  • Basic terminal/command line knowledge
  • AWS EC2 instance (for cloud deployment) or local machine

Installation Links:


πŸ“ Project Structure

flask-notes-compose/
β”œβ”€β”€ .env                    # Environment variables (DO NOT COMMIT)
β”œβ”€β”€ .env.example           # Template for environment variables
β”œβ”€β”€ .gitignore             # Git ignore rules
β”œβ”€β”€ Dockerfile             # Web app container build file
β”œβ”€β”€ README.md              # This documentation
β”œβ”€β”€ app/                   # Flask application source code
β”‚   β”œβ”€β”€ __init__.py        # Flask app initialization
β”‚   β”œβ”€β”€ static/            # Static assets (CSS, JS, images)
β”‚   └── templates/         # HTML templates
β”‚       └── index.html     # Main UI template
β”œβ”€β”€ db/                    # Database configuration
β”‚   └── init/              # SQL initialization scripts
β”‚       └── 001_create_table.sql
β”œβ”€β”€ docker-compose.yml     # Docker Compose configuration
β”œβ”€β”€ docs/                  # Documentation files
└── requirements.txt       # Python dependencies

βš™οΈ Environment Variables

The application uses the following environment variables (defined in .env):

Variable Description Example
MYSQL_ROOT_PASSWORD MySQL root user password secure_root_pass123
MYSQL_DATABASE Database name notesdb
MYSQL_USER MySQL application user notesuser
MYSQL_PASSWORD MySQL application user password user_pass123
HOST_PORT Host port for web application 8080
DB_USER Database user for Flask app notesuser
DB_PASSWORD Database password for Flask app user_pass123
DB_NAME Database name for Flask app notesdb
DB_HOST Database hostname (container name) db
DB_PORT Database port 3306

πŸš€ Quick Start

1. Clone the Repository

git clone https://github.com/davidahdy/flask-notes-compose.git
cd flask-notes-compose

2. Setup Environment Variables

cp .env.example .env
# Edit .env with your preferred MySQL credentials and HOST_PORT

3. Build and Start the Application

docker compose up -d --build

4. Verify Installation

# Check container status
docker compose ps

# View logs
docker compose logs -f web

# Test health endpoint
curl -i http://localhost:${HOST_PORT:-8080}/healthz

Expected health check response:

{
  "status": "healthy",
  "database": "connected",
  "timestamp": "2025-08-13T10:30:45Z"
}

🌐 Usage

Web Interface

Access the web UI at:

Web Interface

API Endpoints

Method Endpoint Description Request Body
GET /notes List all notes N/A
POST /notes Create a new note {"content":"Your note text"}
GET /healthz Health check N/A

API Examples

Create a Note

curl -X POST http://localhost:8080/notes \
  -H "Content-Type: application/json" \
  -d '{"content":"Buy groceries for the week"}'

Response (201 Created):

{
  "id": 1,
  "content": "Buy groceries for the week",
  "created_at": "2025-08-13T10:30:45Z",
  "message": "Note created successfully"
}

List All Notes

curl http://localhost:8080/notes

Response (200 OK):

{
  "notes": [
    {
      "id": 1,
      "content": "Buy groceries for the week",
      "created_at": "2025-08-13T10:30:45Z"
    },
    {
      "id": 2,
      "content": "Schedule dentist appointment",
      "created_at": "2025-08-13T09:15:30Z"
    }
  ],
  "total": 2
}

Health Check

curl http://localhost:8080/healthz

Response (200 OK):

{
  "status": "healthy",
  "database": "connected",
  "timestamp": "2025-08-13T10:30:45Z"
}

πŸ’Ύ Data Persistence

MySQL data is stored in a Docker named volume (db-data) ensuring persistence between container restarts.

Reset Database

To completely wipe all data:

docker compose down -v  # Remove containers and volumes
docker compose up -d    # Restart with fresh database

Backup Data

# Create backup
docker compose exec db mysqldump -u root -p notesdb > backup.sql

# Restore backup
docker compose exec -T db mysql -u root -p notesdb < backup.sql

πŸ”§ Management Commands

View Logs

# All services
docker compose logs -f

# Specific service
docker compose logs -f web
docker compose logs -f db

Stop Services

# Stop containers (keep data)
docker compose down

# Stop containers and remove volumes (lose data)
docker compose down -v

Restart Services

docker compose restart

πŸ› Troubleshooting

Common Issues

Issue Cause Solution
Access denied for user Incorrect MySQL credentials Verify .env credentials match MYSQL_USER/MYSQL_PASSWORD
Port already in use Another service using the port Change HOST_PORT in .env to an available port
Health check failing Database not ready or connection issues Check logs: docker compose logs db web
Database schema missing Initialization scripts not executed Reset containers: docker compose down -v && docker compose up -d
Container won't start Resource constraints or Docker issues Check Docker Desktop resources and restart Docker

Debug Commands

# Check container resource usage
docker stats

# Inspect container details
docker compose exec web ps aux
docker compose exec db ps aux

# Test database connectivity
docker compose exec db mysql -u root -p -e "SHOW DATABASES;"

# Check application logs inside container
docker compose exec web tail -f /var/log/flask-app.log

Security Group (AWS EC2)

Ensure your EC2 Security Group allows:

  • Inbound: Port 8080 (or your HOST_PORT) from 0.0.0.0/0
  • Outbound: All traffic

☁️ AWS EC2 Deployment

Quick Deployment Steps

  1. Launch EC2 Instance

    • Use Amazon Linux 2 or Ubuntu 20.04+
    • Install Docker and Docker Compose
    • Configure Security Group for port 8080
  2. Deploy Application

    # On EC2 instance
    git clone https://github.com/davidahdy/flask-notes-compose.git
    cd flask-notes-compose
    cp .env.example .env
    # Edit .env with production credentials
    docker compose up -d --build
  3. Access Application

    • Web UI: http://<EC2_PUBLIC_IP>:8080
    • API: http://<EC2_PUBLIC_IP>:8080/notes

Production Considerations

  • Use strong, unique passwords in production .env
  • Set up SSL/TLS termination with a reverse proxy (nginx)
  • Implement log rotation and monitoring
  • Regular database backups
  • Consider using AWS RDS for database in production

πŸ” Security Notes

  • Never commit .env files to version control
  • Use strong passwords for all database credentials
  • Restrict database access to trusted networks only
  • Run containers as non-root user (implemented in Dockerfile)
  • Keep Docker images updated regularly
  • Monitor application logs for suspicious activity

πŸ§ͺ Testing

Manual Testing Checklist

  • Web UI loads successfully
  • Can create notes via web form
  • Notes persist after container restart
  • API endpoints return correct responses
  • Health check reports healthy status
  • Database connection works properly

Automated Testing

# Run basic API tests
./scripts/test-api.sh  # (if you create this script)

πŸ“– Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Web Browser   β”‚    β”‚   API Client     β”‚
β”‚   (Port 8080)   β”‚    β”‚   (curl/Postman) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
          β”‚                      β”‚
          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
                     β–Ό
            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
            β”‚  Flask Web App  β”‚
            β”‚   (Container)   β”‚
            β”‚   Port 5000     β”‚
            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
                      β”‚
                      β–Ό
            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
            β”‚ MySQL Database  β”‚
            β”‚   (Container)   β”‚
            β”‚   Port 3306     β”‚
            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit changes (git commit -m 'Add amazing feature')
  4. Push to branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

About

Flask note-taking app (Flask + MySQL, orchestrated with Docker Compose).

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published