Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 79

Building Images with Podman and Dockerfiles

Recommended resources

Hello! Welcome back to our course on containerizing your Django application with Podman.

In our last lesson, you wrote a complete, production-ready Dockerfile. You created the blueprint for your Django application, detailing everything from the base system to the final command needed to run it.

Today, we bring that blueprint to life. Our goal is to build a custom container image from the Dockerfile using Podman. We'll take the text file you created and use Podman to execute its instructions, producing a self-contained, portable image of your application. This is the crucial step that packages your code into a distributable unit, ready for the final step: running it.

1. The podman build Command

The primary tool for this task is the podman build command. It reads a Dockerfile (or Containerfile, as it's often called in the Podman world), executes the instructions in order, and generates a container image.

Before we build our own Django image, let's watch a demonstration to understand the command and the process.

Containers and Podman for beginners | Into the Terminal 154

This video from Red Hat's 'Into the Terminal' series provides a clear, practical walkthrough of the podman build command. It's an excellent primer for a Fedora user.

Watch the segment from 26:12 to 31:18. Note that the presenter uses the name Containerfile, which is functionally identical to Dockerfile for our purposes. Pay close attention to: The explanation of the instructions within the file (FROM, RUN, EXPOSE, ENTRYPOINT). The syntax of the podman build -t command. What the -t (tag) flag is used for. How the build process creates a local image named localhost/myapp.

As you saw in the video, the basic syntax is:

podman build -t <image_name>:<tag> .

  • podman build: The command itself.
  • -t: The flag for tagging. This gives your image a human-readable name and version (e.g., django-app:1.0). The localhost/ prefix is often added by Podman to denote an image that exists only on your local machine and not in a remote registry.
  • .: The final dot is crucial. It represents the build context, which is the set of files at the specified location. By using ., you're telling Podman to use the current directory as the context. This is how the COPY instruction in your Dockerfile knows where to find your project files.

2. Your Turn: Build Your Django Image

Now, let's apply this to the Django project you created in the last lesson.

1. Navigate to Your Project
Open your terminal and change into the directory you created previously.

cd ~/django_podman_project

You can verify that your Dockerfile, entrypoint.sh, requirements.txt, and Django project files are all present with ls -l.

2. Build the Image
Execute the following command. We will tag our image as django-app with a version of 1.0.

podman build -t django-app:1.0 .

You will see Podman execute each step from your Dockerfile. It will pull the base python:3.11-slim image, run commands, copy files, and finally create your image. The output should look similar to the process shown below.

Podman Build Process Output
This image shows the typical terminal output from a `podman build` command. Each `STEP` corresponds to a line in your Dockerfile, showing how the image is constructed layer by layer.

3. Verify the Image
Once the build is complete, how can you be sure it worked? Use the podman images command to list all the container images stored on your machine.

podman images

You should see your newly created image in the list, something like this:

REPOSITORY             TAG         IMAGE ID      CREATED         SIZE
localhost/django-app   1.0         a1b2c3d4e5f6  2 minutes ago   ...MB
docker.io/library/python  3.11-slim   f7g8h9i0j1k2  ...             ...MB

Congratulations! You've successfully turned your source code and Dockerfile into a runnable container image.


3. Understanding Layers and Caching

You may have noticed that the build output mentions "layers". Each instruction in a Dockerfile creates a filesystem layer. Podman then caches these layers. If you rebuild an image and a layer's instruction (and any files it depends on) hasn't changed, Podman reuses the cached layer instead of re-running the instruction. This makes subsequent builds much faster.

Let's see this in action.

1. Re-run the Build
Run the exact same build command again:

podman build -t django-app:1.0 .

Notice how it finishes almost instantly. The output for each step will likely say Using cache, because nothing has changed.

2. Make a Small Change
Now, let's make a trivial change to one of your project files. For example, add a comment to your settings.py file.




# Open the settings file in a text editor
nano core/settings.py



# Add a comment like '# Test change' anywhere in the file and save it.

3. Rebuild Again
Run the build command one more time:

podman build -t django-app:1.0 .

Observe the output carefully. The initial steps (FROM, ENV, RUN pip wheel...) will still use the cache. However, when the build reaches the step that copies your application code (COPY --chown=app:app . .), Podman detects the change and invalidates the cache. This step, and all subsequent steps, will be re-executed.

This powerful mechanism is why we structured our Dockerfile in the previous lesson to copy requirements.txt and install dependencies before copying the rest of the application code. Since dependencies change less frequently than code, their layer is more likely to be cached, speeding up your day-to-day development workflow.


4. Further Reading and References

For a concise, text-based summary of the build process, you can refer to the following resources. They also touch on pushing images to a registry, a topic for another day.

Building Container Image With Podman

This section from the DevOps Cube tutorial provides a straightforward, step-by-step guide to building an image with Podman.

Read the section titled 'Building Container Image With Podman'. It reinforces the podman build, podman tag, and podman push commands you've seen.

Building Application Images Using Red Hat Software Collections Container Images

The official Red Hat documentation provides another excellent example, this time specifically for a Django application, confirming the steps we've taken.

Focus on Example 2.1, which shows a Dockerfile for a Django application and the podman build command used to create the image.


Conclusion

In this lesson, you have mastered the essential skill of building a container image from a Dockerfile. You've moved from a theoretical blueprint to a tangible, ready-to-use artifact.

Key Takeaways:

  • The podman build -t <name:tag> . command is used to build a container image from a Dockerfile in the current directory.
  • Tagging (-t) is essential for versioning and identifying your images.
  • podman images lists all the images on your local system.
  • Podman's layer caching significantly speeds up rebuilds by reusing unchanged parts of an image, highlighting the importance of a well-structured Dockerfile.

Preview of the Next Lesson:
You have the blueprint, and you've built the vehicle. In our next lesson, "Run the Django application in a rootless container with port mapping," you'll finally turn the key. We will use the podman run command to launch a container from your newly built image and access your Django application from your web browser.