🚀Building a Two-Tier Application with Docker, MySQL, and Flask Setup.
🚀 Thrilled to share the success of a hands-on Docker project! 🐳💻 Recently, I wrapped up a hands-on experience deploying a two-tier Flask application paired with MySQL. The journey involved delving into the complexities of containerized architecture, with a special emphasis on establishing seamless communication between the front-end Flask app and the back-end MySQL database. 🛳️✨
🌠Introduction: 🌠 🚀
In this project, we will build a two-tier application using Docker for containerization, MySQL for database management, and Flask as the web framework. This setup allows for easy deployment, scalability, and efficient management of application components.
🌠Prerequisites
Before you begin, make sure you have the following installed:
Docker
Git (optional, for cloning the repository)
🌠Clone the Repository:
ubuntu@ip-172-31-39-158:~/projects$ git clone https://github.com/Trushid/two-tier-flask-app.git
Cloning into 'two-tier-flask-app'...
remote: Enumerating objects: 140, done.
remote: Counting objects: 100% (77/77), done.
remote: Compressing objects: 100% (38/38), done.
remote: Total 140 (delta 62), reused 39 (delta 39), pack-reused 63
Receiving objects: 100% (140/140), 35.15 KiB | 3.20 MiB/s, done.
Resolving deltas: 100% (69/69), done.
ubuntu@ip-172-31-39-158:~/projects$ cd two-tier-flask-app/
ubuntu@ip-172-31-39-158:~/projects/two-tier-flask-app$
🌠Docker File:
# Use an official Python runtime as the base image FROM python:3.9-slim # Set the working directory in the container WORKDIR /app # install required packages for system RUN apt-get update \ && apt-get upgrade -y \ && apt-get install -y gcc default-libmysqlclient-dev pkg-config \ && rm -rf /var/lib/apt/lists/* # Copy the requirements file into the container COPY requirements.txt . # Install app dependencies RUN pip install mysqlclient RUN pip install --no-cache-dir -r requirements.txt # Copy the rest of the application code COPY . . # Specify the command to run your application CMD ["python", "app.py"]
Build the Docker Image:
docker build -t flask-app .
🌠Setting Up MySQL Container:
Create MySQL Container:
Run the following Docker command to set up a MySQL container with specified environment variables:
Command:-
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=test@123 -e MYSQL_DATABASE=testdb -e MYSQL_USER=admin -e MYSQL_PASSWORD=admin --name mysql mysql:latest
ubuntu@ip-172-31-10-226:~/projects/two-tier-flask-app$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE flask-app latest c9619ea0fce1 12 seconds ago 389MB mysql latest a3b6608898d6 6 weeks ago 596MB python 3.9-slim 262f85ec54de 6 weeks ago 125MB ubuntu@ip-172-31-10-226:~/projects/two-tier-flask-app$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ubuntu@ip-172-31-10-226:~/projects/two-tier-flask-app$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ubuntu@ip-172-31-10-226:~/projects/two-tier-flask-app$ docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=test@123 -e MYSQL_DATABASE=testdb -e MYSQL_USER=admin -e MYSQL_PASSWORD=admin --name mysql mysql:latest 9bba086ef951fb586b9be8f487a49272298ceab95f31826d6f71b425ebd14d10 ubuntu@ip-172-31-10-226:~/projects/two-tier-flask-app$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9bba086ef951 mysql:latest "docker-entrypoint.s…" 4 seconds ago Up 3 seconds 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql
🌠Building Flask App Image and Container:
Build Flask App Image:
Build the Docker image for the Flask application:
Command:-
docker build -t flask-app .
Run Flask App Container:
Start the Flask application container, specifying the MySQL connection details:
Command:-
docker run -d -p 5000:5000 -e MYSQL_HOST=mysql -e MYSQL_USER=admin -e MYSQL_PASSWORD=admin -e MYSQL_DB=testdb --name flask-app flask-app:latest
This command runs a Docker container based on the "flask-app" image. It exposes port 5000 on the host machine, sets environment variables for MySQL connection, and names the container as "flask-app ."
ubuntu@ip-172-31-39-158:~/projects/two-tier-flask-app$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
03657e058161 mysql:latest "docker-entrypoint.s…" 43 seconds ago Up 42 seconds 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql
ubuntu@ip-172-31-39-158:~/projects/two-tier-flask-app$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
flask-app latest 4a7e95497b28 About a minute ago 389MB
mysql latest a3b6608898d6 6 weeks ago 596MB
python 3.9-slim 262f85ec54de 6 weeks ago 125MB
ubuntu@ip-172-31-39-158:~/projects/two-tier-flask-app$ docker run -d -p 5000:5000 -e MYSQL_HOST=mysql -e MYSQL_USER=admin -e MYSQL_PASSWORD=admin -e MYSQL_DB=testdb --name flask-app flask-app:latest
9d84155e601b8cd9558676d121a1edd71fa1ed192d9b4c2bdb8547e7b865b056
ubuntu@ip-172-31-39-158:~/projects/two-tier-flask-app$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9d84155e601b flask-app:latest "python app.py" 11 seconds ago Up 9 seconds 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp flask-app
03657e058161 mysql:latest "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql
ubuntu@ip-172-31-39-158:~/projects/two-tier-flask-app$
Expose Port and Access:
Allow port 5000 on AWS security inbound rule.
Access the application using the public IP address and port number.
🌠Introducing Docker Network:
Create Docker Network Bridge: see the network list
docker network ls
Establish a bridge network for communication between containers:
* Command:-
docker network create -d bridge two-tier-app-nw
ubuntu@ip-172-31-39-158:~/projects/two-tier-flask-app$ docker network ls NETWORK ID NAME DRIVER SCOPE df3faeb606dd bridge bridge local faa303557216 host host local 927d5c2d598d none null local ubuntu@ip-172-31-39-158:~/projects/two-tier-flask-app$ docker network create -d bridge two-tier-app-nw 7b29a84eb6228c85dc3f0d8a0e51775e2ffbb6b56321a1443e74e6256b3e70e0 ubuntu@ip-172-31-39-158:~/projects/two-tier-flask-app$ docker network ls NETWORK ID NAME DRIVER SCOPE df3faeb606dd bridge bridge local faa303557216 host host local 927d5c2d598d none null local 7b29a84eb622 two-tier-app-nw bridge local ubuntu@ip-172-31-39-158:~/projects/two-tier-flask-app$
*Connect MySQL Container to Network:
Attach the MySQL container to the created network:
Command:-
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=test@123 -e MYSQL_DATABASE=testdb -e MYSQL_USER=admin -e MYSQL_PASSWORD=admin --name mysql --network two-tier-app-nw mysql:latest
ubuntu@ip-172-31-39-158:~/projects/two-tier-flask-app$ docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=test@123 -e MYSQL_DATABASE=testdb -e MYSQL_USER=admin -e MYSQL_PASSWORD=admin --name mysql --network two-tier-app-nw mysql:latest 44fe2e997d8c5f0792ba58fbd46593596ea23ad36ad6df0c32d6f6012d6143c6 ubuntu@ip-172-31-39-158:~/projects/two-tier-flask-app$
*Connect Flask App Container to Network:
Join the Flask application container to the same network
Command:-
docker run -d -p 5000:5000 -e MYSQL_HOST=mysql -e MYSQL_USER=admin -e MYSQL_PASSWORD=admin -e MYSQL_DB=testdb --name flask-app --network two-tier-app-nw flask-app:latest
ubuntu@ip-172-31-39-158:~/projects/two-tier-flask-app$ docker run -d -p 5000:5000 -e MYSQL_HOST=mysql -e MYSQL_USER=admin -e MYSQL_PASSWORD=admin -e MYSQL_DB=testdb --name flask-app --network two-tier-app-nw flask-app:latest 5bffb57e2b83a48e2d1041485c271d5df41258e69bd2b1cb0e63c6890fcacba4 ubuntu@ip-172-31-39-158:~/projects/two-tier-flask-app$
🌠Inspect Network:
Verify the presence of both containers within the created network:
Command:-
docker inspect two-tier-app-nw
[ { "Name": "two-tier-app-nw", "Id": "7b29a84eb6228c85dc3f0d8a0e51775e2ffbb6b56321a1443e74e6256b3e70e0", "Created": "2023-12-07T13:46:21.978317078Z", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.18.0.0/16", "Gateway": "172.18.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "44fe2e997d8c5f0792ba58fbd46593596ea23ad36ad6df0c32d6f6012d6143c6": { "Name": "mysql", "EndpointID": "e51466de1b304b1f61eb77e1f4b6f4c7639145f47365b846ecd4535d3889fedd", "MacAddress": "02:42:ac:12:00:02", "IPv4Address": "172.18.0.2/16", "IPv6Address": "" }, "5bffb57e2b83a48e2d1041485c271d5df41258e69bd2b1cb0e63c6890fcacba4": { "Name": "flask-app", "EndpointID": "a60b3e072f7c6ffde19412c1a6b1ba3e0bc624c7786fd4e5c5e2daa46019261f", "MacAddress": "02:42:ac:12:00:03", "IPv4Address": "172.18.0.3/16", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ] ubuntu@ip-172-31-39-158:~/projects/two-tier-flask-app$
Solving MySQL Database Error:
Access MySQL Container:
Enter the MySQL container's shell to interact with the database:
Command:-
docker exec -it <mysql_container_id> bash
ubuntu@ip-172-31-39-158:~/projects/two-tier-flask-app$ mysql -u root -h 172.18.0.1 -P 3306 -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 8 Server version: 8.2.0 MySQL Community Server - GPL Copyright (c) 2000, 2023, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql>
Create the
messages
table in your MySQL database:- Create a database:
mysql> sqlCopy codeCREATE DATABASE testdb;
mysql> CREATE DATABASE testdb;
Query OK, 1 row affected (0.06 sec)
mysql>
Select the created database:
sqlCopy codeUSE testdb;
Now you can create your table:
sqlCopy codeCREATE TABLE messages (
id INT AUTO_INCREMENT PRIMARY KEY,
message TEXT
);
3. Insert data into the messages
table:
sqlCopy codeINSERT INTO messages (message) VALUES
('Hello, this is a message.'),
('Another message here.');
4Retrieve the data from the messages
table:
sqlCopy codeSELECT * FROM messages;
mysql> select * from messages;
+----+---------------------------+
| id | message |
+----+---------------------------+
| 1 | Hello, this is a message. |
| 2 | Another message here. |
+----+---------------------------+
2 rows in set (0.00 sec)
🌠🌠🌠Thrilled to share that our application deployment is a success! 🎉 After overcoming a few challenges, we've got our two-tier Flask app up and running seamlessly. A huge shoutout to ME 😁 for the hard work and dedication! 🙌
Key Achievements: ✅ MySQL Container Setup ✅ Docker Image and Container for Flask App ✅ Database and Table Creation ✅ Application Deployment Success
Conclusion: This project showcases the seamless integration of Docker, MySQL, and Flask to create a two-tier application. The use of containerization simplifies deployment and management, making it an efficient solution for modern applications. By following these steps, you can replicate and customize this setup for various projects, promoting scalability and maintainability.
Subscribe to my newsletter
Read articles from Trushid Hatmode directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Trushid Hatmode
Trushid Hatmode
As a DevOps Engineer, I'm passionate about building and maintaining robust, efficient, and scalable infrastructure to enable seamless software delivery. With a strong foundation in C/C++, Linux, and a toolkit that spans AWS, Jenkins, Docker, Nagios, Kubernetes, YAML, Ansible, Terraform, Bash Scripting, Git, and GitHub, I'm well-equipped to tackle the challenges of modern software development and deployment.