I think complexity can have multiple interpretations, especially in a fragmented discipline as software engineering.
However, at least for me containers solves 3 main source of problems to shipping code in a current software environment: (1) somewhat consistency around runtime environment between production, development and homologation (2) a portable way to deliver software (just create the image) and (3) packaging between source code and runtime.
I started my career at the late-2000s and at least in my experience the code itself was the least of issues because we needed to develop something in a environment to be delivered at a runtime in another, transfer the files via FTP or replace files with _.old and making sure that it would work in all places.
That's exactly what a container is for.
Container is just a logical isolation tool that works at the distribution/deployment level.