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

Build your first Python application in a Linux container

August 26, 2021
Don Schenck
Related topics:
ContainersLinuxKubernetesPython
Related products:
Red Hat OpenShiftRed Hat Enterprise Linux

Share:

    Setting up your Python 3.9 development environment in a Linux container is quick and easy. This article shows you how to install Python 3.9, set up your environment, and use it to create and run a Python web service on Red Hat Enterprise Linux (RHEL) 8. The whole process should take about 15 minutes.

    The amazing thing about building and using a Linux container with Python is that you don't actually need Python on your machine to do it. Creating a Python containerized application on a machine without Python support might not be ideal, but it is possible.

    Step 1: Install Python 3.9 on RHEL 8

    Use the following commands to install Python 3.9 on your RHEL 8 machine:

    
    sudo yum module install python39/build
    
    

    Now you can start using Python via the python3.9 command, as shown in Figure 1.

    Results of running the Python version command.
    Figure 1: Start using Python 3.9 in your local environment.

    Notice that we installed a module, the yum module. Modules were introduced with RHEL 8 as part of the new Application Streams concept. A module is a streamlined way to get all the components you would typically need for a particular deployment. For example, the Python3.9 module includes development tools like numby, pip, setuptools, scipy, and many more. You can see a complete list by running the yum module info python39 command.

    Step 2: Don't install Docker (you don't need to)

    That's right, there's no need to install Docker on RHEL 8 because Podman is included automatically. Podman is the open source alternative to Docker that does not run as root, which improves security. You can run podman --version to verify that it exists.

    You can use the Docker "Hello World" example to see a containerized application running on your local system. Enter the following command to see it run:

    podman run hello-world

    You'll see output like the screenshot in Figure 2.

    Results of running the command 'podman run hello-world'.'
    Figure 2: The containerized application running in a local system.

    Note: If you really feel the need to run docker commands, you can always use alias docker='podman'. Also, every podman instance in this article can be replaced with docker; they're command-for-command compatible.

    Step 3: Create a Python web service

    Now it's time to create a simple Python HTTP server that will act as our very basic web service. It will run on port 8000 and return a "Hello world"-type message.

    There are three parts to this service:

    1. The HTML file that will be served.
    2. The Python code to run as the HTTP server.
    3. The Dockerfile build instructions to build the container image.

    Note: I'm borrowing the code for this article from my colleague Mike Guerette. See his tutorial Build your first application using Python 3.5 on RHEL 7 with containers and Red Hat Software Collections if you need instructions for building a Python application on RHEL 7.

    Let's get started with our Python web service.

    Set up a directory for the Python project

    First, create a directory and move into it with the following commands:

    mkdir firstpython && cd firstpython

    Create the HTML file

    Typically, a web service will return data as a JSON document, but for this demonstration, we'll be returning HTML. That means it'll display nicely in a browser.

    Create a file named index.html with the following contents:

    <html>Hello, Red Hat Developers World from Python!</html>

    This content will be returned by our web service.

    Write the Python code to run as the HTTP server

    Create a file named web.py with the following contents:

    #
    # A very simple Python HTTP server
    #
    
    import http.server
    import socketserver
    
    PORT = 8000
    
    Handler = http.server.SimpleHTTPRequestHandler
    
    httpd = socketserver.TCPServer(("", PORT), Handler)
    
    print("serving at port", PORT)
    httpd.serve_forever()

    This is a very simple HTTP server, running on port 8000. That's good enough for our demonstration.

    Step 4: Test the Python application locally

    You can test your Python application before building an image and running it in a container. Use the following command to start the web server, running at localhost:8000:

    python3.9 -u web.py

    Then, either use the curl command or open your browser to the address. You'll see results similar to the screenshot in Figure 3.

    Results of running the curl command against a Python web service.
    Figure 3: The web.py application is running.

    Step 5: Build a container image

    Now that we have the Python web service, and we've tested it, we'll build a container image for it.

    We will use a Dockerfile containing build instructions to build the container image. Create a file named Dockerfile with the following contents:

    FROM registry.access.redhat.com/ubi8/python-39
    
    EXPOSE 8000
    
    COPY . /opt/app-root/src
    
    CMD /bin/bash -c 'python3 -u web.py'

    Use the following command to build the image:

    podman build -t pythonweb .

    As the image is being built, you will see the underlying image (ubi8/python-39) being pulled from the Red Hat registry. This image will be stored on your local machine. If you use this underlying image in a future build, it will not be pulled again.

    Note: UBI is the acronym for Universal Base Images. A UBI is a Red Hat image that allows you to use RHEL in your container and make sure it runs anywhere. UBI is specifically designed for cloud-native and containerized applications.

    Finally, the commands in your Dockerfile build instructions are carried out, and the resulting image ID is displayed. Figure 4 shows the build on my machine.

    Results of running the command 'podman build'.
    Figure 4: Confirming the build is running on a local machine.

    You can see the images on your local machine by running the command podman images, as shown in Figure 5.

    Results of running the command 'podman images'.
    Figure 5: Viewing the images on a local machine.

    Step 6: Run, run, run ... run it in a container

    Now that we've built the image, we can run it in a container. Use the following command:

    podman run --detach --publish 8000:8000 --name=helloweb localhost/pythonweb

    When you enter this command, the container runtime engine runs the image in the background—that's what the --detach flag does—and returns the container ID. The --publish flag publishes the port to the host. In this case, the container's port 8000 is made available to the host (your local machine), which, in turn, is mapping it to it's own port 8000. Note that these port numbers do not need to match. Figure 6 shows an example of the command output on my machine.

    Results of running the command 'podman run'.
    Figure 6: Viewing the command output.

    Just to recap: The image ID is created when you build the image. The container ID is assigned to the container in which the image is being run. You can see the container running by entering the command podman ps. Figure 7 shows the running container.

    Results of running the command 'podman ps'.
    Figure 7: Viewing the running container.

    Results? We got 'em

    That's it, we've created a Python web service and it's running in a container. Now let's view the results. As before, open your browser or use the curl command with the address http://localhost:8000. You'll get something like the screenshot in Figure 8.

    Results of running the curl command against a web service running in a container.
    Figure 8: The Python web service running in a container.

    What's in a name?

    Did you notice the mess I've made with naming? The directory is named firstpython. The image is named pythonweb. The name I assigned to the container is helloweb.

    I did this on purpose to demonstrate that, if you really want to, you can make a colossal mess with naming. A best practice would be to have the directory name, the image name, and the container name match.

    Additionally, the name that I assigned to the image, pythonweb, was not fully qualified by me, so the system assigned it to the localhost namespace. The tag assigned, by default, is :latest. So, putting this together, the name is localhost/pythonweb:latest.

    In real life, you would use an image registry as part of your namespace, and perhaps assign a tag. For example, if I were to build this image for my own (personal) image registry—where I will later send it using the podman push command—I would use the following command to name and build it:

    podman build -t quay.io/donschenck/pythonweb:v1 .

    It is not uncommon to use only two tags for image naming: :latest and :next. When you wish to update to the next version, you build the code for the :next image, but tag it as :latest.

    "But what about rolling back?"

    You don't. You never roll back; you roll forward, always. This idea is not without controversy, but it does force you to keep your microservices small and simple, and easy to update.

    Keep all of this in mind, especially when you create your own free Kubernetes cluster in the Developer Sandbox for Red Hat OpenShift and run your Python application there.

    Tips for running your application in a container

    To stop the container from running, use the following command:

    podman stop helloweb

    You can view the logs of the container with the following command:

    podman logs helloweb

    You can restart the container if you wish—I'll let you do a web search for that command.

    Finally, you can delete the container with the following command:

    podman rm helloweb

    After you remove the container, the logs are gone, which makes sense. But the image (localhost/pythonweb) is still on your local machine. In fact, if you want to see something interesting, run the following command:

    podman inspect localhost/pythonweb

    Now see what happens if you run the podman inspect command but, instead, reference the Red Hat Universal Base Images 8 image that was pulled down during the build process.

    Where do we go from here?

    This article has been a quick introduction to creating and running a Python web service in a RHEL 8 Linux container. If you are wondering about next steps, here are a few suggestions:

    • Download your free copy of RHEL 8 and run it in a virtual machine (I'm using Windows 10 and Hyper-V).
    • Are you a Windows developer and not super skilled with Linux? No worries: Download Burr Sutter's Linux Commands Cheat Sheet.
    • Build an application on your RHEL 8 machine.
    • Create an image from the application and push it to your own image registry.
    • Get a free Kubernetes cluster and start experimenting in the Developer Sandbox for Red Hat OpenShift.
    • Join Red Hat Developer for more resources like this one.
    Last updated: September 19, 2023

    Related Posts

    • Hello World - Python on RHEL 8

    • Why Python 4.0 won't be like Python 3.0

    • Build your first application using Python 3.5 on RHEL 7 with containers and Red Hat Software Collections

    • Build Your "Hello World" Container Using Python

    • Introducing Application Streams in RHEL 8

    Recent Posts

    • Create and enrich ServiceNow ITSM tickets with Ansible Automation Platform

    • Expand Model-as-a-Service for secure enterprise AI

    • OpenShift LACP bonding performance expectations

    • Build container images in CI/CD with Tekton and Buildpacks

    • How to deploy OpenShift AI & Service Mesh 3 on one cluster

    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
    © 2025 Red Hat

    Red Hat legal and privacy links

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

    Report a website issue