The cloud native community has developed an almost religious devotion to slim container images. The reasoning seems sound enough: fewer packages mean a smaller attack surface, which translates to better security. But like most orthodoxies, this one deserves some scrutiny. What if our collective obsession with minimal images is causing us to overlook certain benefits of fatter images?
In my previous post, I showed you how to create an inline buildpack that live directly in your application repository. We created a Python buildpack that bundles uv for dependency installation, eliminating the need to maintain a separate buildpack repository.
Do you know who’s maintaining your critical open source infrastructure? That project with a fancy logo could be one corporate re-org away from disaster.
Using buildpacks can be as easy as dropping a project.toml into your app, and adding some custom build logic. But unlike a Dockerfile, the resulting image can benefit from powerful features like rebase and advanced caching.
The key to removing the friction in a developer experience is meeting developers where they are, which we can do by following just a few rules as we design our software tools.
If you already have the Pack CLI installed, you can create a Docker image for any Java, Node.js, Python, or Ruby app (without a Dockerfile) by running:
You can’t teach an old dog new tricks, but you can wrap it in an API compatibility layer. In this post, you’ll learn how to use older versions of Heroku Buildpacks with the Pack CLI by wrapping them in a Cloud Native Buildpack shim that’s as easy as:
Spring Boot 2.3.0 introduced a new feature you can use to package your app into a Docker image with Cloud Native Buildpacks (CNB). In this post, you’ll learn how to use this mechanism with Heroku buildpacks to create an image you can run on any cloud platform.
Choosing a Java runtime to install has become… interesting. Simon Ritter of Azul and Matt Raible of Okta have done great write-ups on how to select the right JDK, and in this post you’ll learn how to use a few of those options on Heroku.
Java libraries that invoke native code (i.e. code written in C/C++ and compiled for a specific platform) via the Java Native Interface (JNI) can allocate memory that is nearly invisible to standard JVM monitoring tools. This creates the potential for very mysterious memory leaks because JNI does not automatically garbage collect or track the non-JVM memory resources allocated on the native side.