7 Key Considerations for Choosing Container Base Images for Java Apps
- By Dmitry Chuyko, BellSoft
- March 30, 2026

At first glance, choosing the best container base image for a Java application may seem simple enough. Teams tend 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? Because 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 base 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.
The what and why of selecting container base images
Let’s start by defining what a container base image is and which role it plays in application development and deployment.
Defining and using base images
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, JDK dependencies, 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
Why base image selection matters
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 best base image for a given project varies widely depending on the 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.
Beyond base images: Other considerations for optimizing Java apps
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:
- How you create the application: Steps like optimizing your runtime (through tools like jlink), building GraalVM-native apps and optimizing your build system (whether it’s Gradle, Maven or something else) play critical roles in shaping overall application performance.
- How you launch your application: The contents of your Dockerfile or buildpack have important implications for both security and performance. So do considerations like which orchestrator you use (if any) and how it’s configured.
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.
What to consider when selecting a container base image
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 base 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.
Security
29% of developers said security is their top priority when choosing base images. 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 affect a container, the greater the threat actors' chances of breaching it.
That said, minimizing CVE count often means choosing a minimalist base image (since the less code you include in your container, the fewer components can be impacted by CVEs). And as we’ll explain later in this article, minimalism may come at the expense of operational convenience.
Performance
The next most popular factor developers cited when asked how they choose base images is performance. They want images that help ensure their applications start up quickly and are as responsive as possible once running. 21% 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, it could come at the expense of a slower startup. (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 optimized for your specific 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.
Image size
Raw image size — the main consideration for 17% 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 on local storage may be less concerned about storage space because they don’t have to pay a monthly bill. 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 that many developers would look for small base images.
Built-in Java support
17% 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 because the base image lacks or provides limited Java support.
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 consider not only which Java version your image supports, but also the performance implications of its capabilities.
Ease of use and operational efficiency
11% of developers told us they prioritize ease of use and operational efficiency when selecting base images.
Specifically, they consider which tools and utilities are included in base images. 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.
License compliance
An easily overlooked aspect of base image selection is licensing compliance, i.e., whether the software included in an image complies with the various open-source and/or commercial licenses that govern it.
This is important because using software in ways that violate its license terms 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 tend 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 with generic Linux distributions don’t always have clear licensing terms because they include so many components, and 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% 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.
Support and roadmap
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 combines vendor support with open-source software, giving teams the assurance of reliable support without locking them into a commercial technology ecosystem.
Best practices for choosing a “best-of-all-worlds” image
In many cases, the various considerations we just described may seem to be in conflict. A base image that is secure but 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 balances security, performance, and usability. 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:
- Assess image components, not size: Smaller is not always better from a performance, security and licensing compliance perspective. Rather than choosing an image simply because it’s tiny, pay attention to the details of what it actually includes, and what its implications are for performance and security.
- Evaluate upstream security practices: In addition to considering the number of CVEs that affect an image, assess how actively the image’s developers discover and mitigate relevant vulnerabilities. Just because an image has few open CVEs currently doesn’t necessarily mean its vendor will excel at patching new CVEs when they emerge. Sourcing images from projects with a solid track record of CVE mitigation will go a long way toward minimizing security risks, regardless of overall image size or complexity.
- Consider support availability: On a similar note, assess how active an image’s developers are in providing support. If something goes wrong — for example, if you run into a Java compatibility issue or are affected by a zero-day vulnerability — will they help? If so, you’re likely to enjoy a faster, smoother resolution process than you would if you had to sort out issues like these on your own.
- Choose optimized software components: As we mentioned, software optimization can be at least as important a factor in shaping application performance as overall image size. For that reason, look for images whose runtimes and libraries are configured out of the box to optimize performance.
- Don’t overlook licensing: Software licensing may seem like a boring topic, but it’s a critical one from the perspective of the business you work for. Avoid compliance headaches — and the hours spent manually sorting out licensing details — by using images with clear licensing terms.
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.
The views and opinions expressed in this article are those of the author and do not necessarily reflect those of CDOTrends. Image credit: iStockphoto/TU IS
Dmitry Chuyko, BellSoft
Dmitry Chuyko is a performance architect at BellSoft.