29.12.2020

Run Flask App Mac

Run Flask App Mac Rating: 8,5/10 924 votes

In this post, we'll first take a look at Kubernetes and container orchestration in general and then we'll walk through a step-by-step tutorial that details how to deploy a Flask-based microservice (along with Postgres and Vue.js) to a Kubernetes cluster.

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. App.py — This contains Flask APIs that receives sales details through GUI or API calls, computes the predicted value based on our model and returns it. Request.py — This uses requests module to call APIs defined in app.py and displays the returned value.

This is an intermediate-level tutorial. It assumes that you have basic working knowledge of Flask and Docker.Review the Test-Driven Development with Python, Flask, and Docker course for more info on these tools.

Dependencies:

  • Kubernetes v1.17.1
  • Minikube v1.6.2
  • Docker v19.03.5
  • Docker-Compose v1.24.1

Contents

Objectives

By the end of this tutorial, you will be able to:

  1. Explain what container orchestration is and why you may need to use an orchestration tool
  2. Discuss the pros and cons of using Kubernetes over other orchestration tools like Docker Swarm and Elastic Container Service (ECS)
  3. Explain the following Kubernetes primitives: Node, Pod, Service, Label, Deployment, Ingress, and Volume
  4. Spin up a Python-based microservice locally with Docker Compose
  5. Configure a Kubernetes cluster to run locally with Minikube
  6. Set up a volume to hold Postgres data within a Kubernetes cluster
  7. Use Kubernetes Secrets to manage sensitive information
  8. Run Flask, Gunicorn, Postgres, and Vue on Kubernetes
  9. Expose Flask and Vue to external users via an Ingress

What is Container Orchestration?

As you move from deploying containers on a single machine to deploying them across a number of machines, you'll need an orchestration tool to manage (and automate) the arrangement, coordination, and availability of the containers across the entire system.

Orchestration tools help with:

  1. Cross-server container communication
  2. Horizontal scaling
  3. Service discovery
  4. Load balancing
  5. Security/TLS
  6. Zero-downtime deploys
  7. Rollbacks
  8. Logging
  9. Monitoring

This is where Kubernetes fits in along with a number of other orchestration tools -- like Docker Swarm, ECS, Mesos, and Nomad.

Which one should you use?

  • use Kubernetes if you need to manage large, complex clusters
  • use Docker Swarm if you are just getting started and/or need to manage small to medium-sized clusters
  • use ECS if you're already using a number of AWS services
ToolProsCons
Kuberneteslarge community, flexible, most features, hipcomplex setup, high learning curve, hip
Docker Swarmeasy to set up, perfect for smaller clusterslimited by the Docker API
ECSfully-managed service, integrated with AWSvendor lock-in

There's also a number of managed Kubernetes services on the market:

  1. Google Kubernetes Engine (GKE)
  2. Elastic Kubernetes Service (EKS)
  3. Azure Kubernetes Service (AKS)

For more, review the Choosing the Right Containerization and Cluster Management Tool blog post.

Kubernetes Concepts

Before diving in, let's look at some of the basic building blocks that you have to work with from the Kubernetes API:

  1. A Node is a worker machine provisioned to run Kubernetes. Each Node is managed by the Kubernetes master.
  2. A Pod is a logical, tightly-coupled group of application containers that run on a Node. Containers in a Pod are deployed together and share resources (like data volumes and network addresses). Multiple Pods can run on a single Node.
  3. A Service is a logical set of Pods that perform a similar function. It enables load balancing and service discovery. It's an abstraction layer over the Pods; Pods are meant to be ephemeral while services are much more persistent.
  4. Deployments are used to describe the desired state of Kubernetes. They dictate how Pods are created, deployed, and replicated.
  5. Labels are key/value pairs that are attached to resources (like Pods) which are used to organize related resources. You can think of them like CSS selectors. For example:
    • Environment - dev, test, prod
    • App version - beta, 1.2.1
    • Type - client, server, db
  6. Ingress is a set of routing rules used to control the external access to Services based on the request host or path.
  7. Volumes are used to persist data beyond the life of a container. They are especially important for stateful applications like Redis and Postgres.
    • A PersistentVolume defines a storage volume independent of the normal Pod-lifecycle. It's managed outside of the particular Pod that it resides in.
    • A PersistentVolumeClaim is a request to use the PersistentVolume by a user.

For more, review the Learn Kubernetes Basics tutorial as well as the Kubernetes Concepts slides from the Scaling Flask with Kubernetes talk.

Project Setup

Clone down the flask-vue-kubernetes repo, and then build the images and spin up the containers:

Create and seed the database books table:

Test out the following server-side endpoints in your browser of choice.

container_id is the id of the Docker container the app is running in.

http://localhost:5001/books:

Navigate to http://localhost:8080. Make sure the basic CRUD functionality works as expected:

Take a quick look at the code before moving on:

Want to learn how to build this project? Check out the Developing a Single Page App with Flask and Vue.js blog post.

Minikube

Minikube is a tool which allows developers to use and run a Kubernetes cluster locally. It's a great way to quickly get a cluster up and running so you can start interacting with the Kubernetes API.

Follow the official quickstart guide to get Minikube installed along with:

  1. A Hypervisor (like VirtualBox or HyperKit) to manage virtual machines
  2. Kubectl to deploy and manage apps on Kubernetes

If you’re on a Mac, we recommend installing Kubectl and Minikube with Homebrew:

Then, start the cluster and pull up the Minikube dashboard:

It's worth noting that the config files will be located in the ~/.kube directory while all the virtual machine bits will be in the ~/.minikube directory.

Now we can start creating objects via the Kubernetes API.

If you run into problems with Minikube, it's often best to remove it completely and start over.

For example:

Creating Objects

To create a new object in Kubernetes, you must provide a 'spec' that describes its desired state.

Example:

Required Fields:

  1. apiVersion - Kubernetes API version
  2. kind - the type of object you want to create
  3. metadata - info about the object so that it can be uniquely identified
  4. spec - desired state of the object

In the above example, this spec will create a new Deployment for a Flask app with a single replica (Pod). Take note of the containers section. Here, we specified the Docker image along with the container port the application will run on.

In order to run our app, we'll need to set up the following objects:

Volume

Again, since containers are ephemeral, we need to configure a volume, via a PersistentVolume and a PersistentVolumeClaim, to store the Postgres data outside of the Pod.

Take note of the YAML file in kubernetes/persistent-volume.yml:

This configuration will create a hostPath PersistentVolume at '/data/postgres-pv' within the Node. The size of the volume is 2 gibibytes with an access mode of ReadWriteOnce, which means that the volume can be mounted as read-write by a single node.

It's worth noting that Kubernetes only supports using a hostPath on a single-node cluster.

Create the volume:

View details:

You should see:

You should also see this object in the dashboard:

kubernetes/persistent-volume-claim.yml:

Create the volume claim:

View details:

Secrets

Secrets are used to handle sensitive info such as passwords, API tokens, and SSH keys. We'll set up a Secret to store our Postgres database credentials.

kubernetes/secret.yml:

The user and password fields are base64 encoded strings (security via obscurity):

Keep in mind that any user with access to the cluster will be able to read the values in plaintext. Take a look at Vault if you want to encrypt secrets in transit and at rest.

Add the Secrets object:

Postgres

With the volume and database credentials set up in the cluster, we can now configure the Postgres database itself.

kubernetes/postgres-deployment.yml:

What's happening here?

  1. metadata
    • The name field defines the Deployment name - postgres
    • labels define the labels for the Deployment - name: database
  2. spec
    • replicas define the number of Pods to run - 1
    • selector defines how the Deployment finds which Pods to manage
    • template
      • metadata
        • labels indicate which labels should be assigned to the Pod - service: postgres
      • spec
        • containers define the containers associated with each Pod
        • volumes define the volume claim - postgres-volume-mount
        • restartPolicy defines the restart policy - Always

Further, the Pod name is postgres and the image is postgres:12.1-alpine, which will be pulled from Docker Hub. The database credentials, from the Secret object, are passed in as well.

Finally, when applied, the volume claim will be mounted into the Pod. The claim is mounted to '/var/lib/postgresql/data' - the default location - while the data will be stored in the PersistentVolume, '/data/postgres-pv'.

Create the Deployment:

Status:

kubernetes/postgres-service.yml:

What's happening here?

  1. metadata
    • The name field defines the Service name - postgres
    • labels define the labels for the Service - name: database
  2. spec
    • selector defines the Pod label and value that the Service applies to - service: postgres
    • type defines the type of Service - ClusterIP
    • ports
      • port defines the port exposed to the cluster

Take a moment to go back to the Deployment spec. How does the selector in the Service relate back to the Deployment?

Since the Service type is ClusterIP, it's not exposed externally, so it's only accessible from within the cluster by other objects.

Create the service:

Create the books database, using the Pod name:

Verify the creation:

You can also get the Pod name via:

Assign the value to a variable and then create the database:

Flask

Take a moment to review the Flask project structure along with the dockerfile and the entrypoint.sh files:

  1. 'services/server'
  2. services/server/dockerfile
  3. services/server/entrypoint.sh

kubernetes/flask-deployment.yml:

This should look similar to the Postgres Deployment spec. The big difference is that you can either use my pre-built and pre-pushed image on Docker Hub, mjhea0/flask-kubernetes, or build and push your own.

For example:

Flask App Example

If you use your own, make sure you replace mjhea0 with your Docker Hub name in kubernetes/flask-deployment.yml as well.

Alternatively, if don't want to push the image to a Docker registry, after you build the image locally, you can set the image-pull-policy flag to Never to always use the local image.

Create the Deployment:

This will immediately spin up a new Pod:

kubernetes/flask-service.yml:

Curious about the targetPort and how it relates to the port? Review the offical Services guide.

Create the service:

Make sure the Pod is associated with the Service:

Apply the migrations and seed the database:

Verify:

Ingress

To enable traffic to access the Flask API inside the cluster, you can use either a NodePort, LoadBalancer, or Ingress:

  1. A NodePort exposes a Service on an open port on the Node.
  2. As the name implies, a LoadBalancer creates an external load balancer that points to a Service in the cluster.
  3. Unlike the previous two methods, an Ingress is not a type of Service; instead, it sits on top of the Services as an entry point into the cluster.

For more, review the official Publishing Services guide.

kubernetes/minikube-ingress.yml:

Here, we defined the following HTTP rules:

  1. / - routes requests to the Vue Service (which we still need to set up)
  2. /books - routes requests to the Flask Service

Enable the Ingress addon:

Create the Ingress object:

Next, you need to update your /etc/hosts file to route requests from the host we defined, hello.world, to the Minikube instance.

Add an entry to /etc/hosts:

Try it out:

http://hello.world/books/ping

http://hello.world/books

Vue

Moving right along, review the Vue project along with the associated Dockerfiles:

  1. 'services/client'
  2. /services/client/Dockerfile
  3. /services/client/Dockerfile-minikube

kubernetes/vue-deployment.yml:

Again, either use my image or build and push your own image to Docker Hub:

Create the Deployment:

Verify that a Pod was created along with the Deployment:

How would you verify that the Pod and Deployment were created successfully in the dashboard?

kubernetes/vue-service.yml:

Create the service:

Ensure http://hello.world/ works as expected.

Scaling

Kubernetes makes it easy to scale, adding additional Pods as necessary, when the traffic load becomes too much for a single Pod to handle.

For example, let's add another Flask Pod to the cluster:

Confirm:

Make a few requests to the service:

You should see different container_ids being returned, indicating that requests are being routed appropriately via a round robin algorithm between the two replicas:

What happens if you scale down as traffic is hitting the cluster? Open two terminal windows and test this on your on. You should see traffic being re-routed appropriately. Try it again, but this time scale up.

Helpful Commands

CommandExplanation
minikube startStarts a local Kubernetes cluster
minikube ipDisplays the IP address of the cluster
minikube dashboardOpens the Kubernetes dashboard in your browser
kubectl versionDisplays the Kubectl version
kubectl cluster-infoDisplays the cluster info
kubectl get nodesLists the Nodes
kubectl get podsLists the Pods
kubectl get deploymentsLists the Deployments
kubectl get servicesLists the Services
minikube stopStops a local Kubernetes cluster
minikube deleteRemoves a local Kubernetes cluster

Check out the Kubernetes Cheatsheet for more commands.

Automation Script

Ready to put everything together?

Take a look at the deploy.sh script in the project root. This script:

  1. Creates a PersistentVolume and a PersistentVolumeClaim
  2. Adds the database credentials via Kubernetes Secrets
  3. Creates the Postgres Deployment and Service
  4. Creates the Flask Deployment and Service
  5. Enables Ingress
  6. Applies the Ingress rules
  7. Creates the Vue Deployment and Service

Try it out!

Once done, create the books database, apply the migrations, and seed the database:

Update /etc/hosts, and then test it out in the browser.

Conclusion

In this post we looked at how to run a Flask-based microservice on Kubernetes.

At this point, you should have a basic understanding of how Kubernetes works and be able to deploy a cluster with an app running on it.

Additional Resources:

  1. Running Flask on Docker Swarm (compare and contrast running Flask on Docker Swarm vs. Kubernetes)

You can find the code in the flask-vue-kubernetes repo on GitHub.

Hello Coders,

This article aims to help beginners to accommodate with Flask, the popular web framework written in Python. To follow and learn something from this tutorial there is no need to have a previous programming background, the content will be presented in the most simple way possible, enhanced at some point with visual materials.

This tutorial will be periodically updated with new topics based on the new technology trends and your suggestions. Thank for reading!.

Topics

  • What is Python
  • What is Flask
  • What is a web framework
  • A curated list with Flask resources
  • A short-list with Flask Starters
  • Install Flask
  • How to install dependencies
  • Useful Flask modules
  • Build a real Flask Application
  • Deployment with Heroku and Docker

Python is an interpreted programming language (no compilation phase as for C/C++ programs) with high-level built-in data structures quite attractive for Rapid Application Development. The Python interpreter along with the standard libraries are available in source or binary form all major platforms (Linux, Windows or Mac).

To execute a Python program we need to have the Python interpreter available in the terminal. The first step is to access the official download page, download the installer for our operating system (Mac, Linux, M$ Windows) and execute it. If the installation goes well we should be able to access the interpreter from the terminal window (Powershell for windows, Xterm for Linux ...).

Please install the Python 3.x version, Python 2.x is deprecated and no longer supported by the Python foundation.

Flask is a Python web framework built with a small core and modularity in mind. It is classified as a microframework because it does not require particular tools or libraries. It has no database abstraction layer, form validation, or any other components, and all those super necessary features are provided by third-party libraries developed by the team behind Flask or other developers from the community.

What is a Web Framework

The best definition I've found is this: Web framework is a set of components and libraries designed to simplify your web development process. - Source HackerNoon.
Indeed, the goal of a Web Framework is to make our life easier and provide help regarding the repetitive configuration and modules required by multiple projects. Flask does this flawlessly.

Flask Resources

A short and curated list. Feel free to suggest more in the comments.

  • Flask - the official website
  • Flask Docs - the official version
  • Flask - Github repository
  • Flask - a super popular tutorial on Full-Stack Python
  • Flask Tutorials - supported by RealPython
  • Flask Mega Tutorial by Miguel Grinberg

Flask Starters

This section contains a few open-source UI-Ready starters already coded with a basic set of modules, helpers and deployment scrips.

  • Flask Dashboard Black - Free admin panel - LIVE Demo
  • Flask Dashboard Argon - MIT License - LIVE Demo
  • Flask Dashboard Datta Able - LIVE Demo
  • Flask Dashboard StarAdmin - LIVE Demo
  • Flask Atlantis Dark - design by ThemeKita - LIVE Demo

For more open-source admin dashboards please access the AppSeed platform. The source code is published under the MIT license on Github (no account required to use the code).

Install Flask

The most easier way to install Flask is to use PIP (python package manager), which comes with Python3 binary distribution.

To check the installation, we can open the python CLI and import flask. If the module is properly installed, we should see no errors after import.

How to install dependencies

Each project has a list of dependencies usually saved in requirements.txt file, located in the root of the project. This is a common practice visible in many opensource projects and adopted by many developers (me included). We can install the modules in two ways:

  • globally, as we did in the previous section
  • using a Virtual Environment - the recommended way. Using a Virtual Environment (aka VENV) the modules will be installed isolated in the workstation, usually called a sandboxed environment.

A simple use case to visualize the benefit of a VENV.

Imagine that we have two apps that use different versions of Flask. If The dependencies are installed globally, the dependencies will affect the set up for the other app. To avoid this use case, a virtual environment helps the developer to execute the app using an isolated environment, and both apps are usable in the same time, without dependencies errors.

Create a VENV Unix based systems

Create a VENV for Windows OS

Once the VENV is created and activated, we can install the project requirements using PIP:

Useful Flask modules

Flask uses third party libraries (or modules) to provide common features used in many projects. I will drop here a short-list with popular modules. Feel free to suggest more in comments, if I missed some.

  • Flask-Login - create a user management flow and it takes care of the scary parts of authentication such as session management and dealing with cookies.
  • Flask-Mail - Sending an email is important for a lot of application types, especially if you’re dealing with users.
  • Flask-WTF - this module makes the forms processing a breeze.
  • Flask-SQLAlchemy - The abstract object-oriented interface to many databases (MySql, SQLite, PostgreSQL).
  • Alembic - this module is super useful when we have a database in production and we need to update the DB Schema with new tables o mutate things on existing tables. In all this cases, Alembic will assist us to migrate the old structure to the new one bu generating the necessary SQL and scripts.

Built a real Flask product

Flask Dashboard Black, the app we will use as a sample to see something nice on the screen, is an open-source product coded in Flask on top of a beautiful UI Kit provided by Creative-Tim agency.

The source is available on Github and anyone can download the code and use it for hobby or commercial projects. In case you have issues using it, AMA in the comments.

App Links

  • Flask Dashboard Black the source code published on Github
  • Flask Dashboard Black - LIVE Demo

The build instructions (saved also in the README file) are listed below:

If all goes well, we should see the dashboard, up & running in the browser. Please note that the app redirects the guest users to the login screen. Please create a new user using the registration page and authenticate into the app. By default, the app uses SQLite to save login information, but we can switch to other databases like MySql or PostgresSQL with ease. Promise to document this in a separate article.

Flask Dashboard - User Profile Page

Flask Dashboard - User Registration Page

As mentioned, the app is released under the MIT license. Feel free to grab the code and add more features on top. A short-list with suggestions:

  • Add another field in the user table - Adress
  • Update the registration form to let users add the new information
  • Display the new Adress field in the profile page

The deployment

Coding an app in our environment is nice, but release it into the wild in the internet is super rewarding, especially if is the first project. To deploy LIVE a Flask app, we have many options that depend on the server and the platform we are using.

Run Flask Application In Production

Deploy on Heroku

The most simple way IMO is to use the Heroku platform. Of course, we need an account on the platform, and also the Heroku CLI installed in our environment. Please find below the steps to deploy the Flask Dashboard Black on Heroku:

If all goes well, the app should be up & running. The database is automatically created and we just need to register a new user and log in.

Docker

Flask App Python

This is not so user-friendly deployment method, but the app that we've mentioned as a sample comes with the necessary scripts to deploy the app instantly using Docker.

In case you want to fully understand the whole process behind the Docker deployment, feel free to access an article, entirely dedicated to this topic: Flask Dashboard - Execution with Docker. The basic steps are:

Get the code from Github, using Git

Start the app in Docker

Visit http://localhost:5005 in your browser. The app should be up & running.

The deployment is not an easy topic to be digested by a beginner, and I prefer to provide a sample 100% configured and hide the real complexity covered by some nice scripts. To explain the deployment options, we need a full article that presents the possible and recommended architectures.

For a particular deploy configuration, feel free to AMA in the comments. I'll be glad to help and provide an extra opinion.

Thanks for reading! Yours, with much respect!