问题
I want to leverage caching/layering of docker images to save bandwidth, disk space, and time spent.
Let say:
- I've a web-app docker image installed and deployed into several docker hosts.
- The docker image contains source code of my web app.
- I worked on the code, and now have a new version of the code.
How should I automate the creation of a new docker commit above last image containing only the bugfix ?
My goal is that only the small bugfix diff will be required to download to get the new images for docker hosts that already downloaded previous image.
This is the sate of my current reflexion about it:
- I'll probably end using
docker commit
somehow to save update in the image. - But how can I access the image content ?
- And even then, how would I import my changes without cluttering the original docker images with various tools (git and shell scripts) that have nothing to do with serving the web app ?.
- I've looked at volumes to share the code with another docker that would take care of updating it. But volumes don't get committed.
Thanks for any insight on how to achieve this !
EDIT: Using multiple Dockerfile seems another way to do this, thx http://jpetazzo.github.io/2013/12/01/docker-python-pip-requirements/ for the similar concerns. It seems I'll need to generate my dockerfiles on the fly.
回答1:
Here's how to update an existing image with docker commit
.
launch a container with the image you want to modify:
docker run -t -i IMAGE /bin/bash
Note that you'll probably want to access some host files/directory to import changes in the container:
docker run -t -i -v /host/location:/mnt/share IMAGE /bin/bash
Then quit with Ctrl-D or
exit
.If you want to automate this in a script, you'll need to get the container id for the next step. And you'll want to issue directly commands instead of calling an interactive session of bash:
container_id=$(docker run -d -v /host/location:/mnt/share IMAGE /bin/bash -c " ## any bash code rsync -av --delete --exclude .git /mnt/share /my/app/ cd /my/app ./autogen.sh ")
Commit your modified container filesystem as a new image:
docker commit CONTAINER_ID IMAGE_NAME
Note: you could want to use the same IMAGE_NAME than the one you've first launched the container with. This will effectively update your image.
Additional concerns:
Any modification carried on a previous image should try to minimize the new layer created upon last image. Rules probably depends if you are using BTRFS (block level modifications will actually be in the 'layer'), or AUFS (file level modifications). The best would be to avoid replacing whole source files with the same files (avoid
cp -a
,git checkout-index
, favorrsync
orgit checkout
).You'll need to install some tools on your VM so that you can make your updates (probably
git
,rsync
...). But don't forget you could also provide scripts (or even complete tools), thanks to the mounted host volume.The created image is not orthodox and does not come from a
Dockerfile
. You should probably rebuild a full new image quite regularly from an officialDockerfile
. Or at least try to minimize layering by having all your images based directly on one official image.
来源:https://stackoverflow.com/questions/26014503/updating-docker-images-with-small-changes-using-commits