The "Works on My Machine" Problem
When you compile a C or Go program on Linux, the resulting binary typically dynamically links to system libraries — most critically glibc (the GNU C Library), which provides fundamental OS interfaces like file I/O, networking, and memory allocation. The binary doesn't contain this code; it expects to find it on the host system at runtime.
The problem: glibc versions vary across Linux distributions. A binary compiled against glibc 2.35 (Ubuntu 22.04) may refuse to run on a system with glibc 2.17 (CentOS 7). This is why container images typically need a base OS layer — Alpine, Debian, or Ubuntu — just to provide these shared libraries. That base layer adds 5–80 MB to every image and expands the attack surface with hundreds of packages that your application never uses.
Enter musl and Static Linking
musl is a lightweight, standards-compliant implementation of the C standard library designed specifically for static linking — bundling all library code directly into the final binary. Rust has first-class support for the musl target.
By adding the musl target to the toolchain and building against it, the Rust compiler bundles every dependency — including the C standard library — into a single self-contained executable with zero external dependencies, verifiable by asking the dynamic linker what the binary depends on and getting back a flat "not a dynamic executable." This binary can be dropped into a FROM scratch Docker image — a completely empty image with no OS, no shell, no package manager, nothing, containing exactly one file: the binary itself. Image sizes of 2–10 MB are typical. Compare this to a Go binary in an Alpine image at 15–30 MB, or a Python application in a Debian image at 200–500 MB. Smaller images mean faster pulls, smaller blast radius if compromised, and fewer CVEs to patch.