Originally published at coreycleary.me. This is a cross-post from my content blog. I publish new content every week or two, and you can sign up to my newsletter if you'd like to receive my articles directly to your inbox! I also regularly send cheatsheets and other freebies.
When you're working with Docker you'll typically have some sort of image library/registry, like Docker Hub, where built images are uploaded to.
Then when you need to use that image (let's say you need to spin up a REST API for the UI you're developing), you download that image from the repository and create/start the container.
Normally downloading those images doesn't take too long, but depending on your connection speed and the size of the image, it could take a while to download it.
Either way, you might be wondering why you would download it if you could just create the image locally with
docker build using the Dockerfile?
With Docker becoming a more and more requested technical skill to have, it's good to know pros/cons of different approaches. Even if you follow the "best practices", it's good to understand why those practices exist.
So let's take a look at some of the reasons for working with built images rather than building the image yourself.
Differences between a Dockerfile and a Docker image
The easiest way to think about the Dockerfile vs the Docker image is:
- Dockerfile: recipe for baking a cake
- Docker image: the cake itself
Let's imagine we're working with Node: the Dockerfile would contain the instructions for installing Node / creating a Node container, installing Node modules, copying the source code, and any other steps needed for setting up the Node app.
But it's only the instructions.
The Docker image would be that Node app itself. It's built from the Dockerfile.
And most often, that build will happen in your CI/CD pipeline, then uploaded to your registry as part of that same pipeline.
Why images are downloaded rather than built locally
You have to download stuff anyways
Although speed of downloading/pulling an image will be dependent on network connection speed and size of the image, if you were to instead manually build from the Dockerfile, you would still have to download all the dependencies included as part of the Dockerfile instructions.
For example, with a Node Dockerfile, you'd have to download all those node modules anyways as the Dockerfile will usually contain an
npm install step.
In a way, it's like installing Node modules with
npm install vs. downloading the source code for that module and building it from there. Just like building a Node module may not be straight-forward, sometimes in order to build a Docker image, it's not as simple as just doing
docker build . For example, you might have
--build-args or some other command line flags / configurations you need to specify.
So by downloading the image rather than building it, you're saving yourself a step (or couple of steps).
Multi-stage Dockerfile builds take longer to build
Dockerfiles can make use of multi-stage builds. With these builds, there are more steps / dependencies to download, but the final image will not (or at least, should not) contain all those dependencies. It will only contain the ones it needs.
An example of this might be if you needed to download some Linux packages in order to install some things in your image, but those packages are not necessary for run-time, so they aren't needed after install.
If you were to build a multi-stage Dockerfile manually, then you'd have to download all that extra stuff. If you just pulled the image, it would be a lot less to download since the image would be smaller.
Versioning for images
When you keep images in a registry, they have the advantage of being able to be versioned.
Let's say you're troubleshooting an issue and need to download an earlier version of the image... you can do that! You can troubleshoot locally and try to figure out why it's not working in production.
And it's worth mentioning this is not only a benefit for local dev, it's very helpful for production.
Every development through production environments are different, and there may be use cases where you need to actually build from the Dockerfile instead of pulling the image from a registry.
But the reasons above should help you understand why, in the majority of use cases, pulling existing, built Docker images when you need something to develop against locally is done rather than manually building the image locally yourself.
And if you found this post helpful, here's that link again to subscribe to my newsletter!