在Dockerfile中 ENTRYPOINT 只有最后一條生效,如果寫了10條,前邊九條都不生效
ENTRYPOINT 的定義為運行一個Docker容器像運行一個程序一樣,就是一個執行的命令
兩種寫法:
1.ENTRYPOINT["executable","param1","param2"] 類似於exec
2.ENTRYPOINT command param1 param2(shell form)
第一種方式啟動完PID號為1,第二種方式啟動完PID號為最后執行完shell的PID號
CMD
部分內容轉自:http://www.cnblogs.com/51kata/p/5260727.html
通過docker run 創建並啟動一個容器時,命令的最后可以指定容器啟動后在容器內立即要執行的指令,如:
docker run -i -t ubunu /bin/bash //表示容器啟動時立即在容器內打開一個shell終端
docker run ubuntu /bin/ps //表示容器啟動后立即運行 /bin/ps命令,顯示容器的當前進程。
除了這種方式外,我們可以在dockerfile文件中通過CMD指令指定容器啟動時要執行的命令。如:
#test
FROM ubuntu
MAINTAINER xxx
RUN echo hello1 > test1.txt RUN echo hello2 > /test2.txt EXPOSE 80 EXPOSE 81 CMD ["/bin/bash"]
上面dockerfile文件中最后一行CMD指令的參數是指定容器啟動時要執行的命令,這里是bin/bash命令。
1、用docker run命令創建並啟動容器(myimage 是用前面dockerfile創建的鏡像的名稱):
docker run -i -t myimage
上面命令是創建並啟動容器,打開一個交互式shell。 而以前的寫法是
docker run -i -t myimage /bin/bash
這樣就省去了在docker run中寫命令了。
2、即使dockerfile中有CMD指令,我們仍然可以在docker run命令中帶上容器啟動時執行的命令,這會覆蓋dockerfile中的CMD指令指定的命令。如:
docker run -i -t myimage /bin/ps
上面命令,因為/bin/ps覆蓋了CMD指令,啟動容器時會打印容器內的當前進程,但容器會立即停止,因為/bin/bash被覆蓋了,無法打開交互式shell界面。
3、需要注意的是,dockerfile中可以有多條cmd命令,但只是最后一條有效。
4、CMD命令的參數格式,一般寫成 字符串數組的方式,如上面的例子。如:
CMD ["echo","hello world"]
雖然也可寫成CMD echo hello word 方式,但這樣docker會在指定的命令前加 /bin/sh -c 執行,有時有可能會出問題。 所以推薦采用數據結構的方式來存放命令。
1.CMD["executable","param1","param2"](exec form,this is the preferred form)
第一種用法:運行一個可執行的文件並提供參數。
2.CMD["param1","param2"](as default parameters to ENTRYPOINT)
第二種用法:為ENTRYPOINT指定參數。
3.CMD command param1 param2(shell form)
第三種用法(shell form): 是以 " /bin/sh -c" 的方法執行的命令。
在啟動 docker時候 后邊加的參數可以把 Dockerfile 中 CMD中的指令覆蓋掉!
寫一個Dockerfile
vim Dockerfile
FROM centos:centos7.1.1503 CMD ["/bin/echo","This is test cmd"]
將Dockerfile生成一個鏡像
docker build -t csphere/cmd:0.1 .
將鏡像run為容器
docker run -it csphere/cmd:0.1
打印:This is test cmd
采用如下run 加入參數時:
docker run -it csphere/cmd:0.1 /bin/bash
會直接進入Container里邊,不會打印語句,/bin/bash 將/bin/echo 覆蓋掉了
然而使用 ENTRYPOINT 時是不能被覆蓋掉
ENTRYPOINT
先回顧下CMD指令的含義,CMD指令可以指定容器啟動時要執行的命令,但它可以被docker run命令的參數覆蓋掉。
ENTRYPOINT 指令和CMD類似,它也可用戶指定容器啟動時要執行的命令,但如果dockerfile中也有CMD指令,CMD中的參數會被附加到ENTRYPOINT 指令的后面。 如果這時docker run命令帶了參數,這個參數會覆蓋掉CMD指令的參數,並也會附加到ENTRYPOINT 指令的后面。
這樣當容器啟動后,會執行ENTRYPOINT 指令的參數部分。
可以看出,相對來說ENTRYPOINT指令優先級更高。
我們來看個例子,下面是Dockerfile的內容
#test
FROM ubuntu
MAINTAINER hello
RUN echo hello1 > test1.txt RUN echo hello2 > /test2.txt EXPOSE 80 ENTRYPOINT ["echo"] CMD ["defaultvalue"]
假設通過該Dockerfile構建的鏡像名為 myimage。
1、當運行 docker run myimage 輸出的內容是 defaultvalue,可以看出CMD指令的參數得確是被添加到ENTRYPOINT指令的后面,然后被執行。
2、當運行docker run myimage hello world 輸出的內容是 hello world ,可以看出docker run命令的參數得確是被添加到ENTRYPOINT指令的后面,然后被執行,這時CMD指令被覆蓋了。
3、另外我們可以在docker run命令中通過 --entrypoint 覆蓋dockerfile文件中的ENTRYPOINT設置,如:
docker run --entrypoint="echo" myimage good 結果輸出good
注意,不管是哪種方式,創建容器后,通過 dokcer ps查看容器信息時,COMMOND列會顯示最終生效的啟動命令。
將上述Dockerfile中的CMD 修改為 ENTRYPOINT
同樣執行:
docker run -it csphere/cmd:0.1 /bin/bash
輸出:
This is test entrypoint /bin/bash
如果想要覆蓋掉Dockerfile中的 ENTRYPOINT 指令,則可以使用如下命令
docker run -it --entrypoint=/bin/bash csphere/ent:0.1
方便調試ENTRYPOINT 中寫錯的指令

