entrypoint指令用于指定容器启动时必须执行的可执行程序或脚本,比cmd更刚性,决定镜像“身份”;推荐使用exec形式(json数组),pid 1即主进程、信号透传、cmd参数追加;shell形式经/bin/sh -c执行,pid 1为shell、信号不自动转发、cmd通常失效。

ENTRYPOINT 指令用于指定容器启动时**必须执行的可执行程序或脚本**,它比 CMD 更刚性,决定了镜像的“身份”和核心行为。合理使用 ENTRYPOINT,能让镜像更专注、更易复用、更符合 Docker 最佳实践。
理解 ENTRYPOINT 的两种写法及其关键区别
ENTRYPOINT 支持 shell 形式和 exec 形式,二者行为差异显著:
-
Shell 形式(ENTRYPOINT command param1 param2):实际以
/bin/sh -c "command param1 param2"启动,PID 1 是 shell 进程,CMD 或 docker run 后的参数会被忽略(除非配合 exec 形式 CMD);信号(如 SIGTERM)无法直接传给主进程,不利于优雅退出。 - Exec 形式(ENTRYPOINT ["executable", "param1", "param2"]):直接执行目标程序,PID 1 就是该程序,CMD 或 docker run 后的参数会作为追加参数拼接到 ENTRYPOINT 数组末尾——这是推荐写法,支持信号透传、便于覆盖参数、更可控。
用 ENTRYPOINT 封装初始化逻辑,再调用 CMD
典型场景:需要预检查环境、加载配置、等待依赖就绪,再运行用户指定的主命令(如启动应用)。推荐结构如下:
#!/bin/sh
# entrypoint.sh
set -e
<h1>执行初始化动作</h1><p>echo "Running pre-start checks..."
[ -n "$DB_HOST" ] || { echo "Error: DB_HOST is required"; exit 1; }
sleep 2 # 示例:简单等待</p><h1>$@ 会接收 docker run 传入的参数或 Dockerfile 中的 CMD</h1><p>exec "$@"</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/ai/2763" title="Vidu Claw"><img
src="https://img.php.cn/upload/ai_manual/001/246/273/177423622433878.png" alt="Vidu Claw" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/ai/2763" title="Vidu Claw" class="overflowclass">Vidu Claw</a>
<p class="overflowclass">一款AI视频创作工具,主要用于Vidu AI打造的多模态AI视频创作智能体,内置Vidu Skills,支持OpenClaw调用,适合需要提升相关任务效率的用户。</p>
</div>
<a rel="nofollow" href="/ai/2763" title="Vidu Claw" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
对应 Dockerfile:
COPY entrypoint.sh /usr/local/bin/entrypoint.sh RUN chmod +x /usr/local/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"] CMD ["node", "app.js"]
这样运行 docker run myapp npm test 时,entrypoint.sh 先执行检查,再以 exec npm test 启动测试,且 npm 成为 PID 1。
避免常见陷阱
-
不要在 ENTRYPOINT 中后台启动服务:例如
ENTRYPOINT ["nginx", "-g", "daemon off;"]是正确写法;而ENTRYPOINT ["sh", "-c", "nginx &"]会导致容器立即退出(因为前台 sh 结束了)。 -
不要混用 shell 和 exec 形式覆盖:如果 Dockerfile 中 ENTRYPOINT 是 exec 形式,用
docker run --entrypoint /bin/bash可覆盖;但若 ENTRYPOINT 是 shell 形式,则 --entrypoint 可能失效或行为异常。 -
确保 entrypoint 脚本有可执行权限且有正确 shebang:COPY 后务必 RUN chmod +x,并以
#!/bin/sh开头(避免依赖 bash 特性,提升兼容性)。
何时该用 ENTRYPOINT,何时只用 CMD?
简单判断标准:
- 用 ENTRYPOINT:镜像有明确、固定的核心职责(如 mysql 镜像总要运行 mysqld,redis 镜像总要运行 redis-server),用户不应轻易替换主程序,只应调整其参数。
- 用 CMD 单独:镜像是通用运行环境(如 ubuntu、node),用户需自由指定启动命令,此时 ENTRYPOINT 反而限制灵活性。
- 组合使用(推荐多数自定义应用镜像):ENTRYPOINT 封装启动流程,CMD 提供默认参数,兼顾健壮性与可定制性。










