Docker Build Checks: Automatically Diagnose and Optimize Dockerfiles Like a Pro

Docker tutorial - IT technology blog
Docker tutorial - IT technology blog

Late-Night Tales: When Your Dockerfile Devours Resources

At 2 AM, the production server triggered an out-of-memory error. To my horror, the newly deployed heavy Docker image was 1.8GB, even though the source code was only 45MB. It turned out a team member forgot to add a .dockerignore file, causing Docker to pull in the heavy node_modules folder and a pile of junk files into the image.

These basic mistakes waste a lot of processing time and storage bandwidth. If only there were a tool to automatically “remind” us right when typing the build command. The good news is that Docker has released Build Checks to solve exactly this problem.

Think of Build Checks as a strict referee. It scrutinizes every line of code in your Dockerfile to ensure you follow Best Practices before you even have a chance to push that mess to the server.

Quick Start: Check Your Dockerfile for Errors in 5 Seconds

If you want to know if your Dockerfile is poorly written, run this command immediately:

docker build --check .

Important note: The --check flag doesn’t actually build an image, so the response is lightning fast. It only scans the structure and lists warnings if you violate optimization rules.

Suppose you have a “naive” Dockerfile like this:

FROM ubuntu:latest
RUN apt-get update
RUN apt-get install -y git
COPY . /app
CMD python /app/main.py

Docker will immediately list the errors: recommending specific tags instead of latest, and requesting you combine RUN commands to reduce the number of layers. Very intuitive and effective.

Why Build Checks is a Game Changer

Previously, we had to install third-party tools like Hadolint to check for errors. Now, Docker has integrated this feature directly into Buildx (from version 0.13). Configuration is now easier than ever.

This mechanism works based on a set of standardized rules from the community. When you run the command, Docker performs linting and matches your code against these rules. If it detects security risks or performance weaknesses, the system displays detailed fix instructions.

In practice, it doesn’t just catch simple syntax errors. Build Checks also detects logical errors, such as forgetting to clear the apt cache after installation, which causes the image to bloat unnecessarily.

4 “Classic” Mistakes Build Checks Will Catch

Here are the mistakes that 90% of Docker beginners make, leading to sub-optimal images:

1. Using the “latest” tag for base images

Rule: StageNameTerminator. Using FROM node:latest is like setting a time bomb. When Node.js updates to a new version, the next build might crash the entire application due to incompatibility. Build Checks will require you to use a fixed version like node:20-alpine.

2. Overusing RUN commands

Each RUN command creates a layer. If you write 5 separate commands, your image carries extra weight. The tool will advise you to use && and \ to combine them into a single layer, helping reduce image size by 20-30%.

3. Forgetting to clean up after installation

When running apt-get install, Docker saves temporary installation files. If you don’t delete them using rm -rf /var/lib/apt/lists/*, the image adds dozens of pointless megabytes. Build Checks is extremely sharp at detecting this omission.

4. Incorrect CMD command format

Rule: JSONArgsRecommended. Writing CMD python app.py (shell form) instead of CMD ["python", "app.py"] (exec form) prevents the container from receiving SIGTERM signals. As a result, the container is “killed” abruptly instead of performing a graceful shutdown.

Advanced: Enforcing “Clean” Code via CI/CD

In real-world projects, not everyone remembers to run --check manually. The definitive solution is to integrate it into CI/CD pipelines like GitHub Actions or GitLab CI.

You can configure the pipeline to automatically fail if the Dockerfile has serious warnings. To force Docker to treat all warnings as errors and stop the build immediately, add this line to the top of your Dockerfile:

# syntax=docker/dockerfile:1
# check=error=true

FROM node:20-alpine
...

Real-World Experience for Image Optimization

After “paying the price” many times in production, I’ve distilled 3 golden rules to combine with Build Checks:

  • Prioritize Multi-stage Builds: Separate the build environment from the runtime environment. Keep only what is absolutely necessary in the final image.
  • Organize command order intelligently: Place commands that change less frequently (environment setup) at the top and frequently changing code at the bottom to maximize Docker Cache usage.
  • Don’t ignore Warnings: Small warnings today can be the reason the system runs slowly or suffers from security vulnerabilities tomorrow.

Applying Docker Build Checks makes your Dockerfiles more professional and provides absolute peace of mind. Try running docker build --check . today—you might be surprised by what you find!

Share: