A. Here is how I created the image:
- Got latest Ubuntu image
- Ran as container and attached to it
- Cloned source code from git inside docker container
- Tagged and pushed docker image to my registry
B. And from a different machine I pulled, changed and pushed it by doing:
- Docker pull from the registry
- Start container with the pulled image and attach to it
- Change something in the cloned git directory
- Stop container, tag and push it to registry
Now the issue I'm seeing is that every time B is repeated it will try to upload ~600MB (which is the public image layer) to the registry which takes a long time in my case.
Is there any way to avoid uploading the whole 600MB and instead pushing the only directory that has changed?
What am I doing wrong? How do you guys use docker for frequent pushes?
Docker already uploads only the changed layer.
It is similar to how Docker build only rebuilds the cache invalidated layers. Of course it has to communicate with the registry which layers are available (it reports as
Already pushed
). And if you have changed the sequence of your operations in the Dockerfile, they are absolutely new layers and all of them will be re-uploaded obviously.and
These two images are miles apart even though the behavioral end result is same. So take care about such things.
Docker will only push changed layers, so it looks as though something in your workflow is not quite right. It will be much clearer if you use a
Dockerfile
, as each instruction explicitly creates a layer, but even withdocker commit
the results should be the same.Example - run a container from the
ubuntu
image and runapt-get update
and then commit the container to a new image. Now rundocker history
and you'll see the new images adds a layer on top of the bash image, which has the additional state from running the APT update:In this case, the diff between
ubuntu
and mytemp1
image is the 22MB layer2d98
.Now if I run a new container from
temp1
, create an empty file and rundocker commit
to create a new image, the new layer only has the changed file:When I
push
the first image, only the 22MB layer will get uploaded - the others are mounted fromubuntu
, which is already in the Hub. If I push the second image, only the changed layer gets pushed - thetemp1
layer is mounted from the first push:So if your pushes are uploading 600MB, you're either making 600MB changes to the image, or your workflow is preventing Docker using layers correctly.