paketo-buildpacks / bellsoft-liberica

A Cloud Native Buildpack that provides the Bellsoft Liberica implementations of JREs and JDKs
Apache License 2.0
75 stars 18 forks source link

Support for JVM-based apps using musl based JVM & the static stack #442

Open ofirm93 opened 1 year ago

ofirm93 commented 1 year ago

Our team is willing to use buildpacks to build our docker images which requires using Alpine for security reasons. Current bellsoft-liberica buildpack (and actually any other java distro buildpack) doesn't support Alpine, due to use of JRE and JDK which depend on libc. Alpine uses musl as an alternative to libc.

Describe the Enhancement

I would like that out-of-the-box liberica buildpack will support Alpine OS. Example usage could be, using Springboot gradle plugin to build Springboot images which are based on Alpine instead of Ubuntu. If needed we can configure the decision of libc/musl using environment variable such as BP_JAVA_MUSL.

Possible Solution

I tested locally and seems like it can be enough to add the java distro based on musl as an additional metadata.dependencies block in buildpack.toml file. It is not very clear to me how the decision of the dependency is done, but we can add the above mentioned env var if needed.

Motivation

As mentioned before, we use Alpine for security reasons. Alpine's attack surface is considered much narrower than Ubuntu or other Linux disros and it is one of the most commonly used OS in cloud services due to it's very small image size. Using Alpine to run java applications can be very useful to people who wish to run many containers as it requires less storage and it is considered very lightweight.

dmikusa commented 1 year ago

As mentioned before, we use Alpine for security reasons. Alpine's attack surface is considered much narrower than Ubuntu or other Linux disros and it is one of the most commonly used OS in cloud services due to it's very small image size. Using Alpine to run java applications can be very useful to people who wish to run many containers as it requires less storage and it is considered very lightweight.

The good news is that we have that, and the Java buildpacks already work in that environment. It's just not based on Alpine.

If you build using the Paketo tiny buildpacks, you'll get a base image that is less than 20M and has virtually everything stripped out, including the shell (list of packages here). You can try it by setting --builder paketobuildpacks/builder-jammy-tiny when you pack build.

Additionally, we are working on support for a static base image which is even smaller. Our initial target for that was native-image applications, but perhaps we could get that to work with JVM-based applications assuming that we can get JVMs compiled to run in that type of environment.

As far as official Alpine support, the Java buildpacks couldn't support that until the Paketo stacks & builder teams do. Those are the layers on which the buildpacks all run so it would have to happen there first. You can reach out to those teams on our discussion board.

I'll leave this issue open as a feature request to see if we can run JVM-based apps on the static base image.

ofirm93 commented 1 year ago

@dmikusa as I played with the builder and lifecycle projects I think they are not limited for Ubuntu only. The single change I had to make in my project is use a customized buildpack from this repo which imports a different liberica artifact. The builder & stack project only require I'll set a label on the base image to be the buildpack id for jammy/bionic stack id, then they run on a different OS like Alpine - which is a bit hacky but works.

Also, adding the option I mentioned above has no impact at all on the entire stack, neither implies that you formally support Alpine for other buildpacks languages. It only maps the option to request a different dependency.

ofirm93 commented 1 year ago

@dmikusa may I get your comment on that?

dmikusa commented 1 year ago

as I played with the builder and lifecycle projects I think they are not limited for Ubuntu only.

Correct. The CNB project defines the general concept of builders and publishes the lifecycle. They are generic across many things.

The Paketo project publishes a specific set of buildpacks & builders. These are based around Ubuntu, presently Jammy.

The single change I had to make in my project is use a customized buildpack from this repo which imports a different liberica artifact.

Yes, that sounds about right. We really can't at this point support all of the Bellsoft artifacts in the buildpack, because adding dependencies has maintenance cost as well as impact on the size of offline builds. We are planning some work in the near future to change how we handle dependencies and after that, it should be trivial to support way more offerings, including more versions, architectures, and distributions.

For now, we need to really keep things focused on the Paketo offering, which targets Ubuntu. As you've discovered, it is pretty easy to modify the deps in buildpack.toml & repackage your buildpack with different dependencies. It doesn't even require a fork. I would suggest this route if you want/need different versions of the dependencies.

The builder & stack project only require I'll set a label on the base image to be the buildpack id for jammy/bionic stack id, then they run on a different OS like Alpine - which is a bit hacky but works.

You're talking about publishing your own custom stack/builder? If so yes, that makes sense for Java because the JVM doesn't have many system requirements. With other language families, your milage may vary.

Also, adding the option I mentioned above has no impact at all on the entire stack, neither implies that you formally support Alpine for other buildpacks languages.

This goes back to what I mentioned before. Adding more dependencies does presently have impact, but we're working on changing that. See this RFC if you're curious.

ofirm93 commented 1 year ago

Got it. I guess we'll have to build our own. Thank for the reply.