Introduction
In the previous chapter, we covered the basics of Docker Engine installation and its architecture. Now, it’s time to dive into the core concepts that make Docker so powerful: Images and Containers. These two fundamental building blocks are often confused, but understanding their distinct roles and how they interact is crucial for anyone looking to leverage Docker effectively.
This chapter will demystify Docker Images and Containers, explain their relationship, and demonstrate how to manage them using basic Docker commands. By the end, you’ll have a solid grasp of what they are, what they do, and how they form the backbone of Dockerized applications.
Main Explanation
What is a Docker Image?
A Docker Image is a lightweight, standalone, executable package that includes everything needed to run a piece of software, including the code, a runtime, libraries, environment variables, and configuration files. Think of an image as a blueprint or a template.
- Read-Only Template: Images are immutable. Once created, they cannot be changed. This ensures consistency across different environments.
- Layered File System: Images are built up from a series of layers. Each layer represents an instruction in the image’s Dockerfile (which we’ll cover in detail later). This layering allows for efficient storage and distribution, as common layers can be shared between images.
- Portability: An image contains all dependencies, making it highly portable. You can build an image once and run it anywhere Docker is installed.
- Origin: Images can be pulled from public registries like Docker Hub, private registries, or built locally from a
Dockerfile.
What is a Docker Container?
A Docker Container is a runnable instance of a Docker Image. If an image is a blueprint, a container is the actual house built from that blueprint. When you run an image, Docker creates a container, which is an isolated environment where your application executes.
- Runtime Instance: Containers are the actual execution environments for applications. You can have multiple containers running from the same image, each isolated from the others.
- Isolated Environment: Each container runs in isolation from other containers and the host system. This isolation includes its own process space, network interface, and file system.
- Read-Write Layer: While the image itself is read-only, a container adds a thin, writable layer on top of the image’s file system. All changes made by the running application within the container are stored in this layer.
- Lifecycle: Containers have a lifecycle: create, start, stop, pause, and remove.
Image vs. Container: The Core Difference
| Feature | Docker Image | Docker Container |
|---|---|---|
| Nature | Blueprint, template, static | Runtime instance, executable, dynamic |
| State | Read-only, immutable | Read-write layer on top of image |
| Storage | Stored as a series of layers | Isolated runtime environment |
| Purpose | Packaging applications and their dependencies | Running applications in isolation |
| Creation | Built from a Dockerfile or pulled from a registry | Created and started from an image |
| Analogy | A class definition (programming), a cookie cutter | An object instance, a cookie |
Key Concepts
- Dockerfile: A text file that contains all the commands a user could call on the command line to assemble an image. It defines the base image, adds files, sets environment variables, and specifies the command to run when the container starts.
- Docker Hub: A cloud-based registry service provided by Docker for finding and sharing container images. It’s the default registry for Docker.
- Registry: A repository for storing and distributing Docker Images. Docker Hub is the most popular public registry, but private registries can also be used.
Examples
Let’s explore some basic Docker commands to manage images and containers.
1. Pulling a Docker Image
To download an image from Docker Hub to your local machine:
docker pull ubuntu:latest
This command pulls the ubuntu image with the latest tag. If no tag is specified, latest is assumed by default.
2. Listing Docker Images
To see all images currently stored on your local machine:
docker images
You’ll see a table with image details like REPOSITORY, TAG, IMAGE ID, CREATED, and SIZE.
3. Running a Docker Container
To create and start a container from an image:
docker run hello-world
This command will:
- Check if the
hello-worldimage exists locally. If not, it pulls it from Docker Hub. - Creates a new container from that image.
- Runs the command specified in the image (in this case, prints “Hello from Docker!”).
- Exits the container because its task is complete.
Let’s try running a more interactive container, like ubuntu:
docker run -it ubuntu:latest /bin/bash
-it: This flag combines-i(interactive) and-t(allocate a pseudo-TTY), allowing you to interact with the container’s shell.ubuntu:latest: The image to use./bin/bash: The command to execute inside the container, which opens a bash shell.
You’ll now be inside the Ubuntu container. Try running commands like ls or pwd. To exit, type exit.
4. Listing Docker Containers
To see currently running containers:
docker ps
To see all containers (running and stopped):
docker ps -a
You’ll see details like CONTAINER ID, IMAGE, COMMAND, CREATED, STATUS, PORTS, and NAMES.
5. Stopping and Removing Containers
First, start an nginx container in detached mode (-d) so it runs in the background:
docker run -d --name my-nginx -p 8080:80 nginx
-d: Detached mode, runs the container in the background.--name my-nginx: Assigns a human-readable name to the container.-p 8080:80: Maps port 8080 on your host to port 80 inside the container.
Now, stop the container:
docker stop my-nginx
And then remove it:
docker rm my-nginx
You can also stop and remove a container using its CONTAINER ID (which you can get from docker ps -a).
6. Removing Docker Images
To remove an image from your local machine:
docker rmi ubuntu:latest
You might need to remove all containers based on an image before you can remove the image itself. If there are running containers, you’ll get an error. If there are stopped containers, you might need to use the -f (force) flag, but it’s generally better to remove containers cleanly first.
Mini Challenge
Your challenge is to:
- Pull the
alpineimage (a very small Linux distribution). - Run a container from the
alpineimage, executing the commandecho "Hello from Alpine!". - Verify that the container ran and exited by listing all containers.
- Remove the
alpinecontainer you just created. - Remove the
alpineimage from your local system.
Good luck!
Summary
In this chapter, we’ve laid the groundwork for understanding Docker by clearly defining Images and Containers. We learned that an Image is a static, read-only blueprint containing everything an application needs, while a Container is a live, runnable instance of that image, providing an isolated environment. We explored the core differences, lifecycle, and key concepts like Dockerfiles and Docker Hub.
Through practical examples, you’ve gained hands-on experience with fundamental Docker commands: pulling images, running containers, listing them, and managing their lifecycle by stopping and removing them. With this knowledge, you are now equipped to start interacting with Docker at a basic level, paving the way for more advanced topics in the upcoming chapters.