Linux container build OCI compliant image hosting Django Application using Buildah

Linux container build OCI compliant image hosting Django Application using Buildah


Test Environment

Fedora 32 installed

Buildah is a opensource tool developed to build container images which are compliant with Open Container initiative (ie. OCI) image specifications. In this article we will see how we can install buildah tool. Also, we will see how it can be used to build container images.

Image can be built from existing images, from scratch and using Dockerfiles. Buildah is currently supported only for Linux distributions and it does not support Windows or Mac OS platforms at this time.

Installing Buildah on Fedora Linux

In order to Build OCI compliant Linux containers we first need to install the Buildah utility on our Linxu OS. Installing Buildah is as simple as shown below without the overhead of installing the client and server packages like we do for setting up Docker.

Buildah installation
[admin@fed32 ~]$ sudo dnf -y install buildah

Now, that we have our buildah tool installed, let see in the below step by step procedure how we can build a container image using a base fedora image.

If you are interested in watching the video. Here is the youtube video on the same.

Procedure –

Step1: Download the Fedora base image

As a first step, we will try retrieve the fedora base image using the below command. We will use this fedora base image as the initial layer on top of which we will install the required softwares to host or deploy our Django application.

Fedora base image download
[root@fed32 ~]# buildah from fedora
Getting image source signatures
Copying blob 22cef3226003 done  
Copying config e6b57c0d9f done  
Writing manifest to image destination
Storing signatures

Once we download the fedora base image using buildah it will actually download an image and along with that a working container is also created as shown below.

Fedora base image validation
[root@fed32 ~]# buildah images
REPOSITORY                          TAG      IMAGE ID       CREATED      SIZE   latest   e6b57c0d9f53   5 days ago   208 MB

[root@fed32 ~]# buildah containers
f970f6155e37     *     e6b57c0d9f53 fedora-working-container

[root@fed32 ~]# buildah run fedora-working-container /bin/bash
[root@f970f6155e37 /]# cat /etc/redhat-release 
Fedora release 32 (Thirty Two)

Step2: Install Python 3.8 and pip on the Fedora base image

Once the base image is downloaded, let try to install Python 3.8 along with pip package as shown below using the buildah run command.

Install Python 3.8 in container
[root@fed32 ~]# buildah run fedora-working-container -- dnf -y install python3.8
Fedora 32 openh264 (From Cisco) - x86_64                                                               1.0 kB/s | 2.5 kB     00:02    
Fedora Modular 32 - x86_64                                                                             228 kB/s | 4.9 MB     00:22    
Fedora Modular 32 - x86_64 - Updates                                                                   238 kB/s | 3.7 MB     00:15    
Fedora 32 - x86_64 - Updates                                                                           324 kB/s |  26 MB     01:21    
Fedora 32 - x86_64                                                                                     622 kB/s |  70 MB     01:55    
Package python3-3.8.5-5.fc32.x86_64 is already installed.
Dependencies resolved.
Nothing to do.
Install and validate pip in container
[root@fed32 ~]# buildah run fedora-working-container -- dnf -y install pip
  libxcrypt-compat-4.4.17-1.fc32.x86_64        python3-pip-19.3.1-4.fc32.noarch        python3-setuptools-41.6.0-2.fc32.noarch       


[root@f970f6155e37 /]# python3 --version
Python 3.8.5
[root@f970f6155e37 /]# pip --version    
pip 19.3.1 from /usr/lib/python3.8/site-packages/pip (python 3.8)

Step3: Install Django

Now, we have the pre-requisite software (ie. Python and pip) installed, we can go ahead and install the Django pip package as shown below.

Install and validate Django in container
[root@fed32 ~]# buildah run fedora-working-container -- pip install Django
WARNING: Running pip install with root privileges is generally not a good idea. Try `pip install --user` instead.
Collecting Django
  Downloading (7.8MB)
     |████████████████████████████████| 7.8MB 347kB/s 
Collecting sqlparse>=0.2.2
  Downloading (42kB)
     |████████████████████████████████| 51kB 2.0MB/s 
Collecting asgiref~=3.2.10
Collecting pytz
  Downloading (510kB)
     |████████████████████████████████| 512kB 2.6MB/s 
Installing collected packages: sqlparse, asgiref, pytz, Django
Successfully installed Django-3.1.2 asgiref-3.2.10 pytz-2020.1 sqlparse-0.4.1

[root@fed32 ~]# buildah run fedora-working-container /bin/bash
[root@f970f6155e37 /]# pip list    
Package    Version
---------- -------
asgiref    3.2.10 
Django     3.1.2  
gpg        1.14.0 
libcomps   0.1.15 
pip        19.3.1 
pytz       2020.1 
rpm        4.15.1 
setuptools 41.6.0 
sqlparse   0.4.1

Step4: Create a project named mysite in folder /home/admin/Django_Projects

Right now we have our Python Django web framework libraries installed. We can try to build a Django project as shown below. First we will create a directory and then use django-admin tool to start a new project named mysite. Once the mysite project is built we will set this project folder directory as the working directory in our image.

Create Django project and set the working directory within container
[root@fed32 ~]# buildah run fedora-working-container -- mkdir -p /home/admin/Django_Projects
[root@fed32 ~]# buildah config --workingdir /home/admin/Django_Projects fedora-working-container
[root@fed32 ~]# buildah run fedora-working-container -- django-admin startproject mysite
[root@fed32 ~]# buildah config --workingdir /home/admin/Django_Projects/mysite fedora-working-container

Step5: Configure the command to run with the container

Now, that we can our default project setup ready, we need to set the PATH to point to the python executable as shown below and launch the django ligthweight web server on port 8000 when the cmd step is executed.

Configure environment variable and command to run within container
[root@fed32 ~]# buildah config --env PATH=$PATH:/usr/bin/python3.8 f970f6155e37
[root@fed32 ~]# buildah config --cmd '"/usr/bin/python3.8" "" "runserver" "0:8000"' fedora-working-container

Step6: Expose the Port to access Django website URL

We need to expose the port 8000 of Django web server that will be used to access the default Django web application.

Configure port to expose within container
[root@fed32 ~]# buildah config --port 8000 fedora-working-container

Step7: Commit the changes to the container into a new image

Now, we have all the required software installed and configuration completed. We can commit all these changes to create an image named hellodjango using the buildah commit command.

Commit changes within container
[root@fed32 ~]# buildah commit fedora-working-container hellodjango
Getting image source signatures
Copying blob 4f51e20f4794 skipped: already exists  
Copying blob 09c674fe9922 done  
Copying config 05fa2ff411 done  
Writing manifest to image destination
Storing signatures

Lets try to list our the images currently available using podman tool once the above commit is completed. This will show our newly built Djang web application image.

Validate new container image
[root@fed32 ~]# podman images
REPOSITORY                         TAG     IMAGE ID      CREATED             SIZE
localhost/hellodjango              latest  05fa2ff411ad  About a minute ago  699 MB  latest  e6b57c0d9f53  5 days ago          208 MB

Step8: Create a container for image hellodjango

Lets try to run a container from the image that has been commited in our previous step. We are using port forwarding to access the Django application hosted on port 8000 to be accessible from host machine on port 8000.

Create container from new image named hellodjango
[root@fed32 ~]# podman run -dt -p 8000:8000 localhost/hellodjango

Step9: Validate the default Django application

Once the container has been instantiated, we can launch the url using http://localhost:8000/ to get the default Django page.

Hope you enjoyed reading this article. Thank you.