A container is a lightweight, self-contained executable that contains all of the dependencies to run an application. It was born out of a need for a simple and streamlined way for developers to have their code deployed.
A containerized application is a single file. Therefore, containers enable us to deploy applications as one unit of deployment.
System dependencies are built as part of the container Everything that is needed for the application to function properly is installed with the appropriate version.
The same underlying system is used to run the application so the runtimes remain consistent. Settings such as the port number are also bundled as part of the container.
Container technology comes with a vibrant set of tools that are standardized across the industry. These tools enable developers to iterate quickly as well as build on top of each other's container settings.
Virtual Machines are burdened with the overhead of managing its entire operating system. This overhead includes its own CPU, network interface, memory, and storage.
Containers, on the other hand, run using the host machine's underlying operating system. This significantly reduces its overhead and allows it to be lightweight.
While virtual machines are typically a few GB in size, containers are often found to be a few MB in size.
Containers are the running instance of a Docker image. Containers are ephemeral so any modifications to a container do not persist after the container is terminated.
Images are read-only instructions that instruct the Docker engine on how to create a container. The instructions to specify how a Docker image is created is contained in a special file called the Dockerfile.
Docker images are immutable so they can't be modified. Any necessary modifications are done during the build process to create a new Docker image.
The Docker Engine is an open-source tool used for building and running images as containerized applications.
The following commands are the most commonly-used Docker commands to manage the lifecycle of Docker images and containers.
docker build <DIRECTORY_WITH_DOCKERFILE> - used with a Dockerfile to build a Docker image
docker run <IMAGE_NAME> - create and run a Docker container for a given image
docker ps - show Docker processes to view running containers
docker kill <CONTAINER_ID> - terminate a running Docker container
docker build with a Dockerfile to build a Docker image
docker run to use a Docker image to create one or more Docker containers
Docker Engine is the core component of the Docker platform that enables containerization of applications. It is responsible for building, running, and managing Docker containers on a host system. Docker Engine is built upon several key components that work together to provide the functionality needed to create, deploy, and manage containers:
Docker Daemon (dockerd): A background service that runs on the host operating system and manages containers, images, networks, and volumes. It listens for API requests from Docker CLI or other clients and processes them to perform various Docker-related tasks.
Docker CLI (Command Line Interface): A command-line tool used to interact with the Docker daemon for managing containers, images, networks, and other Docker objects. Users issue commands to build, run, and manage containers through the Docker CLI.
Docker API (Application Programming Interface): A RESTful API that allows communication between the Docker daemon and Docker CLI or other clients. It enables programmatic control of Docker containers, images, networks, and volumes.
Container Runtime: The component responsible for running containers. Docker Engine initially used Docker's native container runtime, but now it supports other container runtimes like containerd or CRI-O through the Container Runtime Interface (CRI) plugin.
Docker attempts to cache build artifacts to improve build times. This helps improve build times to increase development productvity.
If you encounter unexpected bugs when setting up a Dockerfile, it can be useful to specify the --no-cache flag in your build to instruct Docker to avoid using the cache.
docker build . --no-cache
Unexpected bugs with the image created from a Dockerfile
Verify Dockerfile will build properly in another environment
A base image specifies a parent image that your Docker image is based on. Any configurations and dependencies in the base image will be included included in the final image. The Docker ecosystem is rich with different base images that make Docker development more streamlined and pleasant.
Base images are specified in the top of a Dockerfile with the FROM <image> syntax.
Simplify your own Dockerfile
Reduce Docker image build time
Best practices with separations of concern
A .dockerignore is created in your root directory and can be used to specify files or directories that you don’t want included in the build process.
Exclude unwanted build artifacts
Exclude sensitive information
Exclude development environment configurations
Arguments and variables can be set during build time or run time. This enables us to abstract configurations from the Docker image itself.
For example, it's common for applications to expose itself on a default port but allow users to override the port with something that makes more sense in their deployment.
Abstract configurations from the Docker image
Build Arguments are defined in a Dockerfile with the ARG syntax. These variables only exist during the build process.
docker build --build-arg key=value .
Runtime arguments are defined as environment variables in a Dockerfile with the ENV syntax.
docker run -e key=value <IMAGE_NAME>
The Docker daemon, also known as dockerd, is a background service that runs on the host operating system and is responsible for managing Docker containers, images, networks, and volumes. It listens for API requests from the Docker CLI or other clients and processes them to build, run, stop, and manage Docker containers, as well as to perform other Docker-related tasks.
The Docker daemon provides a REST API, enabling various tools and applications to communicate with it and perform container management tasks.
Docker Desktop is a software application and developer tool that you install on your local machine (Windows or macOS). It provides a user-friendly interface for setting up and managing Docker containers and additional tools and features for working with Docker.
Docker Desktop includes the Docker daemon as part of its package, making it easy to set up and manage Docker on Windows and macOS operating systems. It also includes the Docker CLI (the command-line interface for interacting with the Docker daemon).
Docker Compose tool (for defining and running multi-container Docker applications). It also offers a dashboard for managing containers, images, and networks.
Docker Hub is a cloud-based service that serves as a centralized registry for Docker container images. While it is a software service, it is not something you install on your local machine like Docker Desktop. Instead, you access Docker Hub through a web browser or interact with it using the Docker CLI or API. Docker Hub allows you to store, manage, and share both public and private Docker container images. It also provides additional features like automated builds, webhooks, and integration with popular CI/CD platforms.
Docker Hub allows developers to share docker containers that can serve as a base image for building new solutions. These base images can be built by experts and certified to be high quality: For example, the official Python developers have a base image. This allows a developer to leverage the expertise of the true expert on a particular software component and improve the overall quality of their container. This concept is similar to using a library developed by another developer versus writing it yourself.