While many developers are well-versed in the fundamental aspects of Docker, such as building images and creating containers, several lesser-known features hold immense value in the deployment process.
Recently, I delved deeper into Docker’s capabilities and discovered some additional important and useful facets. Some of these features may prove beneficial during deployment, while others simply serve as good-to-know pieces of information.
In this article, we will explore some advanced Docker features and facts that transcend the basics, offering the potential to enhance application performance significantly.
Let’s dive into the world of Docker 🐋 to uncover these important insights.
Unknown but small habits can change your life in a bigger way. For example, Cleanliness follows when things are put back in their place after use. Build your habits with Justly today.
Docker is a platform that enables developers to automate the deployment and management of applications within lightweight, isolated containers. Containers only include necessary dependencies, configurations, and library files required to run an application.
Docker provides a consistent and efficient way to build, distribute, and run applications across different environments. It provides many features like Multi-stage builds, Content trust, and Compose profiling which can be helpful to us when building the applications.
Let’s see all of them one by one.
When building a docker image, the docker system needs multiple files to build the final output. To build an efficient Docker image, sometimes we want to eliminate some of those files in the final build.
You can achieve the above scenario by using a multi-stage build process.
Multi-stage builds allow you to create intermediate images(In the below example, builder
stage) during the Docker build process.
These intermediate images can be used to compile code, build dependencies, and generate artifacts, which are then copied into the final image. This helps optimize the size of the final image by excluding unnecessary build tools and artifacts.
For the multi-stage build, the Dockerfile should contain multiple FROM statements. Each of these FROM statements can COPY the artifacts from the previous stage.
The build stage is named by appending AS “build_stage_name”
.
Example
# Stage 1: Build assets
FROM node:21 as builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2: Final image, will copy artifacts from builder
FROM nginx:1.21
COPY --from=builder /app/build /usr/share/nginx/html
Advantage
Docker BuildKit is an improved docker backend that has enhanced build capabilities, improved performance, storage management, and some additional features like Parallelize build, Skip executing unused build stages, Transferring only the changed files, and many more…
It’s available in Docker version 18.09 and later and comes as the default builder from version 23.0.
Example
We can enable/disable it using the following command in the older versions.
DOCKER_BUILDKIT=1 docker build -t newApp:latest .
Advantage
This enables us to manage various application environments using a single compose file. It allows us to define different sets of services and configurations within the same compose file.
We can easily switch between different environments or deployment scenarios without duplicating compose files.
Example
Consider a web application that requires both staging
and production
environments with the same configuration but different database versions.
Here’s the solution to this using profiles:
version: '3.9'
services:
db:
image: postgres:15
# Production profile
profiles:
- production
db:
image: postgres:13
# Staging profile
profiles:
- development
profiles:
development:
variables:
- NODE_ENV=development
- DB_HOST=dev_db
production:
variables:
- NODE_ENV=production
- DB_HOST=prod_db
We can run this with,
docker compose up --profile=development
Advantage
In today’s world of digitalization, security is the most necessary feature for any type of data. The same thing also can apply to docker images. We use the docker engine to push or pull data from public or private registries.
Docker Content Trust (DCT) provides the ability to use digital signatures for data sent to and received from remote Docker registries. These signatures allow client-side or runtime verification of the integrity and publisher of specific image tags.
Using DCT, the Publisher can sign their docker images, and the Consumer can use those signed images without worrying about security.
Example
Publishers can follow the Sign docker image with DCT steps to generate signed images.
Consumers can use only signed images if DCT is enabled in their docker system. DCT can be enabled using the following command.
export DOCKER_CONTENT_TRUST=1
// or
docker pull node:20 --disable-content-trust=false
Advantage
SBOM (Software Bill of Materials) is a document that provides a detailed inventory of the components and dependencies used in a software application.
In the case of docker, it includes details of the given image like operating system packages and other dependencies. It also includes a subset of this information or even more details, like the versions of components and their source.
Example
The below command is used to see the software details of any docker image
docker sbom image:tag
You can get detailed information on docker SBOM.
Advantage
Docker provides an official Go SDK called docker/docker that allows developers to interact with the Docker Engine API programmatically using Go.
The SDK provides a set of Go packages that simplify tasks such as creating, managing, and monitoring Docker containers, images, networks, and volumes.
Note: Docker has unofficial SDKs for other languages too.
Example
Prerequisites: Configure the docker server URL using the
DOCKER_HOST
env variable. You can learn more about docker env variables here.
package main
import (
"context"
"fmt"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
)
func main() {
// Create a new Docker client
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
panic(err)
}
// List running containers
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true})
if err != nil {
panic(err)
}
// Print container details
for _, container := range containers {
fmt.Printf("Container ID: %s\n", container.ID)
fmt.Println("-------------------")
}
}
The above code is similar to the docker ps command.
Advantage
The latest features in Docker, such as
further, enhance the platform’s capabilities and provide developers with powerful tools to streamline their workflows, improve performance, enhance security, and seamlessly integrate Docker into their applications.
We’re Grateful to have you with us on this journey!
Suggestions and feedback are more than welcome!
Please reach us at Canopas Twitter handle @canopas_eng with your content or feedback. Your input enriches our content and fuels our motivation to create more valuable and informative articles for you.
That’s it for today. Keep exploring for the best. 👐
Whether you need...