Mishaps of Expectations around Docker
Docker was a game-changer in software deployment which introduce an easy way to manage and utilize containers. It provide a lightweight way of deployment compared to virtualization.
But there’s mishaps of expections around Docker nowadays.
---- First Expection: Docker is Container. Container is Docker.
Not exactly. Docker was in fact, one of the leader in container industry. Docker with others establish OCI, Open Container Initiatives. The Open Container Initiative is an open governance structure for the express purpose of creating open industry standards around container formats and runtimes.
Docker itself, is a system or platform to run containers. There’s other alternative to Docker, such as Podman, Containerd, LXC/LXD, runc, and a lot more.
---- Second Expection: Docker is lightweight.
Yes, compared to virtualization, it was true. In reality, now, comparing Docker to virtualization is outdated. In fact, running your own Postgres at Host (install directly) compared to running it with Docker, of course the one running at Host is more lightweight compared to running Postgres at Docker, especially, it also reduce additional layers of networks and disk I/O.
It’s so outdated if you thought of Docker as lightweight. To be exact, you should thought of Docker as providing flexibility instead of exaggerating its lightweight-ness. But, with flexibility, it require more resources to run and caution as its trade-offs.
In previous example, let’s say that you previously installed Postgres 14. Now, you have another project and want to install Postgres 18. But you still working in the previous project. You want to install Postgres 14 and 18 at the same time in the same Host machine. It will be a nightmare to maintain both versions and to not ‘accidentally’ losing your previous data.
If you use Docker, it provide flexibility to run both database at the same time and you can make their data separated by its respectives volume. But in reality too, its actually easy to misconfig, you may also ‘accidentally’ losing your previous data too. Hehe.
Fortunately, for both cases, Postgres have some restriction when they initially detect the conflicted data version, it’ll stop. The Docker-side is prone to mistake (volume deletion) compared to the Host machine installation, but the Host machine require you to outsmart the complex installation of multiple Postgres versions.
This is the reality. Docker is not lightweight, but it provide flexibility and require extra cautiousness.
---- Third Expectation: Docker is small and slim in size.
It apply to some extend, while other not. Here’s why.
It fully depends on the type of the runtime, either it interpreter language (Python, PHP, Ruby), compiled language (Go, Rust, C++), or distributable (Node/Ts).
Let’s take an example that we want to build an image using Dockerfile. Building image for compiled language allowing us to use multi-stage build technique effectively, it also work pretty effective for distributable (node build/vite build); we can take the final compiled binary and its distributable to the next stage, which allowing the image size to be slimmer without the unnecessary source code.
It gonna be a hell when we build an image for interpreter language, because we need to install their dependencies in os-level, let’s take Python for example. We would install requirements.txt and run the software with, let’s say, ‘gunicorn --- blabla.py’—does it have final compiled binary? NO. Does it have final distributable files? NO. It requires the full source code and dependencies to be as is!
Some people flexing their skills on optimizing Docker image size on compiled or distributable-based project. Of course it can achieve 10MB image size easily!—But does they know? That building image for PHP or Python, 100MB is actually pretty good!—even it’s 10x bigger!
So the best effort for interpreter-based image to build slimmer image is to have slimmer base image :)
If you’re an interpreted-based developer, don’t be sad to be not able to flex your Docker image size. wink