Moving to Ubuntu for our Docker image

Will Ezell

Since first providing dotCMS containers, we have used Alpine linux as the base image for our docker builds.  As of 21.07 and the upcoming 21.06 (LTS) versions, we are moving away from the Alpine base image and moving to use Ubuntu’s 20.04 LTS as our base image. 

Why did we choose to move away from Alpine?  

  1. Alpine uses non-standard C libraries and makes innovation hard.  Unlike other linux distros, Alpine linux is based on musl and ships muslc for its c libraries.  While musl is smaller (and arguably cleaner) than the standard glibc libraries, glibc is much more common, well tested and used by RedHat, Ubuntu, Debian.  Because Alpine is built on an uncommon c library, many packages and libraries are not available via apk, their package manager and need to be compiled specifically for Alpine in order to be used. Dealing with Alpine’s packaging issues is a time consuming process.  See this article entitled “Using Alpine can make Python Docker builds 50× slower” on the pitfalls of using Alpine linux with Python. Here at dotCMS, we have come across a number of hard to solve issues with Alpine numerous times, including with our sass and webp support. Turns out that Alpine, while “cleaner” can make developing harder.

  2. Alpine locks us into specific Java builds and versions.  Ever since it was open-sourced by Oracle in 2018, Java is changing, innovating and improving very quickly. There are many JVM versions and builds available that include important new features and enterprise capabilities. Unfortunately, Alpine locks us into a very limited number of pre-packaged Java versions and if we want to try any new and unsupported version, we have to compile it on your own.  For example, when we were delivering our first  dotCMS image with Java 11, we intended to run a flavor of Java 11 which included the low pause GC algo “Shenandoah”.  It turned out that the Alpine Java 11 build that included Shenandoah was unavailable for Alpine.  Additionally, because Alpine uses musl rather than glibc, we were unable to find a downloadable Java 11 version that would run on Alpine.  We were forced to use the Java version that is delivered via apk - Alpine’s packaging system.

  3. Alpine is not much smaller than its glibc counterparts.  Once you add any needed packages, an Alpine linux image is as big as the more mainstream distros.  In our case, our Alpine image was almost twice the size of our newer ubuntu based image.  This is because with Ubuntu we can limit what parts of Java we include in the build rather than relying on Alpine’s APK packages.

  4. Alpine is less secure.  The mainstream linux distros (Redhat, Ubuntu, etc) are run by nearly every large company and organization in the world.  They have in-house dedicated security teams, 10 year security SLAs and receive an untold amount of security research, hardening and testing. The Alpine distro is maintained through a community process, it has a ~2 year lifecycle and does not receive anywhere near the same amount of security scrutiny. This is especially true for the community supported packages. This means that on paper, Alpine linux looks more secure than other distros, while in reality it is just another form of security through obscurity.  If you install any of the surrounding packages, Alpine linux is just less tested and supported, particularly if you account for the similar attack surfaces of the required packages you install..   

This is a great article that To see the comparison between multiple distributions for use as a base container read this great article. 

Why not distroless?  

Distroless containers are basically like running a major distro with the package manager removed.  They offer a reduced attack surface which is good, but working with them brings some of the same pitfalls as Alpine.  They are difficult to create, difficult to maintain and can slow down innovation and developmental agility.  We might explore distroless containers in the future but for now, we believe that a Ubuntu’s 20.04 LTS base image is the right balance for dotCMS between security, agility and container size.

Why Ubuntu?  

When looking at the many base image options we chose to use Ubuntu LTS. Ubuntu is a commercially-backed industry leading distro with a 5 year security lifecycle (10 years paid) on its LTS versions. Ubuntu has an in-house security team that provides many 0-day security patches and does not rely solely on a faceless community process or volunteers to provide its security. Read more about Ubuntu and security here).

Redhat distros like Fedora or RedHat'sUniversal Base Image are other good and common options, though over the years I have been burned a few times by RedHat as they work through opensource/commercial concerns.  I've seen RedHat drop support for distros and projects on a whim which can leave projects relying on them out in the cold (RIP Redhat Linux and CentOS).  Also, even though Ubuntu as a whole is larger than Alpine it is smaller than the Redhat distros while still utilizing common linux libraries.  Overall Ubuntu was the right compromise for dotCMS between security, space, performance and ease of use.

Image Credit: CloudBooklet (
Will Ezell
Chief Technology Officer
July 30, 2021

Recommended Reading

Mastering the New Universal Visual Editor in dotCMS: A Technical Deep Dive for Developers

Explore dotCMS's Universal Visual Editor, merging WYSIWYG simplicity with headless CMS flexibility. This tool offers drag-and-drop editing, inline content editing, and NoCode tooling for seamless omni...

Benefits of a Multi-Tenant CMS and Why Global Brands Need to Consolidate

Maintaining or achieving a global presence requires effective use of resources, time and money. Single-tenant CMS solutions were once the go-to choices for enterprises to reach out to different market...

Headless CMS vs Hybrid CMS: How dotCMS Goes Beyond Headless

What’s the difference between a headless CMS and a hybrid CMS, and which one is best suited for an enterprise?