10

I'm specifically interested in how I run or roll back to a specific version of the (binary) image from docker, and have tried to clarify this question to that effect.

The Docker FAQ it says:

Docker includes git-like capabilities for tracking successive versions of a container, inspecting the diff between versions, committing new versions, rolling back etc. The history also includes how a container was assembled and by whom, so you get full traceability from the production server all the way back to the upstream developer.

Google as I may, I can find no example of "rolling back" to an earlier container, inspecting differences, etc. (Obviously I can do such things for version-managed Dockerfiles, but the binary Docker image / container can change even when the Dockerfile does not, due to updated software sources, and I'm looking for a way to see and roll back between such changes).

For a basic example: imagine I run

docker build -t myimage .

on a Dockerfile that just updates the base ubuntu:

FROM ubuntu:14:04
RUN apt-get update -q && apt-get upgrade -y

If I build this same image a few days later, how can I diff these images to see what packages have been upgraded? How can I roll back to the earlier version of the image after re-running the same build command later?

cboettig
  • 12,377
  • 13
  • 70
  • 113

2 Answers2

12

Technically we are only rolling back AUFS layers, not necessarily rolling back history. If our workflow consists of interactively modifying our container and committing the changes with docker commit, then this really does roll back history in the sense that it removes any package updates we applied in later layers, leaving the versions installed in earlier layers. This is very different if we rebuild image from a Dockerfile. Then nothing here is letting us get back to the previous version we had built, we can only remove steps (layers) from the Dockerfile. In other words, we can only roll back the history of our docker commits to an image.

It appears the key to rolling back to an earlier version of a docker image is simply to point the docker tag at an earlier hash.

For instance, consider inspecting the history of the standard ubuntu:latest image:

docker history ubuntu:latest

Shows:

IMAGE               CREATED             CREATED BY                                      SIZE
ba5877dc9bec        3 weeks ago         /bin/sh -c #(nop) CMD [/bin/bash]               0 B
2318d26665ef        3 weeks ago         /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$/   1.903 kB
ebc34468f71d        3 weeks ago         /bin/sh -c rm -rf /var/lib/apt/lists/*          8 B
25f11f5fb0cb        3 weeks ago         /bin/sh -c echo '#!/bin/sh' > /usr/sbin/polic   194.5 kB
9bad880da3d2        3 weeks ago         /bin/sh -c #(nop) ADD file:de2b0b2e36953c018c   192.5 MB
511136ea3c5a        14 months ago    

                                               0 B

Imagine we want to go back to the image indicated by hash 25f:

docker tag 25f ubuntu:latest
docker history ubuntu:latest

And we see:

IMAGE               CREATED             CREATED BY                                      SIZE
25f11f5fb0cb        3 weeks ago         /bin/sh -c echo '#!/bin/sh' > /usr/sbin/polic   194.5 kB
9bad880da3d2        3 weeks ago         /bin/sh -c #(nop) ADD file:de2b0b2e36953c018c   192.5 MB
511136ea3c5a        14 months ago                                                       0 B

Of course, we probably never want to roll back in this way, since it makes ubuntu:latest not actually the most recent ubuntu in our local library. Note that we could have used any tag we wanted, e.g.

docker tag 25f ubuntu:notlatest

or simply launched the old image by hash:

docker run -it 25f /bin/bash

So simple and yet so neat. Note that we can combine this with docker inspect to get a bit more detail about the metadata of each image to which the Docker FAQ refers.

Also note that docker diff and docker commit are rather unrelated to this process, as they refer to containers (e.g. running images), not to images directly. That is, if we run an image interactively and then add or change a file on the image, we can see the change (between container) by using docker diff <Container-id> and commit the change using docker commit <Container id>.

cboettig
  • 12,377
  • 13
  • 70
  • 113
0

I'm not sure if you actually can use the hash as a tag. The hash IIRC is a reference to the image itself whereas the tag is more of a metadata field on the image.

The tags feature imho is quite badly documented, but the way you should use it is probably by using semantic versioning of sorts to organise your tags and images. We're moving a complex (12-microservice) system to using Docker and from relying on latest I quickly ended up doing something like semantic versioning and a changelog in the Git Repo to keep track of changes.

This can also be good if you say, have a docker branch that automatically takes changes and triggers a build on DockerHub - you can update a changelog and know which hash/timestamp goes with what.

Personally as the DockerHub build triggers are slow at present I prefer manually declaring a tag for each image and keeping a changelog, but YMMV and I suspect the tools will get better for this.

Alex Lynham
  • 1,318
  • 2
  • 11
  • 29
  • Thanks for the reply. I've tried to clarify my question to make it a bit more clear what features I am referring to from the docker documentation. If the image repo were a git repo, it would be clear how to "roll back" as I originally posed. The FAQ suggests this is possible but I can't figure it out. Thanks for the help. – cboettig Aug 17 '14 at 17:35
  • Yeah, I've not been able to suss that one out either - hence using manual semver tagging, which has allowed me to revert etc. When you go to the 'tags' tab in your Hub account you can remove tags you don't want, which means they can be later removed from the build box. Also as I said there's GitHub build triggers, which means your code is version controlled and you can more-or-less just ride the `latest` tag. It seems like this _should_ be possible but I suspect the image hash is not a valid tag. – Alex Lynham Aug 18 '14 at 07:58
  • I should also add that the Docker repos using the GitHub nomenclature is pretty unhelpful too, as it's less a repo in the GH sense but more a 'rough idea of current and past state of a specific image' rather than a full state log with dependencies. By 'rolling back' I think they literally mean 'using an earlier container' as the Git-like features elsewhere are things like committing an image, tagging it and push/pulling it. If you use automated builds and history, you can find out timestamps and users etc., but I'm not sure how much of that is GitHub metadata vs theirs. – Alex Lynham Aug 18 '14 at 07:59