【问题标题】:Building Docker images on Windows: Entrypoint script "no such file or directory"在 Windows 上构建 Docker 映像:入口点脚本“没有这样的文件或目录”
【发布时间】:2018-11-06 03:44:54
【问题描述】:

我在这上面浪费了两天时间,直到我终于弄清楚了我的问题,所以我想我会分享。我将在这里概述我遇到的问题,然后在答案中概述解决方案。

我的Dockerfile 看起来像这样,

FROM php:7.2-fpm

COPY custom-docker-php-entrypoint /usr/local/bin/

ENTRYPOINT ["custom-docker-php-entrypoint"]

我在同一目录中有一个文件custom-docker-php-entrypont

#!/bin/sh

set -e

# first arg is `-f` or `--some-option`
if [ "${1#-}" != "$1" ]; then
    set -- php "$@"
fi

exec "$@"

但是,当我运行 docker-compose up -d 然后运行 ​​docker-compose logs -f 时,我的 php 容器显示为失败,exit code 1exec user process caused "no such file or directory"

然后,我使用不同的入口点命令加载容器,并使用 bash 查看内部并确认文件正在复制到我预期的位置。

我想,“也许这是权限问题?”所以我尝试设置chmod 777 custom-docker-php-entrypoint,但这也没有解决我的问题。我还尝试使用chmod -x custom-docker-php-entrypoint 将其设置为可执行文件,但这也无济于事。

【问题讨论】:

    标签: windows docker docker-compose dockerfile


    【解决方案1】:

    因此,即使日志显示“没有这样的文件或目录”,实际问题(至少在我的情况下)是由于 Windows 和 Linux 上的行尾 (EOL) 字符不同造成的。 Windows 使用CRLF 表示行尾,Unix/Linux 使用LF

    我没有认为这是一个潜在的问题,因为这些文件是从 Github 新克隆的并且最初是在 Linux 上创建的。我不知道的是,在 Windows 上 Git 设置为自动将 EOL 字符转换为 CRLF

    使 Git 保留原始 EOL 字符(禁用 autocrlf)。

    有几种方法可以做到这一点。 autocrlf 是决定 git 是否转换行尾的属性名称。您只需要根据需要执行以下选项之一。

    对一个命令禁用autocrlf

    您可以使用以下内容克隆文件以一次性禁用 autocrlf

    git clone https://github.com/someuser/somerepo --config core.autocrlf=false
    

    .gitattributes 中指定 EOL 类型

    如果您知道要始终禁用 autocrlf 的单个 repo,您​​可以在该 repo 的 .gitattributes 文件中指定它。只需将以下行添加到您的 .gitattributes 文件中。

    * text eol=lf
    

    在 Git 的配置文件中禁用 autocrlf

    导航到您机器上安装 Git 的文件夹。对我来说,它安装在C:\ProgramData\Git。在文本编辑器中打开 config。将autocrlf=true 更改为autocrlf=false

    更改现有文件的 EOL 字符。

    如果您有需要转换的现有入口点脚本,或者如果您首先在 Windows 中编写入口点脚本,则可以使用最流行的文本编辑器轻松设置 EOL 类型。我将概述如何在 Vim、Notepad++ 和 Sublime 中执行此操作,但通过搜索“更改 EOL”和您选择的文本编辑器的名称应该很容易弄清楚。

    使用 Vim

    要将行尾更改为与 Linux 兼容,请执行 :set ff=unix。要更改它们以使其与 Windows 兼容,请执行:set ff=dos

    使用记事本++

    在菜单栏上单击Edit,然后转到EOL Conversion 并选择所需的转换。您需要选择 Unix (LF) 以使其与 Linux 兼容。

    使用崇高

    在菜单栏上单击“查看”并转到“行尾”,然后从那里选择所需的转换。您需要选择 Unix 以使其与 Linux 兼容。

    从 Dockerfile 转换 EOL 字符。

    另外,还有一个名为dos2unix 的有用工具,您可以将其安装在映像中并用于转换入口点脚本。假设基于 UbuntuDebian 的映像使用 apt-get ,您可以通过以下方式使用它。

    FROM php:7.2-fpm
    
    RUN apt-get update && \
        apt-get install -y dos2unix
    
    COPY custom-docker-php-entrypoint /usr/local/bin/
    
    RUN dos2unix /usr/local/bin/custom-docker-php-entrypoint
    
    ENTRYPOINT ["custom-docker-php-entrypoint"]
    

    如果你的 Docker 镜像是基于 Alpine linux 使用 apk 作为包管理器,你会想要做这样的事情,

    FROM alpine:latest
    
    RUN apk --update add bash && \
        apk add dos2unix
    
    COPY entrypoint.sh /
    
    RUN dos2unix /entrypoint.sh
    
    ENTRYPOINT ["/entrypoint.sh"]
    

    如果你的 Docker 镜像是基于 Centos 使用 yum 作为包管理器,你会想要做这样的事情,

    FROM centos:latest
    
    RUN yum update -y && \
        yum install dos2unix -y
    
    COPY entrypoint.sh /
    
    RUN dos2unix /entrypoint.sh
    
    ENTRYPOINT ["/entrypoint.sh"]
    

    【讨论】:

    • 我使用的是 Windows 10 x64...我在项目中的每个文件上递归地运行了 dos2unix.exe。我在我的 Dockerfile 中添加了 apt-get install dos2unixRUN dos2unix。没有任何效果。我想死。互联网上的这些线路结束解决方案对我不起作用
    • 也许会考虑文件实际上没有找到的可能性?好像其中一条路径中有错字?或者可能是权限错误导致文件看起来好像找不到?
    猜你喜欢
    • 2021-05-26
    • 1970-01-01
    • 1970-01-01
    • 2019-11-23
    • 2020-04-05
    • 2022-11-17
    • 2016-02-10
    • 1970-01-01
    • 2020-04-18
    相关资源
    最近更新 更多