A Docker image is a lightweight, standalone, and executable package that includes everything needed to run a piece of software, including the code, runtime, system tools, libraries, and settings. Images are the building blocks of Docker containers.
- Layers: Images are composed of multiple layers, each representing a set of changes to the filesystem.
- Base Image: The foundation of an image, typically a minimal operating system.
- Parent Image: An image that your image is built upon.
- Image Tags: Labels used to version and identify images.
- Image ID: A unique identifier for each image.
To see all images on your local system:
docker images
Or use the more verbose command:
docker image ls
To download an image from Docker Hub:
docker pull <image_name>:<tag>
Example:
docker pull ubuntu:20.04
If no tag is specified, Docker will pull the latest
tag by default.
To run a container from an image:
docker run <image_name>:<tag>
Example:
docker run -it ubuntu:20.04 /bin/bash
To get detailed information about an image:
docker inspect <image_name>:<tag>
To remove an image:
docker rmi <image_name>:<tag>
or
docker image rm <image_name>:<tag>
To remove all unused images:
docker image prune
- Create a file named
Dockerfile
with no extension. - Define the instructions to build your image.
Example Dockerfile:
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y nginx
COPY ./my-nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
- Build the image:
docker build -t my-nginx:v1 .
- Make changes to a running container.
- Create a new image from the container:
docker commit <container_id> my-new-image:tag
To tag an existing image:
docker tag <source_image>:<tag> <target_image>:<tag>
Example:
docker tag my-nginx:v1 my-dockerhub-username/my-nginx:v1
- Log in to Docker Hub:
docker login
- Push the image:
docker push my-dockerhub-username/my-nginx:v1
Understanding layers is crucial for optimizing image builds:
- Each instruction in a Dockerfile creates a new layer.
- Layers are cached and reused in subsequent builds.
- Ordering instructions from least to most frequently changing can speed up builds.
Example of leveraging caching:
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y nginx
COPY ./static-files /var/www/html
COPY ./config-files /etc/nginx
Multi-stage builds allow you to use multiple FROM statements in your Dockerfile. This is useful for creating smaller production images.
Example:
# Build stage
FROM golang:1.16 AS build
WORKDIR /app
COPY . .
RUN go build -o myapp
# Production stage
FROM alpine:3.14
COPY --from=build /app/myapp /usr/local/bin/myapp
CMD ["myapp"]
Docker provides built-in image scanning capabilities:
docker scan <image_name>:<tag>
This helps identify vulnerabilities in your images.
- Use specific tags instead of
latest
for reproducibility. - Keep images small by using minimal base images and multi-stage builds.
- Use
.dockerignore
to exclude unnecessary files from the build context. - Leverage build cache by ordering Dockerfile instructions effectively.
- Regularly update base images to get security patches.
- Scan images for vulnerabilities before deployment.
To manage disk space, regularly clean up unused images:
docker system prune -a
This removes all unused images, not just dangling ones.
Docker images are a fundamental concept in containerization. They provide a consistent and portable way to package applications and their dependencies. By mastering image creation, optimization, and management, you can significantly improve your Docker workflows and application deployments.