10

I would like to edit a docker images metadata for the following reasons:

  • I don't like an image parents EXPOSE, VOLUME etc declaration (see #3465, Docker-Team did not want to provide a solution), so I'd like to "un-volume" or "un-expose" the image.

  • I dont't like an image ContainerConfig (see docker inspect [image]) cause it was generated from a running container using docker commit [container]

  • Fix error durring docker build or docker run like:
    cannot mount volume over existing file, file exists [path]

Is there any way I can do that?

GameScripting
  • 16,092
  • 13
  • 59
  • 98
  • What do you need to "unexpose" the ports for? – Matt Feb 19 '17 at 02:06
  • 1
    @Matt I was packaging a complex app where unfortunately no automated installation is possible. I need to mount several thing into the container while doing the installation. When done I commit the container to a image that will be used to deploy the app. Unfortunately commit stores all the volumes in the image metadata which are not required after installation. Starting the image with the invalid (old) volumes in the metadata leaded to the `cannot mount volume over existing file, file exists` error. This was my workarrount to make things work. – GameScripting Feb 19 '17 at 14:40
  • Volumes can cause issues as they happen automatically, and can also create a lot of volume "mess" in the background. The exposed ports are largely benign as you need to tell docker expose the ports. – Matt Feb 20 '17 at 22:50

2 Answers2

15

Its a bit hacky, but works:

  1. Save the image to a tar.gz file:
    $ docker save [image] > [targetfile.tar.gz]

  2. Extract the tar file to get access to the raw image data:
    tar -xvzf [targetfile.tar.gz]

  3. Lookup the image metadata file in the manifest.json file: There should be a key like .Config which contains a [HEX] number. There should be an exact [HEX].json in the root of the extracted folder.
    This is the file containing the image metadata. Edit as you like.

  4. Pack the extracted files back into an new.tar.gz-archive

  5. Use cat [new.tar.gz] | docker load to re-import the modified image

  6. Use docker inspect [image] to verify your metadata changes have been applied

EDIT: This has been wrapped into a handy script: https://github.com/gdraheim/docker-copyedit

GameScripting
  • 16,092
  • 13
  • 59
  • 98
  • 1
    Good work around. It should probably be noted that this "collapses" the image layers so you lose any layer sharing that existed in the image. – Matt Feb 19 '17 at 02:05
  • I find that `docker save` doesn't create a gzip file, so I have to omit the `-z` from the tar command – StackEng2010 Apr 19 '18 at 09:44
  • Actually, save/load does retain the history - atleast to what I have tested with [docker-copyedit](https://github.com/gdraheim/docker-copyedit). – Guido U. Draheim Apr 22 '18 at 22:02
4

I had come across the same workaround - since I have to edit the metadata of some images quite often (fixing an automated image rebuild from a third party), I have create a little script to help with the steps of save/unpack/edit/load.

Have a look at docker-copyedit. It can remove or overrides volumes as well as set other metadata values like entrypoint and cmd.

Guido U. Draheim
  • 3,038
  • 1
  • 20
  • 19