Introduction
Docker containers are designed to run anywhere - in an in-house data center, the cloud, or a hybrid and multi-cloud environment. Out of the box, Docker containers tend to outperform other virtualization methods, but they can be further optimized to offer even better performance.
This article discusses the reasons behind sub-optimal Docker performance in some scenarios and offers solutions to apply to your system to optimize Docker deployments.
What Causes Slow Docker Performance?
Docker is a complex system that depends on multiple factors, including the host configurations and network quality. The following are some of the most common reasons why Docker is slow.
Inadequately Allocated Resources
When Docker containers do not have access to enough resources, they quickly experience performance issues. Depending on the average image size of a project and the number of containers you are running, the hosts and network need to be able to support the workload.
Docker Image Size
Docker uses images to create containers. Images consist of the source code, libraries, and dependencies necessary for the app to function properly. A Docker container created from an image is a stable environment for development and testing.
However, unwieldy Docker images consume a lot of resources and hog the entire system. Since the image size is a relative term and depends on the needs of a particular application, this statement refers primarily to how much the image is optimized or bloated with unnecessary files.
Note: Check out our article Docker Image vs Docker Container to learn more about the difference between these two.
Docker File Context Size
The docker build
command uses two sources to build an image - a Dockerfile and a context. A context is the set of files in a specified location to which the build process can refer. If the context size is too large, build-time performance may be affected.
Default Docker Configuration Still in Use
Even though the default Docker configuration provides reasonable parameters for Docker to work out of the box, every system is specific. Misconfigured daemon startup options, networking, and other parameters can degrade Docker's performance.
Network Latency
Unless you create your registry, Docker will use Dockerhub to fetch images directly. Moving a large amount of data over the internet causes network latency to become a factor in the general Docker performance.
Note: If you plan to move to Kubernetes, you might want to switch to Podman. Learn more in our Docker vs Podman comparison.
How to Optimize Docker Performance
There are several ways to make your Docker perform faster, ranging from hardware improvements to tweaks inside Docker itself.
Allocate Resources Properly
The performance of the host machine influences the containers performance. A slow CPU or insufficient RAM can become a bottleneck, slowing down Docker's performance.
When you experience slow Docker performance, check your CPU, memory usage, and available disk space. Consider upgrading your system if a component does not perform as expected.
When dealing with a specific container that is performing worse than expected, it may be helpful to check container-specific metrics.
The docker stats
command displays the important metric data about the running containers. Use it to diagnose potential problems.
docker stats
The command output shows:
- CPU utilization.
- Memory usage and limit per container.
- Percentage of memory consumption.
- NET I/O - Docker network traffic.
- BLOCK I/O - Data written to host block devices.
- PIDS - The number of threads a container created.
Optimize Docker Images
First, check the size of the built image by using the following command:
docker images
The output lists the image's repository, tag, ID, time since creation, and size:
Check the image's Dockerfile and make sure that the file context is not too large. The context lists the files that Docker needs to build a container.
The context size is displayed in the output of the docker build
command:
docker build -t [image-name] .
In the following example, the context size is 4.641 MB:
If the build context of the image is too big, create a .dockerignore file in the root directory of the context, and add the unnecessary files to it. Docker will ignore the files listed there when it builds the image.
Here is an example of a .dockerignore file:
temp*
*/temp*
The first line tells Docker to exclude from the context all files and directories whose names start with temp
in the root directory. The second does the same for any sub-directory of the root.
Note: For more tips on how to optimize your Docker image size, read Docker Image Size - How to Keep It Small.
Check the Dependencies
When installing dependencies, Debian-based Docker images can generate additional binaries and files. Some of these interdependencies are not needed for the normal functioning of the container and can be removed.
To manually remove unnecessary interdependencies, use the commands listed below.
Remove packages in /var/cache
:
apt clean
Remove obsolete packages:
apt autoclean
Remove interdependencies used by removed packages:
apt autoremove
Consider Switching to Microservice Architecture
Monolithic applications tend to be slower than applications built using microservice architecture. If your Docker containers struggle to perform, it may be due to the size of the app inside the container. Migrating the app to microservices allows splitting the workload between more than one container.
Use Dedicated Resources
In cloud environments, VMs often share hardware resources with other VMs on the same server. However, hosting containers on Bare Metal Cloud's dedicated hardware eliminates virtualization overhead and improves the performance of the containers. Containerized apps do not share system resources like RAM and CPU, which does not lower latency and lets apps fully utilize the hardware.
Use Lightweight Operating System
Full-featured operating systems like Windows, macOS, or commercial Linux distributions consume a large portion of system resources, leaving less than necessary for optimal Docker performance. Lightweight distros such as RancherOS, CoreOS Container Linux, Alpine Linux, and VMware Photon OS have been optimized to work with Docker containers. Building images on a lightweight system can save upwards of 100 MB of the final image size, significantly improving the speed.
Cache Dockerfile Layers
Use layer caching to improve image-building speed. When Docker starts building an image, it searches the cache for layers containing similar signatures and uses them in the process. This feature speeds up the building process.
If you want to specify the pre-existing image as the cache source, use the --cache-from
option:
docker build --cache-from [image-to-cache-from] -t [next-build] -f [path-to-dockerfile]
Note: For a comprehensive list of Docker commands, read Docker Commands Cheat Sheet.
Conclusion
The article listed some common reasons for slow Docker performance, such as performance bottlenecks, image and context size, and network latency. This guide also offered tips on how to resolve these issues.
For more information about Docker container management, read How to Manage Docker Containers - Best Practices.