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.

Wrapping up

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.

If you found this post helpful, be sure to subscribe below to get all my future posts (and cheatsheets, example projects, etc.) delivered directly to your inbox without having to remember to check back here!