In this page: everything you need to know about Docker Images
What is a Docker Image?
A Docker image is a snapshot, or template, from which new containers can be started. It’s a representation of a filesystem plus libraries for a given OS. A new image can be created by executing a set of commands contained in a Dockerfile (it’s also possible but not recommended to take a snapshot from a running container). For example, this Dockerfile would take a base Ubuntu 16.06 image and install mongoDB, resulting in a new image:
FROM ubuntu:16.04
RUN apt-get install -y mongodb-10gen
From a physical perspective, an image is composed of a set of read-only layers. Image layers function as follows:
Each image layer is the outcome of one command in the image’s Dockerfile—an image is then a compressed (tar) file containing the series of layers.
Each additional image layer only includes the set of differences from the previous layer (try running docker history for a given image to list all its layers and what created them).
For further reading, see Docker Documentation: About images, containers, and storage drivers
Running Images as Containers
Images and containers are not the same—a container is a running instance of an image. A single image can be used to start any number of containers. Images are read-only, while containers can be modified, Also, changes to a container will be lost once it gets removed, unless changes are committed into a new image.
Follow these steps to run an image as container:
First, note that you can run docker container specifying either the image name or image ID (reference).
Run the
docker imagescommand to view the images you have pulled locally or, alternatively, explore the Docker Hub repositories for the image you want to run the container from.
Once you know the name or ID of the image, you can start a docker container with the docker run command. For example, to download the Ubuntu 16.04 image (if not available locally yet), start a container and run a bash shell:
Once you know the name or ID of the image, you can start a docker container with the docker run command. For example, to download the Ubuntu 16.04 image (if not available locally yet), start a container and run a bash shell:
docker run -it ubuntu:16.04 /bin/bash
For further reading, see Docker Documentation: Docker Run Reference
Image Registries
An image registry is a collection of private and/or public repositories to which users can upload and share their Docker images, as well as download (pull) images created by others. A repository is a collection of docker images with the same name but different tags (different versions, if you like).
Examples of public registries include:
Docker Hub , which contains both public and private repositories of images—the public repositories store images from community and official libraries.
Quay , a hosted service which has a free plan for public repositories and a paid model for private repositories.
Cloud providers like AWS or Google typically provide their own registries as well.
Private repositories are suited for proprietary applications, for which you need to strictly control access to your container images.
It is possible to host a private registry composed only of private repositories, either on-prem or in the cloud. Examples include Gitlab’s Container Registry, or JFrog’s Artifactory.
For further reading, see Docker Documentation: Image Registry
Common Operations
Some common operations you’ll need with Docker images include:
Build a new image from a Dockerfile: The command for building an image from a Dockerfile is
docker build, where you specify the location of the Dockerfile (it could be the current directory). You can (optionally) apply one or more tags to the resulting image using parameters. Use the-toption.List all local images: Use the
docker imagescommand to list all local images. The output includes image ID, repository, tags, and creation date.Tagging an existing image: You assign tags to images for clarification, so users know the version of an image they are pulling from a repository. The command to tag an image is
docker tagand you need to provide the image ID and your chosen tag (including the repository). For example:
docker tag 0e5574283393 username/my_repo:1.0
- Pulling a new image from a Docker Registry: To pull an image from a registry, use
docker pulland specify the repository name. By default, the latest version of the image is retrieved from the Docker Hub registry, but this behaviour can be overridden by specifying a different version and/or registry in the pull command. For example, to pull version 2.0 of my_repo from a private registry running on localhost port 5000, run:
docker pull localhost:5000/my_repo:2.0
- Pushing a local image to the Docker registry: You can push an image to Docker Hub or another registry to make it available for other users by running the
docker pushcommand. For example, to push the (latest) local version of my_repo to Docker Hub, make sure you’re logged in first by runningdocker login, then run:
docker push username/my_repo
- Searching for images: You can search the Docker Hub for images relating to specific terms using
docker search. You can specify filters to the search, for example only list “official” repositories.
Best Practices for Building Images
The following best practices are recommended when you build images by writing Dockerfiles:
Containers should be ephemeral in the sense that you can stop or delete a container at any moment and replace it with a new container from the Dockerfile with minimal set-up and configuration.
Use a .dockerignore file to reduce image size and reduce build time by excluding files from the build context that are unnecessary for the build. The build context is the full recursive contents of the directory where the Dockerfile was when the image was built.
Reduce image file sizes (and attack surface) while keeping Dockerfiles readable by applying either a builder pattern or a multi-stage build (available only in Docker 17.05 or higher).
With a builder pattern, you maintain two Dockerfiles – one to build an application inside the image and a second Dockerfile that includes only the resulting application binaries from the first image to generate a second, streamlined image that is production ready. This pattern requires a custom script in order to automatically apply the transformation from the “development” image to the “production” image (for an example, see the Docker documentation: Before Multi-Stage Builds ).
A multi-stage build allows you to use multiple FROM statements in a single Dockerfile and selectively copy artifacts from one stage to another, leaving behind everything you don’t want in the final image. You can, therefore, reduce image file sizes without the hassle of maintaining separate Dockerfiles and custom scripts when using the builder pattern.
Don’t install unnecessary packages when building images.
Use multi-line commands instead of multiple RUN commands for faster builds when possible (for example, when installing a list of packages).
Sort multi-line lists of packages into alphanumerical order to easily identify duplicates and make it easier to update and review the list.
Enable content trust when operating with a remote Docker registry so that you can only push, pull, run, or build trusted images which have been digitally signed to verify their integrity. When you use Docker with content trust, commands only operate on tagged images that have been digitally signed. Less trustworthy unsigned image tags are invisible when you enable content trust (off by default). To enable it, set the DOCKER_CONTENT_TRUST environment variable to 1. For further information see the Docker documentation: Content trust in Docker .
For further reading, see Docker Documentation: Best Practices For Writing Dockerfiles
How to Create a Base Image
Many Dockerfiles begin with a parent image using the FROM directive in the Dockerfile, typically pulling a version of an operating system or a custom-made image. A base image, on the contrary, is built without specifying a parent image.
The format for a Docker image is a tar archive file, or tarball.
To create a base image you need to either directly create a tarball that contains the OS distribution you want in the base image, or you can use Docker’s reserved scratch image. The scratch image appears in Docker’s repository, but you can’t pull, run, or tag any image with the name “scratch”. However, you can reference it in your Dockerfile with the command FROM scratch. This is common for building an image with a standalone binary that does not depend on specific OS libraries.
For further reading, see Docker Documentation: Create a Base Image
How to Remove an Image
When you work with Docker, it’s easy to accumulate excessive numbers of either untagged old images (called dangling images) or tagged but unused images, which consume unnecessary disk space.
You can remove dangling images with the docker image prune command. Further specifying the -a option in the command will remove not only the dangling images, but also all unused ones (that means an image not assigned or used in any container), regardless of their tags.
For further reading, see Docker Documentation: docker image prune
Summary
A Docker image is a template from which new Docker containers can be started. A Dockerfile is a short file that contains instructions for the new Docker containers that are created from the image. In this page we explained basic concepts of Docker images, the idea of Image Registries which allow you to publish images for use by others and consume images published by others, common operations such as building a new image, listing all images and publishing a local image to a registry, some important best practices for working with images, and how to create and remove a base image.
Further Reading
- Docker 101
- Docker Containers vs. Virtual Machines
- 100 Best Docker Tutorials
- Docker Architecture
- Docker Registries 101
- Docker Images 101
- Docker Security - Risks, Benefits and 8 Best Practices
- Docker Tools
- Docker Alternatives - Rkt, LXD, OpenVZ, Linux VServer, Windows Containers
- Docker Swarm 101
- Docker vs. Kubernetes - 8 Industry Opinions
- Docker Networking 101
- Docker in the Cloud
- Docker in Production
- Docker Deployment
- Basic Docker Operations
- Docker Administration
- Docker Security Resources
- Docker OS Interaction
- Docker With Other Tools
- Docker API
- Docker Compose

