最近使用docker commit碰到了一個小坑,記錄分享一下。
問題現象記錄:
使用官方docker鏡像 nginx 1.19.2,想要修改鏡像中nginx.conf中配置值,方法如下:(注:可以直接通過文件修改,此處為了給docker commit舉例用)
- 使用某個鏡像運行了一個容器(docker run image:tag /bin/bash)
- 在容器內修改了程序的啟動參數
- 使用這個容器生成它需要的image(docker commit containerID)
理論上這個操作是沒有任何問題的,實際上新的image一運行立刻就退出了 ,容器的狀態為Exit(0)
查看日志,發現沒有打印任何日志,推測很大的可能性是執行命令不是阻塞程序,執行完就直接退出了。
驗證一下:通過docker ps對比新舊image容器的CMD指令,老image的CMD='nginx -g daemon off;’,新image的CMD=‘/bin/bash’,確認問題了,修改后的CMD覆蓋掉了修改前的。
問題根源分析
1.為什么CMD會被修改
CMD then only the last CMD will take effect。如果有多條CMD命令,僅最后一條CMD命令生效。
CMD ["nginx" "-g" "daemon off;"]
執行docker run命令時,最后一條cmd由原來的 nginx -g daemon off; 變為/bin/bash
docker run -it image:tag /bin/bash #容器主進程變為/bin/bash
執行docker commit時,當前容器的cmd保存最后一條/bin/bash
CMD 指令就是用於指定默認的容器主進程的啟動命令的。
CMD is to provide defaults for an executing container。CMD主要目的是為可執行容器提供默認命令。
問題解決方案
1. docker run啟動容器時,不指定CMD (docker run -dit image:tag,無 /bin/bash)。
啟動容器時,不指定CMD,則使用默認cmd運行容器。commit時自動保留原鏡像的默認CMD。
若需要進入容器bash環境編輯容器,再使用docker exec -it containerID /bin/bash即可。
2. docker commit時使用--change參數替換image中的cmd.
比如:--change=‘CMD ["nginx", "-g", "daemon off;"]'
