

内容声明
本文仅用于技术分享和学习交流,内容不包含任何广告、推广、引流、付费课程或外链信息。所有示例和配置均为技术实践,欢迎参考和自定义。
本文聚焦 Docker 启动时 "entrypoint.sh" 存在却执行失败的问题,梳理 CRLF、权限、shebang、挂载覆盖、架构不匹配与 EOL 镜像仓库异常等根因,提供诊断命令与修复路径,并给出兼顾稳定性与可维护性的 Dockerfile、CI 与镜像升级建议。
明明把 entrypoint.sh 打进了镜像,容器一启动却直接退出。报错信息经常是 no such file or directory、permission denied,或者 exec format error。这类问题看起来像是"文件丢了",但多数时候原因不在文件本身。下面按常见场景拆解原因,并给出排查思路和修复方式。
容器在启动阶段失败,通常由以下原因引起:
以上问题都可能让容器在执行入口脚本时失败。
如果脚本使用 Windows 的 CRLF 行尾,shebang 行末会带 ^M。内核会把解释器路径识别为带回车符的路径,最终找不到解释器。此时常见报错是 no such file or directory。
脚本在镜像内必须具备执行位,某些平台上的宿主机绑定挂载可能丢失执行位。此时常见报错是 permission denied。
脚本可能写了 #!/bin/bash,但镜像里只有 /bin/sh。例如 Alpine 镜像默认使用 BusyBox sh。解释器路径错误时,脚本同样无法执行。
如果将宿主机目录挂载到 /PATH,会覆盖镜像内 /PATH 的内容。若宿主机目录没有 entrypoint.sh,容器就找不到入口脚本。
如果入口文件是二进制,且架构与运行平台不一致,会触发 exec format error。例如在 x86 环境执行 ARM 二进制。
旧版发行版 (如 buster) 可能已归档。构建时 apt-get update、apt-get install 可能返回 404 或 502。这会影响安装 dos2unix 等工具,间接导致行尾修复失败。
docker run --rm -it --entrypoint /bin/sh IMAGE_NAMEdocker-compose run --rm SERVICE_NAME shls -l /PATH/entrypoint.shstat /PATH/entrypoint.shhead -n1 /PATH/entrypoint.sh | sed -n lfile /PATH/entrypoint.shod -c /PATH/entrypoint.sh | head这组命令可以快速确认权限、行尾、解释器和文件类型。
建议通过 .gitattributes 强制 shell 脚本使用 LF:
# .gitattributes
*.sh text eol=lf同时在 CI 中加入行尾检查,避免问题进入镜像构建阶段。
Debian 系镜像可用 sed 去除 CR:
FROM node:10-buster
COPY entrypoint.sh /PATH/entrypoint.sh
RUN sed -i 's/\r$//' /PATH/entrypoint.sh \
&& chmod +x /PATH/entrypoint.sh
ENTRYPOINT ["/PATH/entrypoint.sh"]也可使用 tr:
RUN tr -d '\r' < /PATH/entrypoint.sh > /PATH/entrypoint.sh.new && mv /PATH/entrypoint.sh.new /PATH/entrypoint.sh在 bookworm-slim 中可直接安装:
FROM debian:bookworm-slim
COPY entrypoint.sh /PATH/entrypoint.sh
RUN apt-get update \
&& apt-get install -y --no-install-recommends dos2unix \
&& dos2unix /PATH/entrypoint.sh \
&& chmod +x /PATH/entrypoint.sh \
&& rm -rf /var/lib/apt/lists/*如果使用旧版镜像 (如 node:10-buster),apt 可能不可用。此时优先使用 sed 或 tr 方案,避免依赖 apt。
可在宿主机设置:
chmod +x entrypoint.sh也可在 Dockerfile 中设置:
RUN chmod +x /PATH/entrypoint.sh#!/bin/sh。/bin/bash,但精简镜像可能仅有 /bin/sh。ENTRYPOINT 显式调用 shell:ENTRYPOINT ["sh", "/PATH/entrypoint.sh"]node:10-buster 为例)问题是 buster 仓库已归档,apt 更新失败。可选方案如下:
node:18、node:20-bullseye、node:20-bookworm。sed 或 tr 处理 CRLF。FROM node:10-buster
RUN sed -i 's|http://deb.debian.org/debian|http://archive.debian.org/debian|g' /etc/apt/sources.list \
&& sed -i 's|http://security.debian.org/debian-security|http://archive.debian.org/debian-security|g' /etc/apt/sources.list || true \
&& echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf.d/99no-check-valid-until \
&& apt-get update -o Acquire::Check-Valid-Until=false \
&& apt-get install -y --no-install-recommends dos2unix \
&& rm -rf /var/lib/apt/lists/*该方案存在安全风险。归档仓库不再维护,应尽快升级镜像。
如果在 docker-compose 中挂载 ./PATH:/PATH,宿主机目录会覆盖镜像目录。当宿主机目录缺少入口脚本时,容器就无法找到它。
示例 (风险配置):
volumes:
- ./PATH:/PATHWindows 绑定挂载可能不保留执行位。可采用以下方式降低风险:
ENTRYPOINT ["sh", "/PATH/entrypoint.sh"]。若入口为二进制文件,请确认其架构与目标平台一致,例如 ARM 二进制不能直接在 x86 环境执行。可使用多架构镜像,或按目标平台重新构建二进制。
下面方案体积小、依赖少、稳定性高:
FROM debian:bookworm-slim
WORKDIR /PATH
COPY entrypoint.sh /PATH/entrypoint.sh
RUN sed -i 's/\r$//' /PATH/entrypoint.sh \
&& chmod +x /PATH/entrypoint.sh
ENTRYPOINT ["/PATH/entrypoint.sh"]在仓库中启用 .gitattributes,统一脚本行尾为 LF。
在 CI 增加检查步骤:
git grep -I --name-only $'\r' || true同时统一编辑器设置,确保仓库文件默认保存为 LF。
排查时建议按以下顺序执行:
ls -l、head -n1 | sed -n l 检查权限与行尾。sed 方案,或直接升级基础镜像。entrypoint.sh 存在却无法执行时,最常见根因是 CRLF 行尾。建议优先在源码和 CI 中统一 LF。如果需要在镜像内快速修复,可使用 sed -i 's/\r$//'。同时请确认执行位、解释器路径和挂载配置正确。对于 EOL 镜像,应尽快升级到受支持版本,以减少构建和安全风险。
版权声明
本文为原创文章,作者保留版权。转载请保留本文完整内容,并以超链接形式注明作者及原文出处。
作者: 除除
原文: http://blog.mazey.net/6215.html
(完)
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。