Skip to main content
Redhat Developers  Logo
  • Products

    Featured

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat OpenShift AI
      Red Hat OpenShift AI
    • Red Hat Enterprise Linux AI
      Linux icon inside of a brain
    • Image mode for Red Hat Enterprise Linux
      RHEL image mode
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • Red Hat Developer Hub
      Developer Hub
    • View All Red Hat Products
    • Linux

      • Red Hat Enterprise Linux
      • Image mode for Red Hat Enterprise Linux
      • Red Hat Universal Base Images (UBI)
    • Java runtimes & frameworks

      • JBoss Enterprise Application Platform
      • Red Hat build of OpenJDK
    • Kubernetes

      • Red Hat OpenShift
      • Microsoft Azure Red Hat OpenShift
      • Red Hat OpenShift Virtualization
      • Red Hat OpenShift Lightspeed
    • Integration & App Connectivity

      • Red Hat Build of Apache Camel
      • Red Hat Service Interconnect
      • Red Hat Connectivity Link
    • AI/ML

      • Red Hat OpenShift AI
      • Red Hat Enterprise Linux AI
    • Automation

      • Red Hat Ansible Automation Platform
      • Red Hat Ansible Lightspeed
    • Developer tools

      • Red Hat Trusted Software Supply Chain
      • Podman Desktop
      • Red Hat OpenShift Dev Spaces
    • Developer Sandbox

      Developer Sandbox
      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Secure Development & Architectures

      • Security
      • Secure coding
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
      • View All Technologies
    • Start exploring in the Developer Sandbox for free

      sandbox graphic
      Try Red Hat's products and technologies without setup or configuration.
    • Try at no cost
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • Java
      Java icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • API Catalog
    • Product Documentation
    • Legacy Documentation
    • Red Hat Learning

      Learning image
      Boost your technical skills to expert-level with the help of interactive lessons offered by various Red Hat Learning programs.
    • Explore Red Hat Learning
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

How to deploy a Flask application in Python with Gunicorn

August 17, 2023
Alex Soto Bueno
Related topics:
ContainersKubernetesPython
Related products:
Red Hat OpenShift

Share:

    Flask is a popular web framework for building web applications in Python. It is considered a microframework because it provides only the bare essentials for web development, focusing on simplicity and extensibility. 

    Flask is one of the most popular frameworks for developing REST applications in Python. Flask also has a server to do local deployments and test the application, but no one would go with it to production. So we need another server to deploy the application in production, and one option is to use a WSGI (Web Server Gateway Interface) server like Gunicorn.

    In this tutorial, you will learn how to create a Flask application, configure it to Gunicorn, and containerize it.

    The application

    Let's create a simple Hello World application using Flask as a web framework.

    You’ll need to install Python 3 and pip.

    Setup

    Create a new file with the name requirements.txt with the dependencies required for the project:

    Flask
    
    Gunicorn

    Then update the pip dependencies and install the dependencies by running the following command:

    pip3 install --upgrade pip
    
    pip3 install -r requirements.txt

    Application

    Create a new file named app.py containing the Flask REST endpoint:

    from flask import Flask
    
    app = Flask(__name__)
    
    
    
    @app.route('/')
    
    def hello_world():
    
        return 'Hello, World!'

    Running

    Let's test the application locally:

    flask --app app run

    The output will be similar to the following:

     * Serving Flask app 'app'
    
     * Debug mode: off
    
    WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
    
     * Running on http://127.0.0.1:5000
    
    Press CTRL+C to quit

    If you send a request to the defined endpoint, you'll get the predefined output:

    curl localhost:5000/
    
    Hello, World!

    So far, so good, but as the log message says, we need another way to use a WSGI server for going to production. So, let's do it.

    WSGI

    WSGI stands for Web Server Gateway Interface. It is a specification for a standardized interface between web servers and web applications or frameworks written in Python. WSGI defines a contract that allows web servers to communicate with Python web applications, enabling them to work together seamlessly.

    This separation of concerns allows web servers to focus on handling low-level networking tasks, such as accepting incoming requests and managing connections. In contrast, web applications can focus on handling the application logic and generating responses.

    You can switch between server implementations with minimal application changes. In this case, we'll use Gunicorn.

    First, we configure the Gunicorn server by creating a new file named gunicorn_config.py, where we'll configure things like the number of workers and threads and open port or timeout.

    import os
    
    
    
    workers = int(os.environ.get('GUNICORN_PROCESSES', '2'))
    
    threads = int(os.environ.get('GUNICORN_THREADS', '4'))
    
    # timeout = int(os.environ.get('GUNICORN_TIMEOUT', '120'))
    
    bind = os.environ.get('GUNICORN_BIND', '0.0.0.0:8080')
    
    
    
    forwarded_allow_ips = '*'
    
    secure_scheme_headers = { 'X-Forwarded-Proto': 'https' }

    Now, the last thing to do is start the Gunicorn server with the application deployed.

    Let's run the following command in the terminal:

    gunicorn --config gunicorn_config.py app:app

    The first app is the name of the Python file containing the Flask application.

    The output shows the application up and running in Gunicorn:

    [2023-07-17 22:55:05 +0200] [15903] [INFO] Starting gunicorn 20.1.0
    
    [2023-07-17 22:55:05 +0200] [15903] [INFO] Listening at: http://0.0.0.0:8080 (15903)
    
    [2023-07-17 22:55:05 +0200] [15903] [INFO] Using worker: gthread
    
    [2023-07-17 22:55:05 +0200] [15904] [INFO] Booting worker with pid: 15904
    
    [2023-07-17 22:55:05 +0200] [15905] [INFO] Booting worker with pid: 15905

    If you re-access the service using port 8080, you'll get the Hello World again.

    curl localhost:8080/
    
    Hello, World!

    Now, with the application up and running locally, it's time to containerize it.

    Containerization

    Generally speaking, to containerize an application, you create a Dockerfile with all the instructions and dependencies required to run the application.

    Dockerfile

    The base image contains Python, so we only copy the application files, install the requirements to run the application, and use Gunicorn to start it.

    FROM python:3.7.3-slim
    
    COPY requirements.txt /
    
    RUN pip3 install --upgrade pip
    
    RUN pip3 install -r /requirements.txt
    
    
    
    COPY . /app
    
    WORKDIR /app
    
    
    
    EXPOSE 8080
    
    
    
    CMD ["gunicorn","--config", "gunicorn_config.py", "app:app"]

    Building the container

    We are going to use Podman Desktop to build the container. With Podman (or Docker) running, let's build the container running the following command:

    podman build -t hello-flask:1.0.0 .

    The output shows the building steps executed:

    STEP 1/8: FROM python:3.7.3-slim
    
    STEP 2/8: COPY requirements.txt /
    
    --> 7721820f5f2e
    
    STEP 3/8: RUN pip3 install --upgrade pip
    
    …
    
    STEP 8/8: CMD ["gunicorn","--config", "gunicorn_config.py", "app:app"]
    
    COMMIT hello-flask:1.0.0
    
    --> 7bf50a7a7936
    
    Successfully tagged localhost/hello-flask:1.0.0
    
    7bf50a7a7936d9b87af74b7d49a94c69d217712901d78ba170acb1f28f800d51

    [ Learn more: What is Podman Desktop? A developer's introduction ]

    Running the container

    To run the container, use Podman (or Docker):

    podman run -it --rm -p 8080:8080 hello-flask:1.0.0
    [2023-07-18 07:35:29 +0000] [1] [INFO] Starting gunicorn 21.0.1
    
    [2023-07-18 07:35:29 +0000] [1] [INFO] Listening at: http://0.0.0.0:8080 (1)
    
    [2023-07-18 07:35:29 +0000] [1] [INFO] Using worker: gthread
    
    [2023-07-18 07:35:29 +0000] [4] [INFO] Booting worker with pid: 4
    
    [2023-07-18 07:35:29 +0000] [5] [INFO] Booting worker with pid: 5

    Kubernetes

    If you want to try the application in Kubernetes, use the following YAML file:

    apiVersion: apps/v1
    
    kind: Deployment
    
    metadata:
    
      labels:
    
        app: hello-service
    
      name: hello-service
    
    spec:
    
      replicas: 1
    
      selector:
    
        matchLabels:
    
          app: hello-service
    
      template:
    
        metadata:
    
          labels:
    
            app: hello-service
    
        spec:
    
          containers:
    
          - name: hello-service
    
            image: quay.io/lordofthejars/hello-flask:1.0.0 
    
            ports:
    
              - containerPort: 8080
    
    ---
    
    apiVersion: v1
    
    kind: Service
    
    metadata:
    
      name: hello-service
    
      labels:
    
        app: hello-service    
    
    spec:
    
      ports:
    
      - name: http
    
        port: 8080
    
      selector:
    
        app: hello-service
    
      type: LoadBalancer

    Use any Kubernetes cluster (minikube, kind, etc.) or a cloud Kubernetes implementation like OpenShift for free in the Developer Sandbox for Red Hat OpenShift.

    Conclusion

    Flask is one of the most popular frameworks in Python to develop web applications, but when it comes to moving to production, you need a server like Gunicorn to deploy it.

    Containerizing the application is a simple process of putting these steps into a Dockerfile and choosing the right base image.

    Last updated: September 19, 2023

    Related Posts

    • Deploy and test Kubernetes containers using Podman Desktop

    • Pipenv and S2I: A better way to manage Python dependencies in containers

    • micropipenv: Installing Python dependencies in containerized applications

    • How to create Python binding for a Rust library

    • Add custom windows to GDB: Programming the TUI in Python

    Recent Posts

    • More Essential AI tutorials for Node.js Developers

    • How to run a fraud detection AI model on RHEL CVMs

    • How we use software provenance at Red Hat

    • Alternatives to creating bootc images from scratch

    • How to update OpenStack Services on OpenShift

    What’s up next?

    Read the Red Hat Universal Base Images e-book to discover why choosing a base image is strategically important for building cloud-native apps.

    Get the e-book
    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue