Skip to main content
Redhat Developers  Logo
  • AI

    Get started with AI

    • Red Hat AI
      Accelerate the development and deployment of enterprise AI solutions.
    • AI learning hub
      Explore learning materials and tools, organized by task.
    • AI interactive demos
      Click through scenarios with Red Hat AI, including training LLMs and more.
    • AI/ML learning paths
      Expand your OpenShift AI knowledge using these learning resources.
    • AI quickstarts
      Focused AI use cases designed for fast deployment on Red Hat AI platforms.
    • No-cost AI training
      Foundational Red Hat AI training.

    Featured resources

    • OpenShift AI learning
    • Open source AI for developers
    • AI product application development
    • Open source-powered AI/ML for hybrid cloud
    • AI and Node.js cheat sheet

    Red Hat AI Factory with NVIDIA

    • Red Hat AI Factory with NVIDIA is a co-engineered, enterprise-grade AI solution for building, deploying, and managing AI at scale across hybrid cloud environments.
    • Explore the solution
  • Learn

    Self-guided

    • Documentation
      Find answers, get step-by-step guidance, and learn how to use Red Hat products.
    • Learning paths
      Explore curated walkthroughs for common development tasks.
    • Guided learning
      Receive custom learning paths powered by our AI assistant.
    • See all learning

    Hands-on

    • Developer Sandbox
      Spin up Red Hat's products and technologies without setup or configuration.
    • Interactive labs
      Learn by doing in these hands-on, browser-based experiences.
    • Interactive demos
      Click through product features in these guided tours.

    Browse by topic

    • AI/ML
    • Automation
    • Java
    • Kubernetes
    • Linux
    • See all topics

    Training & certifications

    • Courses and exams
    • Certifications
    • Skills assessments
    • Red Hat Academy
    • Learning subscription
    • Explore training
  • Build

    Get started

    • Red Hat build of Podman Desktop
      A downloadable, local development hub to experiment with our products and builds.
    • Developer Sandbox
      Spin up Red Hat's products and technologies without setup or configuration.

    Download products

    • Access product downloads to start building and testing right away.
    • Red Hat Enterprise Linux
    • Red Hat AI
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Featured

    • Red Hat build of OpenJDK
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat Developer Toolset

    References

    • E-books
    • Documentation
    • Cheat sheets
    • Architecture center
  • Community

    Get involved

    • Events
    • Live AI events
    • Red Hat Summit
    • Red Hat Accelerators
    • Community discussions

    Follow along

    • Articles & blogs
    • Developer newsletter
    • Videos
    • Github

    Get help

    • Customer service
    • Customer support
    • Regional contacts
    • Find a partner

    Join the Red Hat Developer program

    • Download Red Hat products and project builds, access support documentation, learning content, and more.
    • Explore the benefits

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

    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

    • 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

    • Debugging image mode with Red Hat OpenShift 4.20: A practical guide

    • EvalHub: Because "looks good to me" isn't a benchmark

    • SQL Server HA on RHEL: Meet Pacemaker HA Agent v2 (tech preview)

    • Deploy with confidence: Continuous integration and continuous delivery for agentic AI

    • Every layer counts: Defense in depth for AI agents with Red Hat AI

    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Platforms

    • Red Hat AI
    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

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

    Red Hat legal and privacy links

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

    Chat Support

    Please log in with your Red Hat account to access chat support.