When deploying your next Java app, don’t choose base images based on simple metrics like total size or total CVE count. Instead, assess the full picture by considering how an image’s security, performance, usability, and support capabilities add up to make your app the best it can be.

At first glance, choosing the best container base image for a Java application may seem simple enough. Teams have a tendency to approach the issue by optimizing layer-by-layer: They choose the smallest base image for efficiency, pick a reputable JDK distribution, apply Java-level optimizations for performance, and harden the image for security.
On paper, this strategy might seem like the best way to create a base image that maximizes security, performance, and usability. But in reality, it often results in images that are less than the sum of their parts.
Why? Optimal performance, security, and cost efficiency don’t come from assembling the best individual pieces. They occur when all container components work together seamlessly as an integrated system – and that type of synergy is nearly impossible to achieve when your OS, runtime, and tooling come from different sources, and focus on distinct and siloed goals.
Hence, the importance of thinking in a holistic, integrated fashion about container-based image sourcing. Read on for a deep and practical guide into the many considerations to weigh, along with actionable tips on selecting the ideal container base image for your Java app.
Let’s start by defining what a container-based image is and which role it plays in application development and deployment.
A container base image is the core code that developers use to create a containerized application. Base images for Java apps typically include operating system components, dependencies for the JDK, various utilities, and the JDK itself. You can build on top of these to create the custom container environment your app needs to run.
To select a base image, you specify its name when creating a Dockerfile. For example, to start with a base image built using Alpine Linux and the Liberica JDK, you’d include a line like this in the Dockerfile:
FROM docker pull bellsoft/liberica-openjdk-alpine:25
See also: 6 Proven Day-2 Strategies for Scaling Kubernetes
Virtually all base images do the same basic thing: They provide a foundation for creating a containerized app.
That said, the code and utilities included in base images can vary widely. Some base images provide full-fledged operating systems with almost as many programs and utilities as you’d find in a desktop version of Linux. This is generally a good thing if your application actually needs all that code. It saves you from having to add it yourself.
Other base images are extremely minimalist and don’t even include a shell or package manager. This can be advantageous for scenarios where application performance, resource utilization optimization, and security are key priorities.
And then, of course, there are base images that fall somewhere in between – ones that include, for example, a Java runtime along with a shell, but not a package manager.
The type of base image that is best for a given project varies widely depending on which type of application you’re deploying and what it needs to do. We’ll walk through the key considerations to weigh when selecting a base image in the next section. But for now, the takeaway is that base images are not interchangeable, and it’s an extremely poor idea to default to using whichever base image is most popular, most familiar, or the most readily available. If you do, you’re likely to end up with an application that falls short in the realms of performance, security, and beyond.
See also: Cloud-Native HA and Kubernetes-driven DR
Of course, the base image you select isn’t the sole factor in shaping the performance, security, and usability of a Java app. Also important are:
Thus, it’s crucial to think not just about how inherently optimized your base image is, but also how well it supports optimizations at later stages of the development process. For instance, if the image lacks the tooling to enable an optimized JRE, you’re likely to achieve lower overall application performance, even if the base image itself is “performance-optimized” in the sense that it includes no unnecessary components.
Now that we’ve walked through the role that base images play in Java application optimization, let’s dive into key considerations for choosing a base image.
To get a sense of what development teams should think about when choosing container-based images, my company surveyed nearly 500 actual developers. The following are what they said they prioritize when comparing base image options, along with context on why each consideration matters and how to optimize it for your Java project.
29 percent of developers said their top priority when choosing base images is security. Specifically, they look for images that have the fewest number of known Common Vulnerabilities and Exposures (CVEs), which document known security flaws in software.
This makes sense because no one wants their app to be hacked, and the more CVEs that affect a container, the more chances threat actors have to breach it.
That said, minimizing CVE count also often means choosing a minimalist base image (since the less code you include in your container, the fewer components you’ll have that can be impacted by CVEs). And as we’ll explain later in this article, minimalism may come at the expense of operational convenience.
The next most-popular factor that developers cited when asked how they choose base images is performance. They want images that will help ensure their applications start up quickly and are as responsive as possible once they are running. 21 percent of developers named performance as their top consideration.
The default strategy here is usually to focus on a base image that is as minimalist as possible. But that’s not actually always the best approach. For example, while a stripped-down image might have a small disk and memory footprint, this could come at the expense of a slower startup process. (Indeed, part of the reason why my team created Alpaquita Linux was to solve startup delays in Alpine Linux that stemmed from this very issue.)
It’s also important to select base images that include code that is optimized for your particular use case. For example, when deploying a Java app, you’re likely to achieve better performance if you use a base image that includes a Java runtime that has been tuned to maximize performance in a containerized environment, as opposed to using the Java that ships with more generic base images.
Raw image size – the main consideration for 17 percent of developers we surveyed – is also an understandable factor to weigh. Larger images take up more storage space and generate more network traffic, which can, in turn, lead to higher cloud bills (if you store images in the cloud).
Large images also take longer to download, which can delay the application deployment and provisioning process if you’re deploying an app using Docker or Kubernetes and you need to pull its image from a remote repository first.
An important nuance to bear in mind, however, is that large images are not always a challenge. Teams that run their own image repositories using local storage may not be as worried about storage space because they don’t have to pay a monthly bill for it. Plus, if you’re pulling an image over the local network, it generally will be much faster than pulling one via the Internet.
But local repositories tend to be the exception, not the norm, so it makes sense why many developers would look for base images that are small in size.
17 percent of developers also reported that their main consideration is how well a base image supports Java.
If you’re a Java developer, you can probably understand why. Java apps can be particularly complex to develop and deploy due to the diversity of Java runtimes and versions. It’s a real hassle – not to mention a potential security risk – to have to create or modify a container image’s Java environment due to limited or non-existent Java support in the base image.
To address this challenge, it helps to choose a base image that supports optimization tooling like CRaC and GraalVM, which can help reduce startup time to almost zero. This is another example of why it’s important to think about not only which type of Java your image supports, but also what the performance implications of its Java capabilities are.
11 percent of developers told us they prioritize ease of use and operational efficiency when selecting base images.
Specifically, they consider which tools and utilities base images include. Minimalist images may help with performance and security, as we mentioned, but their drawbacks can outweigh their benefits if the images are so bare-bones that they lack key utilities such as a shell and package manager. In that case, it becomes very difficult to run commands or add software.
Hence, the importance of choosing a base image that balances ease of use on the one hand with performance and security on the other. Selecting images that include utilities you don’t need is a bad idea, but so is being so minimalist that you make your life as a developer harder than it needs to be. You already have a lot on your plate, and figuring out how to do things like add a shell to a “blank” container image need not be one of them.
An easily overlooked aspect of base image selection is licensing compliance, meaning whether the software included in an image conforms with the various open source and/or commercial licenses that govern it.
This is important because using software in ways that violate licenses can lead to compliance risks and lawsuits. Plus, researching licensing details can be a time-consuming and frustrating endeavor for developers. This is especially true in the Java ecosystem, where Oracle’s complex licensing terms have a tendency to change unpredictably.
To avoid licensing compliance issues, it’s best practice to choose base images with clear-cut licensing terms. We’re talking here not just about the license for the operating system that the image uses, but also for the various individual runtimes, tools, and so on within it.
Base images created using generic Linux distributions don’t always have clear licensing terms because they include so many components that the projects that develop them rarely take the time to research or guarantee licensing compliance. But base images do exist that include clear and specific software licensing details.
Only 4 percent of the developers we surveyed said that licensing compliance is their top consideration when evaluating base image options. We can hope, however, that for many of those who didn’t say that licensing is their number-one concern, it’s still something they pay attention to.
For most Java development teams, the work doesn’t start when an app has been deployed. It continues indefinitely as developers update and redeploy the app.
For this reason, it’s important to consider the support and roadmap outlook for your base image. Ideally, you’ll select an image that is maintained by an established vendor, which – unlike community projects – is not likely to abandon an image that you depend on to run your apps. Also important to weigh is whether the image includes proprietary tooling, which could create lock-in risks.
A “best of both worlds” solution is one that combines vendor support with open source software, giving teams the assurance of reliable support without locking them into a commercial technology ecosystem.
See also: Best Practices for Balancing Container Security with Operational Efficiency
In many cases, the various considerations we just described may seem to be in conflict. A base image that is secure because it is minimalist may come at the expense of a positive developer experience, for example.
But as we said in the introduction, the key to resolving these tensions is to choose a base image generated through a holistic process that considers security, performance, and usability in equal measure. When you source images from projects or vendors that specialize in all of these areas, you avoid the pitfalls that would arise if you chose disparate components, each optimized in isolation for a different priority.
To be more specific, a “best-of-all-worlds” experience comes when your base image strategy is guided by the following principles:
The bottom line: When deploying your next Java app, don’t choose base images based on simple metrics like total size or total CVE count. Instead, assess the full picture by considering how an image’s security, performance, usability, and support capabilities add up to make your app the best it can be.
Dmitry Chuyko is a Performance Architect at BellSoft.
Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved
Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.