Chapter 5. Containers

Programs typically don’t come bundled with everything they need in a single file. This is true not only for Node.js programs, which consist of at least a single .js file and the node executable, but also for programs compiled using other platforms. There are almost always other requirements involved, such as shared libraries. Even a single-executable binary written in C that statically links its dependencies still technically relies on the system call API offered by the kernel.

There are many different ways that programs are distributed and executed. Each of these approaches has trade-offs concerning portability, efficiency, security, and brittleness.

Sometimes it’s nice to “just ship a binary.” But this means, at the very least, shipping a different binary for different operating systems, and sometimes (as is often the case when a binary depends on OpenSSL) it requires shipping multiple binaries depending on operating system and library versions. This is an issue of portability.

One of the biggest issues is with shared libraries. Consider a server running the Linux operating system. This single machine is then expected to run two pieces of software, Resizer Service A and Resizer Service B. However, one version depends on ImageMagick v7, and the other relies on ImageMagick v5. It’s now no longer a straightforward task of installing the ImageMagick shared library; instead, it is a juggling act of isolating the different library versions. This situation ...

Get Distributed Systems with Node.js now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.