Cloud Native 5 Minutes at a Time: Build Image from Dockerfile

Eric Gregory - February 11, 2022 - , , ,

One of the biggest challenges for implementing cloud native technologies is learning the fundamentals—especially when you need to fit your learning into a busy schedule.

In this series, we’ll break down core cloud native concepts, challenges, and best practices into short, manageable exercises and explainers, so you can learn five minutes at a time. These lessons assume a basic familiarity with the Linux command line and a Unix-like operating system—beyond that, you don’t need any special preparation to get started.

In the last lesson, we practiced creating, interrogating, and deleting containers. When we created a new container, we built it on the foundation of a container image—now it’s time to explore exactly what that is, how it works, and how we can build images from Dockerfiles.

Table of Contents

  1. What is a Container?
  2. Creating, Observing, and Deleting Containers
  3. Build Image from Dockerfile←You are here
  4. Using an Image Registry
  5. Volumes and Persistent Storage
  6. Container Networking and Opening Container Ports
  7. Running a Containerized App
  8. Multi-Container Apps on User-Defined Networks
  9. Docker Compose and Next Steps

What is a container image?

You can think of a container image as a photograph—a snapshot of a container’s filesystem state, frozen in time.

In the last lesson, when we wanted to create a new container, we started with a container image called alpine. This was a snapshot of a filesystem with only the bare-bones binaries and libraries of a Linux distribution called Alpine Linux, and nothing else. This open source Linux distribution is well-suited to containerization because it is so lightweight: it packs only what is needed to spin up containers quickly and efficiently, so if we want to quickly create a container running a new process, the alpine image is a great choice.

That gives us a nice glimpse of container images’ utility. To get a process running on an isolated filesystem, we didn’t have to install and configure a whole new system. Instead, with a single command, we conjured a prefabricated base image.

As you’ve probably already guessed, container images can provide a lot more than empty canvases. If we can capture filesystem states in an image, we can capture states with more complex prerequisites, configuration options, and processes ready to go. This allows us to…

  • Trivially replicate containers running complex processes
  • Shape more advanced “building blocks” for development
  • Create a container image repository that acts as a “single source of truth” for software modules used throughout an organization

… and much more besides. As we’ll see over the course of this series, the modularity facilitated by container images can transform the way you develop and deploy software.

Using Dockerfiles to create container images

Sometimes, you’ll want to create a container image based on a container on your system—like taking a live snapshot. You can find a detailed tutorial on that process here. For the purposes of this series, we’re going to focus on a different approach: using a Dockerfile.

A Dockerfile is a set of instructions for creating a container, all set down in a simple text file. Here, we can specify not only a base image to start from, but applications to install and processes to run. That allows us to accomplish much more complicated tasks with easily replicable “recipes.”

Let’s see what this looks like in action. Make sure your container engine is running, and then bring up the terminal. Try entering the following command:

docker container run alpine curl

Based on our last lesson, we would expect this to create a new container based on the alpine image and then run the curl tool (which transfers data from—or to—a server) with the parameter “” With that parameter, we would expect to see some HTML downloaded from the address we specified.

Instead, we likely get output something like this:

docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "curl": executable file not found in $PATH: unknown.

Translation: our new container doesn’t know what we’re asking it to do, because it doesn’t have curl installed.

Well, we can take care of that with a Dockerfile. Create a new folder called “curler” and inside of that folder, create an empty file called Dockerfile, which shouldn’t have a file extension. (If you’re not sure how to do this, use the command touch Dockerfile in your folder and open the file with the editor of your choice.)

Now add the following lines to Dockerfile and save:

FROM alpine:latest
RUN apk update
RUN apk add curl

This recipe instructs the container engine to build an image based on the most recent version of the alpine image, and then to run alpine’s package manager apk, update apk’s index of available packages, and then add the package for curl. In other words, we’re installing the curl tool.

Let’s put our Dockerfile into action by creating an image from these instructions. Run the following command:

docker image build -t curler .

This command tells the Docker engine to build a new image, and -t is shorthand for --tag, which we’re using to name our image “curler.” Finally, the period at the end gives Docker the location of the Dockerfile we’re using for this image—in this case, our current working directory.

The container engine then builds an image based on our instructions (actually, a series of images in swift succession based on each step) and adds it to our local selection of images. If we run…

docker image ls

…we should see it in our image listing. The images listed will vary depending on your environment, but you should see curler among them, and the output should look something like this:

REPOSITORY        TAG            IMAGE ID       CREATED         SIZE
curler            latest         a46b2fdd95c9   1 minute ago    9.97MB
nginx             latest         605c77e624dd   6 weeks ago     141MB
postgres          latest         7526db3fb03b   2 months ago    53.6MB
alpine            latest         c059bfaa849c   2 months ago    5.59MB

Now let’s try using it. Run:

docker container run curler curl

We’re trying to do the same thing as before—run curl with the parameter “” This time, we should get a better result:

% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
Dload  Upload   Total   Spent    Left  Speed
0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
301 Moved

301 Moved

The document has moved here. 100   219  100   219    0     0    180      0  0:00:01  0:00:01 --:--:--   180

Success! We downloaded some very simple placeholder HTML from the address

That’s it for this lesson—remember to clean up your containers. You may also wish to delete the new curler image from among your local images. To do this, you should first delete any containers depending on it, and then run:

docker image rm curler

Next time, we’ll dive deeper into the use and management of images.

From Virtualization to Containerization
Learn how to move from monolithic to microservices in this free eBook
Download Now
Radio Cloud Native – Week of May 11th, 2022

Every Wednesday, Nick Chase and Eric Gregory from Mirantis go over the week’s cloud native and industry news. This week they discussed: Docker Extensions Artificial Intelligence shows signs that it's reaching the common person Google Cloud TPU VMs reach general availability Google buys MobileX, folds into Google Cloud NIST changes Palantir is back, and it's got a Blanket Purchase Agreement at the Department of Health and Human …

Radio Cloud Native – Week of May 11th, 2022
Where do Ubuntu 20.04, OpenSearch, Tungsten Fabric, and more all come together? In the latest Mirantis Container Cloud releases!

In the last several weeks we have released two updates to Mirantis Container Cloud - versions 2.16 and 2.17, which bring a number of important changes and enhancements. These are focused on both keeping key components up to date to provide the latest functionality and security fixes, and also delivering new functionalities for our customers to take advantage of in …

Where do Ubuntu 20.04, OpenSearch, Tungsten Fabric, and more all come together? In the latest Mirantis Container Cloud releases!
Monitoring Kubernetes costs using Kubecost and Mirantis Kubernetes Engine [Transcript]

Cloud environments & Kubernetes are becoming more and more expensive to operate and manage. In this demo-rich workshop, Mirantis and Kubecost demonstrate how to deploy Kubecost as a Helm chart on top of Mirantis Kubernetes Engine. Lens users will be able to visualize their Kubernetes spend directly in the Lens desktop application, allowing users to view spend and costs efficiently …

Monitoring Kubernetes costs using Kubecost and Mirantis Kubernetes Engine [Transcript]
The Definitive Guide to Container Platforms
Mirantis Webstore
Purchase Kubernetes support
Istio in the Enterprise: Security & Scale Out Challenges for Microservices in k8s

Presented with Tetrate