loading...

Moving away from Alpine

asyazwan profile image Ahmad Syazwan ・3 min read

When container movement started getting a lot of traction thanks to docker, there was a real demand for lightweight base image that is optimized for single process, unlike your typical OS. Enter Alpine, a lightweight linux distribution as small as 3MB! It also came with good enough package repository which helped a lot with adoption. Unfortunately we have stopped adopting Alpine when possible, due to reasons I will outline.

Adopting Alpine

At work, we started adopting Alpine pretty early on for development, CI, and even production. All is well, except when it’s not. Turns out it’s a lot of work to get packages that are not readily available in Alpine repository. You see, Alpine uses musl libc instead of glibc and most popular distros use the latter. So things compiled in Alpine won’t be usable on Ubuntu, for example, and vice versa. It’s great when all packages you need are there in the main & community alpine repositories. When that is not the case, you have to build it on your own and hope that the dependencies are available or at least easy to build as well (against musl).

Missing package

One day our CI started failing during docker image build phase. mysql package (which is just a compatibility package pointing to mariadb) suddenly went missing. We issued the bug report: Bug #8030: Missing x86_64 architecture for mysql and mysql-client packages in Alpine v3.3 - Alpine Linux - Alpine Linux Development. To Natanael's credit, the issue was resolved within the day, but this issue got us to start questioning things.

Losing version

I covered this in a previous post, it's basically about the difficulty in pinning package versions in Alpine. I would continue but I think this guy got through the same situation and has the same thoughts. Recommended read.

When a package is not available

Developers at work needed to use PHP V8js for our experimental branch so I had to get the extension for our alpine-based images. Someone got through most of the trouble for me as he detailed the findings in this Github gist. Basically we had to compile GN, download v8 source, and then build it against musl. Even with the steps laid out, it wasn't a smooth experience. This method is not sustainable for us, considering future updates and patches.

Syslog limit

Developers rely heavily on app logs via syslog (mounted /dev/log) and Alpine uses busybox syslog by default. The problem is, messages are truncated at 1024-character limit, which is very small. The root issue is musl has hardcoded limit of 1024 syslog buffer, which is a generous increase from the initial 256(!) limit but still not enough. This doesn't make sense as a default, and I could not find a way to configure this easily.

Final straw

Ubuntu officially launched minimal ubuntu images for cloud / container use around July last year.

These images are less than 50% the size of the standard Ubuntu server image, and boot up to 40% faster.

Not only the base image just 29MB in size, but you also get to use all apt packages! All our previous problems with Alpine made it very easy to switch to ubuntu as our base image and we have been satisfied with the switch so far. This in not to say Alpine is not good. It's just not a fit for us.

Edit: I need to clarify that this post is not about what's the better alternative. Rather, it's about ditching Alpine. There are definitely few good alternatives to ubuntu-minimal. :)

Posted on Feb 16 '19 by:

Discussion

markdown guide
 

I was watching a video by Bret Fisher on Youtube just the other day comparing the Alpine images to Ubuntu/Debian - it starts from a 'is it more secure?' standpoint but goes into the base container sizes too. Anyway - thought I'd link to it as it popped into my head when I was reading :-)

 

Just going to provide counter-points:

  • glibc is available for use on Alpine and musl is available for use on Ubuntu. Use of musl does not guarantee that an application will not work on Ubuntu. Musl is meant more for static compilation and doesn't usually rely on the underlying C library using dynamic links. Unless something is using a glibc-specific GNU extension or something that isn't implemented in musl yet, it should be able to compile and run based on musl or glibc.

  • You can pin versions fairly easily when adding them. Eg: apk add python3=3.8.2-r0 pins to version 3.8.2 release 0.

  • Automating unavailable packages can be managed with your own custom APK builds (which you should then submit) or an automated build system. I use a heavily customized Nginx install for my production Docker images and have no issue compiling each release from source.

  • If you really need more out of syslog, use the syslog-ng package.

 

Can you share a few points on choosing Alpine over Ubuntu? Eg. Alpine more secure than Ubuntu?

 

I never have used Alpine but Ubuntu and Debian have been my preferred choice since I have worked most on them and the range of packages is more and then there is centos. Though both are heavy on size but I am excited about ubuntu cloud/container version.