ENTRYPOINT 是 Docker 定义容器启动命令的关键指令,设定“容器本身是什么”,CMD 提供默认参数;推荐使用 exec 形式以支持参数覆盖和信号传递,须确保主进程前台运行。

ENTRYPOINT 是 Docker 中定义容器启动时默认执行命令的关键指令,特别适合将容器用作长期运行的服务(如 Web 服务器、数据库、消息队列等)。它与 CMD 协同工作,但语义更明确:**ENTRYPOINT 设定“容器本身是什么”,CMD 提供其默认“参数”**。
ENTRYPOINT 的两种写法及其适用场景
• Shell 形式:ENTRYPOINT command param1 param2
Docker 会将其包装进 /bin/sh -c 执行,无法直接接收 docker run 后追加的参数,适合简单固定启动逻辑(如 ENTRYPOINT nginx -g "daemon off;")。
• Exec 形式(推荐):ENTRYPOINT ["executable", "param1", "param2"]
以数组方式调用,不经过 shell,可完整继承 docker run 后的参数,适合需要灵活覆盖或调试的生产服务(如 ENTRYPOINT ["java", "-jar", "/app.jar"])。
让服务在前台运行是关键前提
Docker 容器生命周期由主进程(PID 1)决定。若 ENTRYPOINT 启动的进程后台化(如默认 daemon 模式),容器会立即退出。
• Nginx:必须加 -g "daemon off;"
• Redis:使用 redis-server /etc/redis.conf 并确保配置中 daemonize no
• Spring Boot:JAR 默认前台运行,无需额外处理
• 自定义脚本:避免 & 或 nohup,确保最终命令阻塞执行
结合 CMD 实现可覆盖的默认参数
当 ENTRYPOINT 使用 exec 形式时,CMD 的值会作为参数追加到 ENTRYPOINT 命令之后:
• ENTRYPOINT ["python", "app.py"]
CMD ["--port", "8000"] → 等效于 python app.py --port 8000
• 运行时可覆盖:
docker run myimage --port 9000 --debug → 执行 python app.py --port 9000 --debug,忽略原 CMD
调试与信号传递注意事项
• 使用 exec 形式时,ENTRYPOINT 进程直接成为 PID 1,能正确接收 SIGTERM,支持优雅关闭;shell 形式下信号可能无法透传给子进程。
• 若需初始化逻辑(如生成配置、等待依赖就绪),建议封装为一个启动脚本:
ENTRYPOINT ["./entrypoint.sh"]
其中 entrypoint.sh 最后一行应为 exec "$@"(确保替换当前 shell 进程,不丢失信号)










