Docker Container Image Security: 13 Best Practices

 

Transcript:

In this video, we will discuss the best practices for securing Docker container images. How can we reduce the risk of attacks on our Docker container images? The short answer is by reducing the attack surface and time spent on detecting the malicious activity. Yeah, but how to do that? Watch and find out.

Keep your container images lean and boring. The smaller the attack surface in your production image, the better. Therefore, try to minimize the number of components that represent a potentially exploitable path. Depending on your application, consider using a minimalistic Linux distro, a distloress image, or even a scratch. Use multi-stage to transfer the app into a final base image. The final image should contain the immutable set of components required for your application to run. No package manager if possible. A package manager in production kills immutability and widens the attack surface. Attackers can use the package manager to install malicious packages with the vulnerabilities. Therefore, if your use case allows to do so, try to use slimbased images without a package manager. Non route and minimum privileges. Running the container as root or giving it a full set of privileges will give the intruders a host level access to container resources and the ability to exercise kernel attacks. So set the unprivileged user and group in the docker file to run the container. Also, if possible, try to avoid using the privileged flag in production because it gives all Linux kernel capabilities to the container. Instead, limit the granted privileges only to those needed by the container. You can first run cap drop all just to be sure and then add the required privileges with the cap at.

Strive towards immutability when possible. Immutability means that the container must correspond to the container image. It means no config tweaks, uh no changes in the privileges, no patches or fixes in the production. If something changes, you rebuild and redeploy the artifact. The key approach to more secure containers in this regard is to use base images with only the essential set of components required by your application and it should be immutable. Also, there shouldn't be any package manager and uh no privilege escalation. Also, you can use the runtime settings like uh tmpfs or mount to store the data outside the container. You can prevent the privilege escalation at runtime by using the security opt no new privileges option. You can also use the readonly flag to run the container with the readonly file system if it fits your use case. Aim for deterministic container images. Deterministic means that given the same input, the build produces the exact same bites. This way you can detect tempering or dependency change between the build runs. Pin everything to achieve determinism tool chain build system OS version. Also pin the base image by digest not by tag because tags can drift. But the digest always points to the image that you used in the first place.

Use SBOMs. A software bill of materials or an SBOM gives you a list of what's inside your image. Direct and indirect dependencies, their versions, licenses, and so on. SBOMS accelerate CV remediation because you can match a new CVE to the affected image. Generate an SBOMB with every image and store it alongside the image digest. There are several open-source tools for generating sbombs. For instance, sift or cyclonx generator. You can generate an SBOM at the pre-built stage to check the dependency state. But generating an sbomb at the build stage is a must because this way you get the list of exactly what you ship and run.

Integrate provenence. Provenence proves where this image came from by providing the metadata about where, when, and how this image was built. It is metadata that software consumers can verify independently of uh software producers. The important part of provenence is software attestation. You can use cosign for that. So you sign the artifact and the software consumer then verifies the signature and the required station in their CI/CD. Other provenence processes and tools are described in the supply chain levels for software artifacts framework or salsa for short. Drop me a comment if you want a separate video on that. Kow do-it-yourself base images. Quite a few teams build their images on some random base which can be poorly maintained, infected with CVS, lacking SBOMs, and just inviting malicious actors. So opt for a well-maintained regularly updated base image from a trusted vendor. The images should come with an SBOMB and should be easily verified by the check samp for instance instead of uh Alpine Linux with only the community support. You can use alpakita Linux with LTS releases and SLA for patches from bellsoft. Use LTS versions if possible. Consider using base images with LTS software versions. LTS releases are supported for several years. Plus, they have clearly defined security updates policies. For instance, NOJS LTS versions are released every year and receive security patches and critical fixes for 2 and 1/2 years. Java LTS versions are released every 2 years. And the support period depends on the JDK vendor. It varies from 3 years to more than seven years. As for the operating systems, Ubuntu LTS versions are released every two years and receive security patches for 5 years. Alpaquita LTS versions come out every 2 years and receive security patches for 4 years. Update base image regularly. If you don't update the base image, you accumulate nonvulnerabilities and extend the attack surface. Reliable vendors update their images constantly. But when a vendor releases an updated version of their image, your builds won't be updated automatically. So set up automatic uh updates monitoring using tools like dependabot and renovate. This way you can promptly rebuild, rescan and resign the container image.

No secrets in containers. Secrets baked into the image are a serious security risk. Use a dedicated secrets management tools like hash corp worlds, Google secrets manager or kubernetes secrets. You can store your secrets there and then patch them at runtime. Use security scanners. Security scanners are tools that analyze the software environments for security flaws. Scanners vary in purpose. They can scan dependencies, configs, sbombs, container images. They can search for CVS, secrecy, and configs. They can scan the source code for security weaknesses or even monitor the malicious activity. So you can use them at different stages of software development life cycle. You should also define policies for acting upon the scanning results. For instance, you can block or allow the build or deploy, create an additional artifact, perform a manual review and so on. Implement host hardening. Containers share the host kernel. So if the host is vulnerable, everything on it is vulnerable. You can use a dedicated OS for Kubernetes nodes such as Bottle Rock or a minimalistic OS such as Alpakita LTS. The key is that the system must be immutable and without any unnecessary components. Update the kernel on a regular basis plus enable Linux security modules to set the required security policies. Okay, I know this whole info may seem overwhelming. So, if you want to learn more about these approaches, I have written a dedicated article with a more detailed description of each approach and code samples. The link is in the description.

 

Summary

This video shows how to build a complete UI for a Spring Boot application using Vaadin, a Java web framework that provides rich, customizable UI components entirely in Java. The guide walks through creating a login page, a main layout with navigation, and a data grid that supports filtering, lazy loading, and detailed dialogs. It also demonstrates how to build a multi-tab dialog with read-only details and an admin-only edit form using Vaadin Binder for validation and data binding. The video explains how to integrate Spring Security, handle database data from MongoDB, and build responsive layouts. Finally, it shows how to apply a custom cyberpunk theme and encourages exploring Vaadin’s broader capabilities.

About Catherine

Java developer passionate about Spring Boot. Writer. Developer Advocate at BellSoft

Social Media

Videos
card image
Oct 7, 2025
Master Java Profiling in 2025: Tools, Techniques, and Real-World Tips

In this complete guide to Java profiling, you will learn sampling and instrumentation techniques, compare the 7 best tools (JFR, VisualVM, Async Profiler, JProfiler, YourKit, Digma.ai, New Relic), and master how to detect memory leaks and analyze CPU usage.

Videos
card image
Sep 25, 2025
Should You Still Use LOMBOK in 2025?

Have you ever wondered how @Data, @Builder, and @Getter actually work? Lombok doesn’t just generate code — it rewrites your AST during compilation using internal, unofficial APIs. And while many developers enjoy the reduced boilerplate, few realize the hidden risks behind it.

Further watching

Videos
card image
Oct 31, 2025
Vaadin Tutorial: From Spring Boot to Beautiful UI Fast

In this guide, I’ll show you how to build a fully functional Java application with authentication, data tables, filters, and a custom cyberpunk theme using Vaadin.

Videos
card image
Oct 23, 2025
Top 7 JavaFX Testing Mistakes You Need To Avoid!

Stop making these common JavaFX testing mistakes! No more random NullPointerExceptions or deadlocks — in this video, we’ll show you how to fix the 7 most frequent TestFX issues when testing JavaFX applications. Learn how to work with FX threads, integrate with Spring Boot, avoid event-queue race conditions, handle pixel-level test differences, set up headless continuous integration with Monocle, and properly separate business logic from UI tests.

Videos
card image
Oct 16, 2025
All 7 Java Garbage Collectors Explained

In this complete guide to Java garbage collection, you will learn how the JVM memory model works, understand the differences between the Serial, Parallel, G1, ZGC, Shenandoah, CMS, and Epsilon collectors, and determine which garbage collector is best suited for your application's performance — from single-threaded programs to massive terabyte-scale heaps.