Containerizing our application is now become the habit for all the projects. As we get exposed to different technology stack, we face new challenges in implementing common solutions.
Not only for CI/CD, we containerize for other reasons as well. We often build a sizeble inventory of projects. We may not end up using them immediately. We may use them intermittently and especially when we have proof-of-concept type of projects. When the time comes to clone these projects for repository, build them and start using for our purpose, a lot of libraries and patches that we used earlier become obsolete. We need to do too much of a circus in restoring our projects back to the stage they are left at. Containerizing application relieves us from all these hurdles and time wasters - a sin in the era of lean development. Hence, it is best practice now to employ technologies like Docker in every project.
I have another unqiue technology stack combination - Python flask application, Mac OS and Postgress DB. In this article, I am going to show you how to -
- Create a Python Flask application.
- Add models to the the application using SQLAlchemy which is an ORM.
- Set up docker on your system.
- Create a docker container for the flask app.
- Create a docker container for the postgres database.
- Connect the two containers using a port mapping and network.
- Create a persistent data storage for the application using docker volumes.
- Migrate the models to the Postgres database on Docker volume.
The first step is to install Flask. Python comes with a package manager named pip. It uses the the official Python package repository named PyPI. Related course: Python Flask: Create Web Apps with Flask. To install a Python package, you need to open a terminal. This varies per operating system. Environment Variables From dotenv¶. Rather than setting FLASKAPP each time you open a new terminal, you can use Flask’s dotenv support to set environment variables automatically. If python-dotenv is installed, running the flask command will set environment variables defined in the files.env and.flaskenv.This can be used to avoid having to set FLASKAPP manually every time you open a new. Versions of Flask older than 0.11 used to have different ways to start the application. In short, the flask command did not exist, and neither did python -m flask. In that case you have two options: either upgrade to newer Flask versions or have a look at the Development Server docs to see the alternative method for running a server.
It is a long list so lets get started right away.
Create a Python Flask application locally.
First let us create the flask app locally and migrate it to the database. After that we will see how to do the same thing on Docker. Create the directory structure as below.
Leave the venv folder for now as this will be automatically created when we create the virtual environment which is the next step. Open the folder in the terminal.
Create the virtual environment.
Here venv is the name of the virtual environment. I am assuming here that you know about the virtual environment as this article is focussed more on deploying the application on Docker. If you want a refresher on that, here is a link.
Activate the virtual environment.
Install the necessary packages
Lets create a simple flask application now with just one model.
model.py
app.py
This is where we have given the path to the postgres database server running on localhost, port 5432. 'Example' is the name of the database you want to migrate your models to.
manage.py
Now that we have created the application code, lets migrate the model and run the flask application server.
We have successfully run the application on our local systems. We can see that we can reach the server at the address http://127.0.0.1:5000/ . Now we have to understand what we did here. Its very essential for serving the same app on Docker.
We are right now interacting with a single operating system. That is, the operating system installed on our own machine. You can view a single Docker container as an operating system in itself. So how can two operating systems installed on different machines talk to each other ? They need to know each other's address. For that purpose, we have the IP Address. To identify a particular application on that OS, we need to know the port it is listening to. So IP + Port Number is all that we need to talk to a application running somewhere on the network. I am telling all this because each Docker container is an OS for the application running on it. Even if the containers are created by the same Docker engine, they communicate with each other using IP and Port number only.
Something about Dockerfile, Images and Containers.
Since this article is not about Docker, I will explain the container set-up process briefly.
First we create a Dockerfile using which image is created. Now this image can be used to pop up different containers which are virtually the same but different identities in themselves. Each can be used to host an application.
This is a very vague description of the Docker stuff. Will be writing all that in another blog.
Architecture of the application.
One more thing. Containers are created and destroyed on the fly. Any thing we save in a container will be wiped off completely after it is destroyed. So we need a mechanism for storing the data permanently. Persistent storage in another words.
As you can see in the above diagram that the Docker is installed on the virtual machine on the host OS. Now this virtual machine is running the Docker engine. So in this example, we will create two containers. One for flask and the other one for Postgres. We will also create a volume for persistent data storage.
Creating the Dockerfile.
Since the Dockerfile is the recipe of creating the image, we need to pass it to Docker engine. Create a file named Dockerfile in the same folder 'Flask_docker'.
Run Flask App Mac Download
There is a slight change in the app.py file.
app.py
Creating the Flask image
Flask App Python
This will create a image by the name flask that can be used to create containers.
Pull the postgres image.
Create a Docker volume
Now that we have both the images locally on our Docker, we can start making containers out of them. But before we do that, lets create a volume.
Setting up the application
Now that we have everything ready, lets start the containers for hosting our application.
Here --net=host flag sets all the requests coming from localhost to this container. Port 5000 on localhost will be mapped to port 5000 inside the container.
This Docker command will start the container from the postgres image. It mounts the volume we created 'postgresdata' to the default location where the postgres stores the data.
At this point of time you have both the containers running. Lets list them by the command -
You have a flask application setup to use postgres database. Also the data in the database is persistent and will not be wiped off with the container. How can we be sure that they both are connected to each other ? Lets see that next.
Checking the connection between the containers.
Open two new tabs on terminal because going to work inside the container itself.
There are two things that we are going to do. First we are going to create the 'Example' database on the postgres container. Second, we are going to migrate the ORM models that we created in our flask application to this database.
Create the database.
Substitute your postgres container id above.
The database is ready but it is still not having any tables. That will be our next step. On a new terminal tab -
Now there should be a table in the 'Example' database that we just saw. Connect to that database and check the columns in the 'user' table.
Deploy Flask App
That's it for this article.