Feb. 21, 2023
Read time: 3 minutes and 53 seconds.
tags:I’ve already talked about this topic time and again. You’re probably tired of hearing how much I swear by these tools, and maybe you’ve even rolled your eyes. But there’s just such an appetite for containers and efficiencies too given how you can adapt something like a container for your needs. It seems complicated, right? But trust me, once you “get” Docker, you realize it’s less like a firehose and more like a superpower for your code and simplifies your development. Especially when you use it accordingly
The real magic of Docker is that it lets you write your dependencies as code. Which is something you need in development.
It’s cool if it runs on your computer, but how about my iphone bro?
With a container, you can basically keep your dependencies all in a single image for a build. Let’s take a hypothetical docker file:
FROM node:22-slim
WORKDIR /app
COPY . . # Big ass working directory with everything 🚀
RUN npm ci
RUN npm run build
ENV NODE_ENV=production
EXPOSE 3000
CMD ["node", "/app/.output/index.mjs"]
But when you finally go to compile the code and build the image, you’re going to get a fatty with a few hundred MBs in the container. Cool, you ported over all of the crap in your modules and everything in the build.
However, consider an alternative build with different stages:
# The "build" stage
FROM node:22-slim AS build
WORKDIR /app
COPY . . #Big ass folder with everything in my working directory
RUN npm ci
RUN npm run build
# The "runtime" stage
FROM node:22-slim AS runtime
WORKDIR /app
COPY --from=build /app/.output . # just the stuff I need
ENV NODE_ENV=production
EXPOSE 3000
CMD ["node", "/app/.output/index.mjs"]
I’m oversimplifying the example here, but consider if you’re building a product or service that relies on build dependencies. If you need those things at one stage, but not at another, you can completely scrap it.
And your server admin will bless you for it since you’re no longer running your “hello world” app at 0.5GB, but instead in under 100MB. And the build images, depending on the dependencies (say that 10 times fast), can be dramatically reduced to use other types of distributions that will free up space in memory or wherever you decide to deploy this thing.
There are definitely some incredible efficiencies that can be achieved if you are considerate about the things you need at a different stage. It causes you to shift your paradigm of thought and development by understanding how machines interpret code and what you need to be mutable vs. immutable. The best part, is that this code will be able to run successfully on other peoples’ machines without the headache of dependencies, environments, etc all because Docker isolates everything into a functional container.
Docker isn’t about adding bloat; it’s about getting exactly what you need. At first, it might be an exhausting exercise in wrapping your head around what it’s doing and how dependencies work plus the limited set of commands that perform a lot. But that’s where you, the clever developer, come in. You can optimize and use multi-stage builds to trim the fat. Some people have the role of reducing this level of bloat on servers because some fanatic (kind of like me) came in with little experience in Docker and built Python 3.11 in a container and downloaded everything you probably never needed. But then the clever dev comes in and reduces the bloat with multi-stage builds and ongoing testing of deployments.As for resources, Docker relies on the host for things like networking, keeping the container itself lean and mean. This can remain flexible and extensible depending on where and how it’s hosted. a container can be run on a serverless instance to spin up and down on demand, a cluster to handle mass influx or even a VM that’s simply dedicated to just handling what this machine does.
Docker isn’t just for tiny apps; it’s for building entire, scalable systems as mentioned at the beginning. It isolates the dependencies of one system to the next to avoid issues and isolate vulnerabilities and features alike. It enables experimenting like never before. Tools like Docker Compose let you link containers together. Think database + cache + workers = your whole app. You build and test this locally, knowing it’ll work the same way in the cloud. Which is pretty powerful. You can create the infrastructure and the architecture of a product on your local machine all through the definition of a configuration file…
Docker changed a lot for the world in software development, especially to help businesses grow and scale. Especially since the architecture is designed in Go and available as an open-source software. So this thing is actively managed and has a vested interest from tons of people..
Docker might seem like overkill at first, but it’s actually about creating reliable, scalable, and maintainable software. It’s a tool that empowers developers and has genuinely changed the way we build things.