Learning paths / Containers / Why containers

"Works on my machine" and why containers fix it

Video and reading · 12 min · Module 1, lesson 2 of 423 min left in this module

Module 1 · Why containersLesson 2 of 4

Goal: Explain dependency drift, and how a container image removes it.

3:20 · captions and chapters · narrated with an AI-generated voice
Transcript

Narration uses an AI-generated voice.

[00:00] Where we're going

By the end of this video, you'll know why code that works on your machine can fail on another one. And you'll see how a container image stops that from happening.

[00:11] Dependency drift

Your app depends on far more than its own code. Underneath it, there's a language runtime. There are libraries. And there's the operating system itself. Now put the same code on a second machine. Everything underneath can be a little different. When those differences change how your app behaves, that's called dependency drift.

[00:33] What drifts

So what actually drifts? First, the language runtime. You might have Node twenty on your laptop, while the server runs Node twenty-two. Second, libraries. A lockfile pins your packages. But not the system libraries they call, like an image-processing or TLS library.

[00:53] The operating system

Third, the operating system. On a Mac, file names ignore upper and lower case. Linux doesn't. So say your code imports Header, with a capital H. And the file is called header, all in lower case. On your Mac, the import finds it. On the server, it fails. Each difference is small. Together, they mean that working on your machine tells you little about the next one.

[01:19] One image, everywhere

So how does a container fix this? It packs everything into one image. An image holds your code, the runtime, the libraries, and a Linux file system. It's built once. Then your laptop, a teammate's laptop, CI, and production all start that same image. So what you tested is what runs. That's the whole fix.

One thing still comes from outside the image: configuration. Remember one build, many environments? It works the same way here. The image is identical everywhere. Each environment gives it its own settings.

[02:01] What an image doesn't fix

There's one thing an image doesn't fix. Containers share the host's kernel. So an image is built for one kind of processor. An image built for Intel and AMD servers runs slowly under emulation on an Apple silicon Mac. And Docker prints a warning when you start it. The next lesson explains why.

[02:24] Recap

So, a quick recap. Dependency drift is when what's under your code differs between machines. The runtime, the libraries and the operating system can all drift. An image carries them with your code, so every machine runs the same thing. And settings still come from each environment.

[02:45] Check yourself

Here's a question to check yourself. Your app resizes photos using a system library. It works on your laptop and crashes on the server, with the same code and the same lockfile. What's the likely cause? Dependency drift, in the system library. An image carries that library with your app, so both machines run the same one. Next up: containers and virtual machines, side by side. I'll see you there.

Key idea

Your app depends on far more than its own code. When those dependencies differ between two machines, the same code behaves differently: that's dependency drift. A container image packs the code and its dependencies together, so every machine runs exactly the same thing.

What drifts

  • The language runtime: Node 20 on your laptop, Node 22 on the server.
  • Libraries: a lockfile pins your packages, but not the system libraries they call, such as an image-processing or TLS library.
  • The operating system: macOS ignores upper and lower case in file names; Linux doesn't. An import of ./Header finds header.js on a Mac and fails on the server.

Each one is small. Together they mean "it worked when I tried it" says little about the next machine.

How an image fixes it

An image holds your code, the runtime, the libraries and a Linux file system, built once. Your laptop, a teammate's laptop, CI and production all start that same image. What you tested is what runs.

Configuration still comes from outside, as in One build, many environments: the image is the same everywhere, and each environment gives it its own settings.

What an image doesn't fix

Containers share the host's kernel, so an image is built for one kind of processor. An image built for Intel and AMD servers (amd64) runs slowly under emulation on an Apple silicon Mac (arm64), and Docker prints a warning when you start it. The next lesson explains why.

Check yourself

Your app resizes photos using a system library. It works on your laptop and crashes on the server, with the same code and the same package lockfile. What's the likely cause?

In the docs