How to build a minimal JVM container with Docker on Alpine Linux?

duke with logos: docker, Java and alpine linux

There has definitely been an awakening of some kind. Lately we’ve been hearing more and more about Alpine Linux, a lightweight distro that’s rising in popularity mostly because of its Docker use case. A single OverOps support chat a few months back piqued our interest, and since then we see more and more of our users trying it out with their containers. In this post we’ll do a quick overview and walkthrough of Alpine and how you can use it to build lightweight Docker containers with Java or any other JVM language.

Let’s get started.

So what’s Alpine Linux anyway?

Linux Alpine on Google Trends
Alpine Linux on the rise – Google Trends

Alpine Linux is an independent stripped down flavour of Linux that’s based on musl libc (pronounce ‘muscle’) and busybox. Apart from being lightweight, it’s also security oriented and uses grsec/Pax which is a security enhancement to the Linux kernel. Simply having less packages and utilities that are otherwise added by default in other distributions also adds to its security. In addition, Alpine uses its own package manager called apk which is fast and pretty straightforward to use. And Another cool perk is its run-from-RAM feature.

Does image size really matter?

Docker image size
Alpine Linux vs Ubuntu
Alpine vs Ubuntu official Docker images: 1.1M pulls on alpine and 39.3M on ubuntu

Docker is all about minimalism BUT When it comes down to JVMs on Docker, the official Java Docker image would add up to over 800MB. This is a pain even if you’re not disk space sensitive because of two main reasons. The bigger the image size, the longer it takes to: 1. Build it 2. Ship it over the network When you’re dealing with tens and hundreds of containers, or constantly shipping updates, it enhances the negative effects of big image sizes so, yes, it matters. At the same time, an Alpine base image would only take 5MB of space. Here’s a comparison from the gliderlabs/alpine image which serves as the source for the official docker-alpine image: Compared to Ubuntu which is probably the most popular distro for Docker users, that’s over a 37x improvement, saving up 183MB of disk space. With that said, Alpine is not for everyone and requires some digging around depending on your specific use case and the kind of features you’re expecting to get from your OS. If being clean and minimal is one of your biggest concerns, then by all means, you should check it out.

Getting started with Alpine: Check out the Alpine wiki with its practical comparison to other distros.

Super useful on Java

While not specific to Java use cases, using Alpine provides a huge size benefit when used together with a JVM on Docker. The out-of-the-box official java Docker image takes over 800MB, with Alpine, it can go down to 117MB if you’re only including the JRE on Java 8. That’s almost 7 times lighter! As for the actual installation, it depends on which version of Java you’re going for. Since Alpine uses musl libc, we have 2 options: 1. OpenJDK installations work out-off-the-box with musl libc, here’s an example. 2. Oracle HotSpot depends on glibc and requires an additional step. The most popular dockerfiles for Oracle Java were published by frolvlad (9.3K pulls) and anapsix (6.9K pulls), including different configurations for minimal installations including glibc. Here’s one way to add glibc on Alpine:On a sidenote, a nice little trick is viewing docker images through imagelayers.io. Here’s how the Java 8 image from anapsix looks like:

How to Install OverOps on Alpine Linux?

We first heard of Alpine following requests from users who wanted to monitor their JVMs with OverOps. To be able to run OverOps on Alpine we had to include a few more dependencies. Apart from glibc, we also require the zlib compression library, libstdc++ and the low-level runtime library libgcc. Hold on tight! Attached is a Dockerfile that describes all the required steps with comments. You’ll see how to install Java on Alpine with glibc, add the additional dependencies, install OverOps, and monitor a simple Scala server which has a few errors.

Some kind of monster @ OverOps, GDG Haifa lead.
  • Kyle C. Quest

    There are other options if you still want to use a full blown distro (e.g., Ubuntu)… DockerSlim ( http://dockersl.im ) will shrink your fat image. The sample java app image went from 743MB down to 100MB. It’s an open source tool, so any contributions, suggestions or requests are welcome 🙂

  • Vlad Frolov

    I didn’t get one thing. You seem to have noticed `develar/java` and `anapsix/alpine-java` images, which provide Oracle JRE (and you have even found my `frolvlad/alpine-oraclejdk8` for those who needs JDK instead of JRE), but still you reinvent a wheel. Why?! Not only you prevent users from reusing Java layers for their other images, you also use Alpine:3.2 instead of Alpine:3.3, and also haven’t cleaned up glibc packages…

    Why don’t you just use `FROM develar/java` (OR `anapsix/alpine-java` though the author admits that develar’s image is smaller)? At the very least, you could use `frolvlad/alpine-glibc` if you need Java 7, though it seems that OpenJDK 7 is a standard reference for Java 7, so you could just use it from the official Alpine repo (or use `frolvlad/alpine-openjdk7`)

  • Mike Holdsworth

    alpine-java is well conceived. Java 7 & 8 versions. 122mb in size.
    https://github.com/anapsix/docker-alpine-java

  • john stanley

    You shares an information about the learn, mean of the java virtual machine. For more information about the java visit@ java

  • Samuel Gwokuda

    Excellent article….

  • Tony Cox

    Does alpine support Java Script? What is my option if I need to use stripped down version of JRE with support for Java Script?

  • merrill77

    Looks like there is an image missing from this post. Right after “Here’s how the Java 8 image from anapsix looks like:”

    • Henn Idan

      Hey Merrill, thanks for letting us know! We’ve updated the image.