A holistic approach to container base image selection can unlock better security, performance and operational efficiency for Java applications, says Dmitry Chuyko, Performance Architect, BellSoft.
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 optimising layer-by-layer: they choose the smallest base image for efficiency, pick a reputable JDK distribution, apply Java-level optimisations for performance and harden the image for security.
On paper, this strategy might seem like the best way to create a base image that maximises 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 do not 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 containerised 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 would 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 containerised 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 would 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 do not even include a shell or package manager. This can be advantageous for scenarios where application performance, resource utilisation optimisation 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 are deploying and what it needs to do. We will 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 is an extremely poor idea to default to using whichever base image is most popular, most familiar or most readily available. If you do, you are likely to end up with an application that falls short in the realms of performance, security and beyond.
Beyond base images: Other considerations for optimising Java apps
Of course, the base image you select is not the sole factor in shaping the performance, security and usability of a Java app. Also important are:
- How you create the application: Steps like optimising your runtime through tools like jlink, building GraalVM-native apps and optimising your build system, whether it is 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 is configured.
Thus, it is crucial to think not just about how inherently optimised your base image is, but also how well it supports optimisations at later stages of the development process. For instance, if the image lacks the tooling to enable an optimised JRE, you are likely to achieve lower overall application performance, even if the base image itself is ‘performance-optimised’ in the sense that it includes no unnecessary components.
What to consider when selecting a container base image
Now that we have walked through the role that base images play in Java application optimisation, let us 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 prioritise when comparing base image options, along with context on why each consideration matters and how to optimise it for your Java project.
Security
Twenty-nine per cent 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, minimising CVE count often means choosing a minimalist base image since the less code you include in your container, the fewer components you will have that can be impacted by CVEs. As we will explain later in this article, minimalism may come at the expense of operational convenience.
Performance
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 is not 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 is also important to select base images that include code that is optimised for your particular use case. For example, when deploying a Java app, you are likely to achieve better performance if you use a base image that includes a Java runtime that has been tuned to maximise performance in a containerised 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 are 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 do not have to pay a monthly bill for it. Plus, if you are 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.
Built-in Java support
Seventeen percent of developers also reported that their main consideration is how well a base image supports Java.
If you are 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 is 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 optimisation tooling like CRaC and GraalVM, which can help reduce startup time to almost zero. This is another example of why it is important to think about not only which type of Java your image supports, but also what the performance implications of its Java capabilities are.
Ease of use and operational efficiency
Eleven per cent of developers told us they prioritise 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 do not 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, 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 endeavour 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 is best practice to choose base images with clear-cut licensing terms. We are 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 do not 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% of 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 did not say that licensing is their number one concern, it is still something they pay attention to.
Support and roadmap
For most Java development teams, the work does not start when an app has been deployed. It continues indefinitely as developers update and redeploy the app.
For this reason, it is important to consider the support and roadmap outlook for your base image. Ideally, you will 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.
Best practices for choosing a ‘best-of-all-worlds’ image
In many cases, the various considerations we have 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 specialise in all of these areas, you avoid the pitfalls that would arise if you chose disparate components, each optimised 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 is tiny, pay attention to the details of what it actually includes and what their implications are for performance and security.
Evaluate upstream security practices: In addition to considering how many CVEs impact an image, assess how active the image’s developers are in discovering and mitigating relevant vulnerabilities. Just because an image has few open CVEs currently does not necessarily mean the image’s vendor will excel in patching new CVEs when they emerge. Sourcing images from projects with a solid track record of CVE mitigation will go far in minimising 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 zero-day vulnerability, will they help? If so, you are likely to enjoy a faster, smoother resolution process than you would if you have to sort out issues like these on your own.
Choose optimised software components: As we mentioned, software optimisation 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 optimise performance.
Do not overlook licensing: Software licensing may seem like a boring topic, but it is a critical one from the perspective of the business you work for. Avoid compliance headaches and having to spend hours sorting out licensing details manually, by using images with clear licensing terms.
The bottom line: When deploying your next Java app, do not 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.

