Deploying a Flask + MySQL Two-Tier Application on AWS EC2 Using Shell Scripting and Docker

Introduction
In this project, I automated the deployment of a Flask and MySQL two-tier application on an AWS EC2 Ubuntu instance using Shell Scripting and Docker.
The automation script performs the following tasks:
Clones the application source code from GitHub
Installs Docker and Git
Configures Docker services
Creates a Docker network
Deploys a MySQL container
Builds and deploys the Flask application container
Verifies the deployment
Project Architecture
GitHub Repository
│
▼
AWS EC2 Instance
│
▼
Shell Script
│
┌──────┴──────┐
▼ ▼
MySQL Flask App
Container Container
│
▼
Application Access
Complete Shell Script
#!/bin/bash
# Deploy Flask + MySQL Two-Tier Application
code_clone() {
echo "Cloning the Flask application..."
if [ -d "two-tier-flask-app" ]; then
echo "Code directory already exists."
cd two-tier-flask-app || exit 1
else
git clone https://github.com//user name two-tier-flask-app.git || {
echo "Failed to clone repository."
return 1
}
cd two-tier-flask-app || exit 1
fi
}
install_requirements() {
echo "Installing Docker and Git..."
sudo apt-get update
sudo apt-get install -y docker.io git || {
echo "Failed to install dependencies."
return 1
}
}
required_restarts() {
echo "Starting Docker service..."
sudo systemctl start docker
sudo systemctl enable docker
sudo chown $USER /var/run/docker.sock || {
echo "Failed to configure Docker permissions."
return 1
}
}
deploy_mysql() {
echo "Creating Docker network..."
docker network create twotier 2>/dev/null || true
echo "Starting MySQL container..."
docker rm -f mysql 2>/dev/null || true
docker run -d \
--name mysql \
-v mysql-data:/var/lib/mysql \
--network twotier \
-e MYSQL_DATABASE=mydb \
-e MYSQL_ROOT_PASSWORD=admin \
-p 3306:3306 \
mysql:5.7 || {
echo "Failed to start MySQL container."
return 1
}
echo "Waiting for MySQL to initialize..."
sleep 30
}
deploy_flask() {
echo "Building Flask image..."
docker build -t flaskapp . || {
echo "Docker build failed."
return 1
}
docker rm -f flaskapp 2>/dev/null || true
echo "Starting Flask container..."
docker run -d \
--name flaskapp \
--network twotier \
-e MYSQL_HOST=mysql \
-e MYSQL_USER=root \
-e MYSQL_PASSWORD=admin \
-e MYSQL_DB=mydb \
-p 5000:5000 \
flaskapp:latest || {
echo "Failed to start Flask container."
return 1
}
}
verify_deployment() {
echo "Running containers:"
docker ps
}
echo "********** FLASK APPLICATION DEPLOYMENT STARTED **********"
code_clone || exit 1
install_requirements || exit 1
required_restarts || exit 1
deploy_mysql || exit 1
deploy_flask || exit 1
verify_deployment
echo "********** DEPLOYMENT COMPLETED SUCCESSFULLY **********"
Step 1: Clone the Application Repository
The code_clone() function checks whether the project directory already exists. If not, it clones the repository from GitHub.
git clone https://github.com/username/two-tier-flask-app.git
This helps avoid duplicate cloning and ensures the application source code is available on the EC2 instance.
Step 2: Install Required Packages
The install_requirements() function updates the package list and installs Docker and Git.
sudo apt-get update
sudo apt-get install -y docker.io git
Docker is required for containerization, and Git is used to clone the source code.
Step 3: Configure Docker Service
The required_restarts() function starts and enables Docker services.
sudo systemctl start docker
sudo systemctl enable docker
sudo chown $USER /var/run/docker.sock
This ensures Docker starts automatically after a reboot and can be accessed without permission issues.
Step 4: Create Docker Network
Before deploying containers, a dedicated Docker network named twotier is created.
docker network create twotier
This network allows communication between the Flask and MySQL containers.
Step 5: Deploy MySQL Container
The deploy_mysql() function creates and runs a MySQL container.
docker run -d \
--name mysql \
-v mysql-data:/var/lib/mysql \
--network twotier \
-e MYSQL_DATABASE=mydb \
-e MYSQL_ROOT_PASSWORD=admin \
-p 3306:3306 \
mysql:5.7
Configuration
| Parameter | Value |
|---|---|
| Database | mydb |
| Username | root |
| Password | admin |
| Port | 3306 |
The Docker volume ensures that database data persists even if the container is recreated.
Step 6: Build Flask Docker Image
The Flask application image is built using the Dockerfile available in the repository.
docker build -t flaskapp .
This creates a reusable Docker image named flaskapp.
Step 7: Deploy Flask Container
The Flask container is launched and connected to the MySQL container through the Docker network.
docker run -d \
--name flaskapp \
--network twotier \
-e MYSQL_HOST=mysql \
-e MYSQL_USER=root \
-e MYSQL_PASSWORD=admin \
-e MYSQL_DB=mydb \
-p 5000:5000 \
flaskapp:latest
The Flask application uses these environment variables to connect to the MySQL database.
Step 8: Verify Deployment
The deployment status is checked using:
docker ps
Expected output:
CONTAINER ID IMAGE NAME
xxxxxxxxxx mysql:5.7 mysql
xxxxxxxxxx flaskapp flaskapp
Access the Application
Open your browser and navigate to:
http://<EC2-PUBLIC-IP>:5000
Make sure the EC2 Security Group allows:
Port 22 (SSH)
Port 5000 (Flask Application)
Conclusion
This project demonstrates how Shell Scripting can automate the deployment of a Dockerized Flask and MySQL two-tier application on AWS EC2. The automation reduces manual effort, improves consistency, and follows modern DevOps deployment practices.
By integrating GitHub, Docker, AWS EC2, and Bash scripting, we can achieve a reliable and repeatable deployment process suitable for real-world applications.
This version is ready to paste into Hashnode with both the explanation and the actual script embedded in the article.




