CMD
支持三種格式
CMD [“executable”,”param1”,”param2”] 使用 exec 執行,推薦方式;
CMD command param1 param2 在 /bin/sh 中執行,提供給需要交互的應用;
CMD [“param1”,”param2”] 提供給 ENTRYPOINT 的默認參數;
指定啟動容器時執行的命令,每個 Dockerfile 只能有一條 CMD 命令。如果指定了多條命令,只有最后一條會被執行。
如果用戶啟動容器時候指定了運行的命令,則會覆蓋掉 CMD 指定的命令。
ENTRYPOINT
兩種格式:
ENTRYPOINT [“executable”, “param1”, “param2”]
ENTRYPOINT command param1 param2(shell中執行)。
配置容器啟動后執行的命令,並且不可被 docker run 提供的參數覆蓋。
每個 Dockerfile 中只能有一個 ENTRYPOINT,當指定多個時,只有最后一個起效。
從以上內容中可以看出,可以看到有兩個共同點:
1.都可以指定shell或exec函數調用的方式執行命令;
2.當存在多個CMD指令或ENTRYPOINT指令時,只有最后一個生效;
但是在涉及到使用變量的時候只有shell的方式才可以,exec函數的形式不行
舉例來說:
# Dockerfile文件內容
ENTRYPOINT [ "yarn", "run", "app-${ENV_CONFIG_INT}" ]
# Compose yaml
test:
image: testimage/test:v1.0
build:
context: .
dockerfile: Dockerfile
env_file:
- ./docker.env
environment:
- ENV_CONFIG_INT=1
如上形式啟動的時候會報錯:
error Command "app-${ENV_CONFIG_INT}" not found.
這是因為ENTRYPOINT(以及CMD和RUN)的shell形式支持擴展環境變量,但是使用exec形式不擴展變量或處理任何其他shell構造。
也就是說使用要想處理變量的話,必須使用shell形式,也就是
CMD command param1 param2 在 /bin/sh 中執行,提供給需要交互的應用;
ENTRYPOINT command param1 param2(shell中執行)。
比如啟動jar包文件
# 使用如下這種形式設置變量就不行
ENTRYPOINT ["java","${PARAMS}","${JAVA_OPTS}","-Djava.security.egd=file:/dev/./urandom","-jar","demo-0.0.1-SNAPSHOT.jar"]
# 可以使用這種形式
ENTRYPOINT ["sh", "-c", "java ${PARAMS} ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar demo-0.0.1-SNAPSHOT.jar"]
ENTRYPOINT java ${PARAMS} ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar demo-0.0.1-SNAPSHOT.jar
擴展
exce形式和shell形式的區別
shell表單阻止使用任何CMD或run命令行參數,但其缺點是ENTRYPOINT將作為/bin/sh-c的子命令啟動,該子命令不傳遞信號。這意味着可執行文件不會是容器的PID 1,也不會接收Unix信號,因此您的可執行文件不會從docker stop