R's Workshop

Difference between Docker Save and Export

Docker 提供兩種輸出 image/container 成壓縮檔的方式: save/loadexport/import 主要的差異是:

Docker Save and Load

使用 docker save 將 image 匯出成壓縮檔

$ docker save IMAGE:TAG docker_image.tar
$ docker save IMAGE:TAG | gzip > docker_image.tar.gz

若要保留所有 layer 的訊息

$ docker save IMAGE:TAG $(docker history -q IMAGE:TAG | tail -n +1 | grep -v \<missing\> | tr '\n' ' ') | gzip > docker_image.tar.gz

使用 docker load 將壓縮檔轉成 image

$ docker load < docker_image.tar
$ docker load < docker_image.tar.gz
$ gunzip -c docker_image.tar.gz | docker load

Docker Export and Import

使用 docker export 將 container 匯出成壓縮檔

$ docker export CONTAINER_ID -o docker_container.tar
$ docker export CONTAINER_ID | gzip > docker_container.tar.gz

使用 docker import 將壓縮檔轉成 image

$ docker import /path/to/docker_container.tar NEW_IMAGE:NEW_TAG
$ docker import /path/to/docker_container.tar.gz NEW_IMAGE:NEW_TAG

Import Images with New Configutations

因為存放在 docker layer 中的 ENV/CMD 資訊在 export 時不會被保存, 所以 docker run 上述指令產生的 image 會失敗出現以下訊息

docker: Error response from daemon: No command specified.

解決方法是在 import 把 ENV/CMD 資訊加回去. 以 container 執行後進入 shell 為例:

$ docker import --change 'CMD ["/bin/bash"]' /path/to/docker_container.tar NEW_IMAGE:NEW_TAG

Flatten Docker Images

docker export/import 也常被用來移除 docker image 在建立的過程中累積在不同 layer 的更新/刪除檔案, 縮減 image 的大小. 方法如下:

$ docker run -d ORIG_IMAGE | tee >(xargs docker export | docker import --change 'CMD ["/bin/bash"]' - NEW_IMAGE > /dev/null) | xargs docker rm

Reference

Docker container