Introduction
Microservices vs a Monolithic Approach
Designing & Building Microservices
Deploying Microservices
The course is part of this learning path
Interested in microservices, and how they can be used for increased agility and scalability?
Microservices is an architectural style and pattern that structures an application as a collection of coherent services. Each service is highly maintainable, testable, loosely coupled, independently deployable, and precisely focused.
This course takes a hands-on look at microservices using Python, Flask, and Docker. You'll learn how Flask can be used to quickly prototype and build microservices, as well as how to use Docker to host and deploy them.
We start by looking at various problems associated with monolithic architectures and how microservices address them. We then move on to designing and building a basic shopping cart system, focusing on each of the microservices that make up the overall system.
If you have any feedback relating to this course, feel free to get in touch with us at support@cloudacademy.com.
Learning Objectives
- Obtain a solid understanding of microservices: the benefits, the challenges, and how using microservices differs from a monolithic approach
- Learn how to design and build microservices using Python and Flask
- Learn how to deploy microservices using Docker
Intended Audience
This course is intended for anyone who wants to build and deploy microservices using Python, Flask, and Docker.
Prerequisites
Python 3.x programming experience is required to get the most out of this course. If you want to follow along with this course, you'll need Python 3.7, an IDE (PyCharm Community Edition - free), and Docker (Docker Desktop).
Resources
The complete source code for the project demonstrated within the course is located here:
The repository contains the following 4 projects:
- user-service
- product-service
- order-service
- frontend
In the last chapter, we are going to deploy our microservices using docker-compose. Docker Compose simplifies multi-container Docker environments on a single host.
Remember that every microservice should have its own database instance to avoid any external dependency and isolate the service to run on its own. For this, we use docker compose, a multi-container environment that will run an accompanying MySQL container.
Before configuring docker-compose, add the production configuration in config.py Set ENV to production, DEBUG to false, and set SQLALCHEMY URI to point to MySQL docker container. Set SQLALCHEMY ECHO to false In .env file replace CONFIGURATION_SETUP value with “config.ProductionConfig” In docker-compose file define a volume for MYSQL database persistence. Use the already created docker network micro_network.
Our first docker service is the user-api. Give that container a new name to avoid the conflict with previously created containers via Docker CLI, add an alphabet ‘c’ at the start as they are created via docker-compose. Specify the build context which is a current directory where Dockerfile is located.
Specify the Host mapping to the docker port on which application is available. Now add the database service as dependency. Docker compose starts the services in dependency order and makes sure the database is up before the API.
Specify the docker network to use and set the restart key to always restart the container if down. Now time to specify the database service in the docker-compose file. Specify the container name. Specify the MySQL image to be downloaded from the docker hub. Now specify environment variables used to set up MySQL database including Root password, Database to create, User, and the password to access the database.
Specify the network being used by the user database container. In the end, specify the docker volume to the MySQL data directory being used. Docker volumes use the Host storage to persist the container storage. Now build and run the containers with docker-compose command.
After the containers are up, do run ‘flask db upgrade’ to create the database tables. This is a one-time step so I prefer to run it manually. You can now test the user-service functionality with POSTMAN. Like with user-service, update the production configuration for product-service and update the .env file.
Write down the docker-compose.yml. As the steps are almost identical like the previous docker-compose file, we speed run through that file.
After completing the file, build the docker and start in detach mode. Now run the ‘flask db upgrade’ command to create the database tables. Like previous services, update the config.py file and add the configuration for production and update .env file. We simply speed run through it. Also update the User API url in UserClient.py file with ‘cuser-service’.
Now again write the docker-compose.yml file like previous steps, as we speed run through the step. After building and starting the containers don’t forget to run the ‘flask db upgrade’ command. Now it's time to update the frontend config.py and update the .env file. As we are calling all three of the services from the frontend, update the API Client one by one and update the container names in the URLs being used. This time we are creating one service. Let’s speed run through it.
Now build and start the container. We can also specify a single docker-compose file for production and append all the docker-compose services. This is useful in scenarios where we want different environments like dev, staging, production from a single file or perform admin tasks against compose applications.
In docker-compose.deploy, we'll define a volume for our database like so, and we'll use the network micro_network. Now, our first Docker service is the user_api, so we'll give that container a new name. So I'll add the letter "c" at the beginning, as it's created by docker-compose, I'll specify the build context, I'll specify the host mapping to the docker portal on which the application is available, and we'll add the database service's dependency.
Now we'll specify the Docker network to use and set the restart key to always restart the container if down.
Now it's time to specify the database service in the docker-compose.deploy file. So we'll specify the name there, we'll specify the MySQL image to be downloaded from the Docker hub, and now we'll specify the environment variables. So we've got the route password there, the database to create, the user, and we'll put in the password to access the database.
And now we'll specify the network being used by the user database container. At the end, we'll specify the Docker volume to the MySQL directory being used.
The next service is product-api. So we'll give it a name. Like before we'll put "c" at the beginning. We'll specify the build context and we'll specify the host mapping as well like before. Now we'll add the database service as a dependency, specify the network, and set the restart key to always restart the container if down. And now we specify the database service, we specify the container name, we specify the MySQL image to be downloaded from the Docker hub, and then we specify again the environment variables to use.
So we have the root password, the database that we want to create, the user, and then the password to access the database.
Now we'll specify the network here and at the end, we specify the docker volume for the MySQL data directory being used. We then do the same thing as before, but for the order-api, so we add the container name as before. Again, we put the letter "c" in front. We specify the build context, we specify the host mapping to the docker port on which the application is available. We add the database service as the dependency, add the network, and we set the restart as well. The restart key there.
Then we specify the database service. So we add the container name, MySQL image, then we do the environment variables as before. So the root password, database, the user, and finally, the password to access the database. Once again, we specify the network being used and were specify the docker volume.
Then for the front-end app, we'll give the container a new name. Again, we put "c" at the front, like we did with the service before. We specify the build context, we specify the host mapping, and the restart key there at the end.
Then we use docker-compose -f docker compose.deploy.yml build
and docker-compose -f docker-compose.deploy.yml up -d.
You don’t need to run ‘flask db upgrade’ as we have run those commands previously and we are using the docker volumes.
Here is the Assignment for students. As we have the is_admin column in the User model in user-service, we can introduce admin users. Add an admin user who can create new products and upload their images. As a result, those products will be displayed by the product-service.
Saqib is a member of the content creation team at Cloud Academy. He has over 15 years of experience in IT as a Programmer, with experience in Linux and AWS admin. He's also had DevOps engineer experience in various startups and in the telecommunications sector. He loves developing Unity3D games and participating in Game Jams.