Good news! Python 3.12 has recently been released and Fedora 39 ships it in the system. We don’t have to replace existing Python installation in our operating system, but we could use the container to run the latest Python release for testing or other purposes.

Since Python 3.9 and Fedora 33, Python’s annual release cycle was adapted for Fedora. It’s now common that Python is upgraded on a similar schedule in every odd-numbered Fedora release and it benefits us to build Python 3.12 container image from the Fedora 39 base image.

Download the latest Fedora-Container-Base-39 package from Koji build system.

~$ wget -O fedora-rootfs.tar.xz https://kojipkgs.fedoraproject.org//packages/Fedora-Container-Base/39/20231116.0/images/Fedora-Container-Base-39-20231116.0.x86_64.tar.xz
~$ tar -tf fedora-rootfs.tar.xz 
12925a914e4fc1e0afe772a695133c8a9b9ab22c9bb1d50291f217aa091df8ac/
12925a914e4fc1e0afe772a695133c8a9b9ab22c9bb1d50291f217aa091df8ac/VERSION
12925a914e4fc1e0afe772a695133c8a9b9ab22c9bb1d50291f217aa091df8ac/json
12925a914e4fc1e0afe772a695133c8a9b9ab22c9bb1d50291f217aa091df8ac/layer.tar
repositories
cdb69bcbc4cabd55d807cec5be5f74755b2925233efc282d672d721533b89fd6.json
manifest.json

The tarbal contains the root file system (rootfs) with the file name layer.tar. The rootfs needs to be extracted from the downloaded archive.

~$ tar -xJvf fedora-rootfs.tar.xz 12925a914e4fc1e0afe772a695133c8a9b9ab22c9bb1d50291f217aa091df8ac/layer.tar
~$ mv 12925a914e4fc1e0afe772a695133c8a9b9ab22c9bb1d50291f217aa091df8ac/layer.tar rootfs.tar 

Once a rootfs is available, to build a base image requires only a Dockerfile file with the following instructions:

# Dockerfile
FROM scratch
ADD rootfs.tar /

The FROM scratch instruction is the instruction for creating an empty image and then add the rootfs to the image. The next instruction then run a command to install the pip package from Fedora.

# Dockerfile
...
RUN dnf install -y python3-pip && dnf clean all

At this point, we already have the pip package manager ready to install the packages required by the application. For example, I want to run the Flask application and the following packages are included in the requirements.txt file.

~$ nano requirements.txt
Flask
Flask_Login
Flask_SQLAlchemy
Flask_WTF 

You may customize the pip requirements in the requirements.txt file according to your needs.

Create a /app directory inside the container and make it as WORKDIR. Copy the requirements.txt and install the Python packages with the command pip install.

# Dockerfile
...
RUN mkdir /app
WORKDIR /app
COPY requirements.txt /app
RUN pip3 install --no-cache-dir -r requirements.txt

Last step, we will use port 5000 and use Python as ENTRYPOINT:

# Dockerfile
...
EXPOSE 5000
ENTRYPOINT ["/usr/bin/python3"]

Below are complete instructions in the Dockerfile file that may be modified to suit your needs:

# Dockerfile
FROM scratch
ADD rootfs.tar /
RUN dnf install -y python3-pip && dnf clean all
RUN mkdir /app
WORKDIR /app
COPY requirements.txt /app
RUN pip3 install --no-cache-dir -r requirements.txt
EXPOSE 5000
ENTRYPOINT ["/usr/bin/python3"]

Let’s build the container image and run it:

~$ docker build -t py312 .
~$ docker run -it --rm py312
Python 3.12.0 (main, Oct  2 2023, 00:00:00) [GCC 13.2.1 20230918 (Red Hat 13.2.1-3)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

Last but not least, we create a simple Flask application and run it in the container:

~$ nano app/flaskapp.py
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
    return "<h1>Welcome to Flask Application!</h1>"
if __name__ == "__main__":
    app.run(host='0.0.0.0')

You can pull Pull the ready-to-use image hananmyid/py312 from Docker Hub.

Leave a comment

Leave a Reply