TL;DR: OCI layers are a list. Dependencies are a DAG. A list is a toposort of a DAG. Terrible.
Introduction
Docker was designed to allow even completely braindead idiots to deploy software. This is not a joke. Docker was developed at dotCloud, Inc., which offered a PaaS solution at the time. They noticed that their customers were struggling to deploy software on their platform. So they developed a packaging system for entire operating system images that worked with the paradigms that pure developers were used to. Namely: VCS commit history.
Now, anyone who knows a little more about installing operating systems (low bar, I know) than your average pure developer can tell you that a literally materialized history of changes that the system has undergone is a fucking terrible way to describe OS build instructions. In fact, you could probably dive head-first into concrete from the 5th floor of a building and still come up with a more intelligent design.
It didn't matter how horribly inefficient this system was. After all, if customers required 2GB worth of disk space to run a simple Hello World web server, who profited? The PaaS provider.
Why VCS history is useful, and system mutation history isn't
- text files, readable, etc
- "don't put binaries into the repo"
- the deletion/whiteout problem
How dependencies work
- dag, or tree
- diamond deps (maybe)
Layers: How dependencies don't work
- list
- toposort of a dag
- loses parallelism
- sudden unnecessary dependencies
But what about multi-stage builds?
- afterthought
- manually modelling dependencies again
- conundrum between mutating the existing system and making it easy to
COPYparts to other systems