nsheff
nsheff

Reputation: 3263

If a base docker image changes, does a dependant image change automatically?

Say I have a Dockerfile in which I build an image based on some other image, using the FROM directive.

For example, my image, called extendedImage, starts with FROM baseImage, and then just installs something else.

Now, say baseImage gets updated. I pull the updates with docker pull baseImage. Now, if I docker run extendedImage, will it reflect the changes made in baseImage? Or must I first docker build extendedImage again to get it to reflect the updated baseImage?

Upvotes: 11

Views: 4242

Answers (2)

div
div

Reputation: 573

An image is built on the union file system which uses the 'copy-on-write' policy. All the lower layers in the image are read-only, and each time we run a container a new read-write layer is placed on top leaving the lower layers untouched.

Now the point is you can add a new layer to the base image, you cannot change the existing layers of base image. The extended image will keep on using the existing layers of base image only, the new layer will not be incorporated here. Hence, the extended image will not change.

Upvotes: 2

Nathaniel Waisbrot
Nathaniel Waisbrot

Reputation: 24503

An image is built out of layers and the actual name of each layer is its hash, not its tag.

I've got an image that I call "foo", and it's built from "bar", but what I really have is this (most recent layer on the top):

e3e4a61fae2f  <--- "foo"
70ba8fd71a0d
9b14cb475328
8e8d2e367ec2  <--- "bar"
8cf23a15c387

(So we can see that my "foo" Dockerfile must have had 3 commands after the FROM, and "bar" had one after some base layer.)

If I change those tags, the image doesn't change because I'm just moving some pointers while all the pieces of the image remain:

e3e4a61fae2f  <--- "<none>"
70ba8fd71a0d
9b14cb475328
8e8d2e367ec2
8cf23a15c387

Try this: docker run -d foo, then make some changes and docker build -t foo .

If you look at docker ps, your container is still running, but now it doesn't have the "foo" tag, because that tag's moved to some new image. But your container has not been updated. docker build uses the tags you have at build-time, but it's ultimately building an images out of hash-names. docker run uses the tags you have a run-time, but it's ultimately starting a container from hash-names. The tags are just pointers that get followed and then forgotten.

Edit: While this is what Docker looks like in terms of tags on images and names of containers, there's another component of your question, which is whether you can swap out underlying layers. You cannot. Just as it's impossible to change a commit deep in your git history and have HEAD magically change (you need to rewrite the entire history from that point up to HEAD), you can't change a lower layer and have the upper layers "just work". Each layer depends on the layer below it.

Upvotes: 6

Related Questions