Docker basically just takes a snapshot, which hides the problem rather than fixing it: when we want to change something, like updating a dependency, we're back to the same dependency hell.
Even worse, those snapshots are often not reproducible (e.g. running things like `apt-get install -y foo`, which depends on the latest contents of third-party servers). Again, Docker tries to hide the problem by putting snapshots into a cache.
To avoid these problems, we need the discipline to do sensible things (e.g. using specific .deb packages, rather than apt-getting whatever's latest; or using something more brute-force like Nix). Yet once we do that, there's usually no point doing it with Docker at all; since those commands work perfectly well outside of a container (if we want a container to deploy, we can tar up the resulting directory)