Skip to main content

Command Palette

Search for a command to run...

Deploy a Flask + MariaDB Note App on EC2 (Amazon Linux 2023) — Complete Guide

How to Host a Python Flask App with a MariaDB Database on AWS

Updated
4 min read
Deploy a Flask + MariaDB Note App on EC2 (Amazon Linux 2023) — Complete Guide
M

In a world where technology advances at a breakneck pace, I'm a passionate developer always inspired by the latest innovations. The revolutionary science fiction of The Matrix (1999) ignited my love for the genre and the idea of what's possible beyond the screen. When I'm not immersed in code, you can find me lost in the melodies of a piano, a peaceful counterpoint to the logic and structure of development. It’s in this harmony of technology and art that I find my true rhythm.

This guide walks you through deploying a simple Flask web app connected to a MariaDB database on a free-tier Amazon EC2 instance running Amazon Linux 2023.

Prerequisites

  • An AWS account

  • EC2 instance (Amazon Linux 2023)

  • Security group with port 5000 open (or port 80 if using a web server)

  • SSH access to the instance

  • Basic knowledge of Python & Linux terminal

Step 1 : Connect to your EC2 instance

We will login using Keypair method and Powershell or Terminal on Linux by Using SSH command.

ssh -i your-key.pem ec2-user@<your-ec2-public-ip>

Step 2 : Install the required packages and setting up the environment.

Here is a list of all python packages needed for the deployment. Keep in mind the current working Python version is (3.9.23)

This command is for installing the required packages

sudo dnf install -y python3 python3-pip mariadb105-server mariadb105 git

Note: You need to enable mariadb and start it to make it work correctly with the web app.

sudo systemctl enable mariadb
sudo systemctl start mariadb

Step 3 : Creating the folder structure and writing the required codes for the app.

noteapp/
├── app.py               # Main Flask application
├── config.py            # App configuration (DB URI, secret key)
├── models.py            # SQLAlchemy models (Note table)
├── requirements.txt     # Python dependencies
├── templates/
│   └── index.html       # HTML template for the app UI
└── venv/                # Python virtual environment (auto-created)

Python Files

  • app.py

      from flask import Flask, request, redirect, render_template
      from config import SQLALCHEMY_DATABASE_URI, SECRET_KEY
      from models import db, Note
    
      app = Flask(__name__)
      app.config['SQLALCHEMY_DATABASE_URI'] = SQLALCHEMY_DATABASE_URI
      app.config['SECRET_KEY'] = SECRET_KEY
    
      db.init_app(app)
    
      with app.app_context():
          db.create_all()
    
      @app.route('/', methods=['GET', 'POST'])
      def index():
          if request.method == 'POST':
              content = request.form['content']
              if content:
                  new_note = Note(content=content)
                  db.session.add(new_note)
                  db.session.commit()
              return redirect('/')
          notes = Note.query.all()
          return render_template('index.html', notes=notes)
    
      if __name__ == '__main__':
          app.run(host='0.0.0.0', port=5000)
    
  • config.py

    • Remember to update your database username and password
    import os

    DB_USER = 'root'
    DB_PASSWORD = 'maro1234'
    DB_HOST = 'localhost'
    DB_NAME = 'notesdb'

    SQLALCHEMY_DATABASE_URI = f'mysql+pymysql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}/{DB_NAME}'
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    SECRET_KEY = os.urandom(24)
  • models.py

      from flask_sqlalchemy import SQLAlchemy
    
      db = SQLAlchemy()
    
      class Note(db.Model):
          id = db.Column(db.Integer, primary_key=True)
          content = db.Column(db.Text, nullable=False)
    
  • requirements.txt

      Flask==3.1.1
      Flask-SQLAlchemy==3.1.1
      PyMySQL==1.1.0
    
  • templates/index.html

      <!DOCTYPE html>
      <html>
      <head>
          <title>Notes</title>
      </head>
      <body>
          <h1>My Notes</h1>
          <form method="POST">
              <textarea name="content" required></textarea><br>
              <button type="submit">Add Note</button>
          </form>
          <ul>
              {% for note in notes %}
                  <li>{{ note.content }}</li>
              {% endfor %}
          </ul>
      </body>
      </html>
    

    Step 4 : Creating the virtual environment and running the application

We need to setup the virtual environment for the app for many useful reason:

  • Keeps your app’s dependencies isolated from the system.

  • Prevents version conflicts.

  • Enables reproducibility on other systems or servers.

python3 -m venv venv
source venv/bin/activate
pip install --upgrade pip
pip install Flask Flask-SQLAlchemy PyMySQL

Step 5 : Running the application

We will write this command in the virtual environment terminal

python app.py

To access the application , open in the browser :

http://<your-ec2-public-ip>:5000
  • You need to replace the placeholder with your EC2 Public IP address

Here is a screenshot of the app while its running.

Summary for the project requirements

  • Amazon Linux + MariaDB + Flask app

  • Systemd starts the DB

  • Flask reads from MariaDB using SQLAlchemy and PyMySQL

  • Public IP + port 5000 = access from anywhere

Backing up the database on a mounted EBS Volume.

  • Attach & Mount EBS Volume.

Important Note : You need to know the correct name of the attached volume by using lsblk command and replace it in the /dev/…

sudo mkfs -t xfs /dev/nvme1n1   # format the disk (only once!) 
sudo mkdir /mariadb
sudo mount /dev/nvme1n1 /mariadb
  • Persist Across reboots

echo "/dev/nvme1n1 /mariadb xfs defaults,nofail 0 0" | sudo tee -a /etc/fstab
  • Stop MariaDB

sudo systemctl stop mariadb
  • Setting Permissions

sudo chown -R mysql:mysql /mariadb/mysql
  • Restarting MariaDB

sudo systemctl start mariadb
  • Backing up the DB

sudo mysqldump -u root -p notesdb > /mariadb/notesdb_backup.sql

To confirm the backup is successful you need to run this command

ls -lh /mariadb

The output should be like this

-rw-r--r-- 1 root root 12K Jul 16 10:25 notesdb_backup.sql

Projects

Part 2 of 2

This series is designed to be a hands-on guide, covering everything from infrastructure provisioning to continuous delivery. You'll not only learn the theory behind key DevOps concepts, but you'll also see them in action as we build out our project.

Start from the beginning

Automated Deployment of a Go Web App on AWS EC2 with Daily Backups Using Ansible

Boost Your Go Web App's Deployment with AWS EC2 Automation and Daily Data Backup