Docker for Windows 中“executable file not found”和“no such file”问题

    xiaoxiao2026-03-30  10

    引子

    昨天收到一封读者来信,他参考“使用Docker Compose部署Redis集群“一文,在Windows环境中执行 docker-compose up 命令时遇到了下面的问题

    ERROR: for sentinel Cannot start service sentinel: oci runtime error: container_linux.go:247: starting container proces s caused "exec: \"sentinel-entrypoint.sh\": executable file not found in $PATH"

    其中“sentinel”容器的 Dockerfile 如下,

    FROM redis:3 MAINTAINER Li Yi <denverdino@gmail.com> EXPOSE 26379 ADD sentinel.conf /etc/redis/sentinel.conf RUN chown redis:redis /etc/redis/sentinel.conf ENV SENTINEL_QUORUM 2 ENV SENTINEL_DOWN_AFTER 30000 ENV SENTINEL_FAILOVER 180000 COPY sentinel-entrypoint.sh /usr/local/bin/ ENTRYPOINT ["sentinel-entrypoint.sh"]

    这个问题在Mac/Linux上不存在,因为sentinel-entrypoint.sh文件已经拥有了可执行权限。为了解决Windows环境中文件权限的缺失,我做了第一个修正,在Dockerfile中为sentinel-entrypoint.sh 添加可执行权限。Github commit地址 ,修改片段如下

    COPY sentinel-entrypoint.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/sentinel-entrypoint.sh ENTRYPOINT ["sentinel-entrypoint.sh"]

    令人困惑的CRLF

    然而很快他又反馈,虽然上述问题已经修正,但是sentinel容器依然启动失败,在执行docker logs rediscluster_sentinel_1 命令时,得到如下异常。

    standard_init_linux.go:175: exec user process caused "no such file or directory"

    因为手头只有Mac和Linux环境,无法复现问题。直到晚上回家后找了一台Windows机器,观察了一下才有了头绪。因为sentinel-entrypoint.sh中最后一行的结束符成了\r\n 导致Docker镜像中的Linux Shell脚本文件无法执行。

    #!/bin/sh sed -i "s/\$SENTINEL_QUORUM/$SENTINEL_QUORUM/g" /etc/redis/sentinel.conf sed -i "s/\$SENTINEL_DOWN_AFTER/$SENTINEL_DOWN_AFTER/g" /etc/redis/sentinel.conf sed -i "s/\$SENTINEL_FAILOVER/$SENTINEL_FAILOVER/g" /etc/redis/sentinel.conf exec docker-entrypoint.sh redis-server /etc/redis/sentinel.conf --sentinel

    Linux/Mac的结束符是\n,所以Shell解释器会将脚本文件中的\r作为命令行的一部分来执行。这就是出现 “no such file or directory” 的原因。

    定位问题之后,修正也很简单。我的做法是利用 dos2unix sentinel-entrypoint.sh命令将其转换成为unix格式文件。 这样问题就解决了。

    问题的根源是Git for Windows默认会将文本文件中的换行符强制转为DOS格式。这可以通过修改缺省设置 git config --global core.autocrlf false 再重新git clone项目来解决。但如果使用文本编辑器修改过文件,还是需要利用dos2unix转换修正换行符。

    总结

    用Google搜了一下,这两个问题在Windows上构建Docker镜像时中非常普遍,即使很多官方镜像也无法直接在Windows上编译成功。Windows的真爱粉在使用Docker时可以使用文中方法解决这些问题。

    感谢大家在2016年的支持,2017新年快乐!

    想了解更多容器服务内容,请访问 https://www.aliyun.com/product/containerservice

    相关资源:python入门教程(PDF版)
    最新回复(0)