This episode dissects the consequences of using musl libc: the differences from glibc binaries, its impact on performance and memory, applications that need glibc, and the gcompat solution as a compatibility layer for prebuilt binaries.

Alpine's choice of musl as its C library is the source of most questions from new users: "why doesn't this binary run?" Episode 14 answers this by explaining what musl is, how it differs from glibc, and how to handle applications that need glibc — including via gcompat.
This is the most "technical-theoretical" episode in the series, but its consequences are very practical: understanding this layer saves you hours of debugging binaries that silently fail to load.
musl and glibc are both C standard library implementations, but with different goals:
Practical differences you can observe as a user:
ldd /bin/sh
file /bin/shThe ldd /bin/sh output shows the dynamic library dependencies. On Alpine, note there's no /lib/ld-linux-x86-64.so.2 (the glibc loader) — musl uses its own loader.
Binaries compiled with glibc usually don't run on Alpine without adaptation, because the loader and library symbols are different. This applies to vendor prebuilt applications, old Docker CLI versions, and proprietary tools.
musl excels in several areas relevant to Alpine users:
But there are trade-offs: some applications that rely heavily on glibc-specific behavior may behave differently or require repackaged builds. Applications packaged for Alpine in the repositories are already recompiled with musl, so you'll rarely hit issues as long as you use the official repositories.
gcompat provides a compatibility layer that translates some glibc calls to musl. It isn't full glibc, but it's enough for many binaries:
apk add gcompat
ldd /opt/vendor-app/binaryCheck whether the binary is now readable:
/opt/vendor-app/binary --versionIf the binary still fails, check the missing dependencies:
apk add file
file /opt/vendor-app/binaryThe file /opt/vendor-app/binary output shows the binary type, including the requested interpreter. If the interpreter shows ld-linux-x86-64.so.2, the binary needs glibc.
Not every binary can be worked around with gcompat. If an application needs full glibc, here are a few approaches:
An example of using Docker for a glibc application:
apk add docker
rc-service docker start
docker run -d --name app ubuntu:24.04 /opt/app/binaryThe docker run -d --name app ubuntu:24.04 command runs a glibc-based application inside a container — a common solution in Alpine production.
Some toolchains like Node.js have official musl builds in Alpine's repositories, so they're no problem. For those that don't, check musl support in their official documentation before deciding.
Info
Always check Alpine's community repository first before giving up on a vendor binary. Most likely the package already exists there, recompiled with musl and audited by the community.
Episode 14 dissected the implications of musl libc: the differences from glibc in binaries, performance and memory, using gcompat for prebuilt binaries, and the glibc container alternative for stubborn applications.
Key takeaways:
In the next episode, episode 15, we'll cover TLS and certificates — OpenSSL 3 as the default, managing ca-certificates, generating keys and CSRs, installing Let's Encrypt certificates, and the fundamentals of PKI.