Build container images using buildah

Paul Reyes
4 min readMay 29, 2019

buildah is a command line tool that facilitates building OCI compliant images.

The Buildah package provides a command line tool that can be used to

  • create a working container, either from scratch or using an image as a starting point
  • create an image, either from a working container or via the instructions in a Dockerfile
  • images can be built in either the OCI image format or the traditional upstream docker image format
  • mount a working container’s root filesystem for manipulation
  • unmount a working container’s root filesystem
  • use the updated contents of a container’s root filesystem as a filesystem layer to create a new image
  • delete a working container or an image
  • rename a local container

Installing buildah

buildah is available in the CentOS repo. All we need to do is to run the following to install it:

[podman@localhost ]# yum install -y buildah

After installation is done, we can check the version of the installed package

[podman@localhost base]# buildah --version
buildah version 1.7.1 (image-spec 1.0.0, runtime-spec 1.0.0)

I am going to use a previous Dockerfile that I have to build a test container image. The application is just a simple flask test application.

[podman@localhost base]# ls
Dockerfile hello.py requirements.txt run.py
[podman@localhost base]# cat Dockerfile
from python:2.7.10
COPY requirements.txt /app/requirements.txt
COPY hello.py /app/hello.py
RUN pip install -r /app/requirements.txtCMD ["python","/app/hello.py"]

And running build-using-dockerfile, you’ll find a pretty similar output when using docker build command

[podman@localhost base]# buildah build-using-dockerfile -t base_bud .
STEP 1: FROM python:2.7.10
Getting image source signatures
Copying blob d4bce7fd68df [======================================] 1.5GiB / 1.5GiB
Copying blob a3ed95caeb02 [======================================] 1.5GiB / 1.5GiB
Copying blob 816152842605 [======================================] 1.5GiB / 1.5GiB
Copying blob 5dcab2c7e430 [======================================] 1.5GiB / 1.5GiB
Copying blob dc54ada22a60 [======================================] 1.5GiB / 1.5GiB
Copying blob b7b0de78f891 [======================================] 1.5GiB / 1.5GiB
Copying blob a3ed95caeb02 [======================================] 1.5GiB / 1.5GiB
Copying blob 88363ed594cb [======================================] 1.5GiB / 1.5GiB
Copying blob a3ed95caeb02 [======================================] 1.5GiB / 1.5GiB
Copying blob a3ed95caeb02 [======================================] 1.5GiB / 1.5GiB
Copying blob f8c4a940a0da [======================================] 1.5GiB / 1.5GiB
Copying blob dd19554ab82c [======================================] 1.5GiB / 1.5GiB
Copying blob a3ed95caeb02 [======================================] 1.5GiB / 1.5GiB
Writing manifest to image destination
Storing signatures
STEP 2: COPY requirements.txt /app/requirements.txt
STEP 3: COPY hello.py /app/hello.py
STEP 4: RUN pip install -r /app/requirements.txt
Collecting flask (from -r /app/requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/9a/74/670ae9737d14114753b8c8fdf2e8bd212a05d3b361ab15b44937dfd40985/Flask-1.0.3-py2.py3-none-any.whl (92kB)
100% |████████████████████████████████| 94kB 905kB/s
Collecting itsdangerous>=0.24 (from flask->-r /app/requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/76/ae/44b03b253d6fade317f32c24d100b3b35c2239807046a4c953c7b89fa49e/itsdangerous-1.1.0-py2.py3-none-any.whl
Collecting Werkzeug>=0.14 (from flask->-r /app/requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/9f/57/92a497e38161ce40606c27a86759c6b92dd34fcdb33f64171ec559257c02/Werkzeug-0.15.4-py2.py3-none-any.whl (327kB)
100% |████████████████████████████████| 327kB 394kB/s
Collecting Jinja2>=2.10 (from flask->-r /app/requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/1d/e7/fd8b501e7a6dfe492a433deb7b9d833d39ca74916fa8bc63dd1a4947a671/Jinja2-2.10.1-py2.py3-none-any.whl (124kB)
100% |████████████████████████████████| 126kB 796kB/s
Collecting click>=5.1 (from flask->-r /app/requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/fa/37/45185cb5abbc30d7257104c434fe0b07e5a195a6847506c074527aa599ec/Click-7.0-py2.py3-none-any.whl (81kB)
100% |████████████████████████████████| 81kB 847kB/s
Collecting MarkupSafe>=0.23 (from Jinja2>=2.10->flask->-r /app/requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/b9/2e/64db92e53b86efccfaea71321f597fa2e1b2bd3853d8ce658568f7a13094/MarkupSafe-1.1.1.tar.gz
Building wheels for collected packages: MarkupSafe
Running setup.py bdist_wheel for MarkupSafe
Stored in directory: /root/.cache/pip/wheels/f2/aa/04/0edf07a1b8a5f5f1aed7580fffb69ce8972edc16a505916a77
Successfully built MarkupSafe
Installing collected packages: itsdangerous, Werkzeug, MarkupSafe, Jinja2, click, flask
Successfully installed Jinja2-2.10.1 MarkupSafe-1.1.1 Werkzeug-0.15.4 click-7.0 flask-1.0.3 itsdangerous-1.1.0
You are using pip version 7.1.2, however version 19.1.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
STEP 5: CMD ["python","/app/hello.py"]
STEP 6: COMMIT containers-storage:[overlay@/var/lib/containers/storage+/var/run/containers/storage]localhost/base_bud:latest
Getting image source signatures
Copying blob 12e469267d21 [======================================] 124.9MiB / 124.9MiB
Copying blob 5f70bf18a086 [======================================] 1.0KiB / 1.0KiB
Copying blob 0d78baeff42f [======================================] 43.1MiB / 43.1MiB
Copying blob c32291971339 [======================================] 120.4MiB / 120.4MiB
Copying blob d6d84a7ea9f1 [======================================] 307.6MiB / 307.6MiB
Copying blob a21d673437af [======================================] 1.4MiB / 1.4MiB
Copying blob 5f70bf18a086 [======================================] 1.0KiB / 1.0KiB
Copying blob 3c62eeb65f64 [======================================] 33.0KiB / 33.0KiB
Copying blob 5f70bf18a086 [======================================] 1.0KiB / 1.0KiB
Copying blob 5f70bf18a086 [======================================] 1.0KiB / 1.0KiB
Copying blob 641946be2935 [======================================] 60.9MiB / 60.9MiB
Copying blob 7ce007c412b5 [======================================] 5.8MiB / 5.8MiB
Copying blob 5f70bf18a086 [======================================] 1.0KiB / 1.0KiB
Copying blob ff620944702d [======================================] 5.9MiB / 5.9MiB
Copying config e3b4c77357 [======================================] 4.6KiB / 4.6KiB
Writing manifest to image destination
Storing signatures
--> e3b4c773576230182c498a12b5a3fd8611da958ba5b273947eedc46b50ff6617

Listing our images using buildah

[podman@localhost base]# buildah images
IMAGE NAME IMAGE TAG IMAGE ID CREATED AT SIZE
docker.io/library/python 2.7.10 4442f7b981c4 Dec 6, 2015 05:49 696 MB
localhost/base_bud latest e3b4c7735762 May 27, 2019 22:47 703 MB

Using podman (podman is a tool for managing pods, containers, and container images.), let’s try the newly created image

[podman@localhost base]# podman run base_bud
* Serving Flask app "hello" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://0.0.0.0:8080/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 437-588-275

And listing our running container

[podman@localhost base]# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
32597e3dd8c5 localhost/base_bud:latest python /app/hello... 2 minutes ago Up About a minute ago upbeat_mcnulty

Checking our app by going inside the container

[podman@localhost base]# podman exec -it 32597e3dd8c5 /bin/sh
# curl localhost:8080
127.0.0.1 - - [27/May/2019 14:56:46] "GET / HTTP/1.1" 200 -
Hello World
#

In this post we saw how simple (and identical to docker) it is to use buildah to create an OCI compliant container image.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Paul Reyes
Paul Reyes

Written by Paul Reyes

{ “Cloud Engineer”:☁️, “DevOps”:🤖, “Automation”: ⚙️, “Shutterbug”: 📷}

No responses yet

Write a response