在Windows上构建Docker映像:Entrypoint脚本“无此文件或目录”

时间:2018-11-06 03:44:55

标签: windows docker docker-compose dockerfile

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

我的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"

test-php | standard_init_linux.go:190: exec user process caused "no such file or directory" test-php exited with code 1

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

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

1 个答案:

答案 0 :(得分:3)

因此,即使日志说“没有这样的文件或目录”,实际的问题(至少在我的情况下)是由于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的仓库,则可以在该仓库的.gitattributes文件中进行指定。只需将以下行添加到您的.gitattributes文件中即可。

* text eol=lf

在Git的配置文件中禁用autocrlf

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

enter image description here

更改现有文件的EOL字符。

如果已经有需要转换的现有入口点脚本,或者首先是在Windows中编写入口点脚本,则可以使用最受欢迎的文本编辑器轻松设置EOL类型。我将概述如何在Vim,Notepad ++和Sublime中进行操作,但是通过搜索“ change EOL”和您选择的文本编辑器的名称,应该很容易找出来。

使用Vim

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

使用记事本++

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

使用Sublime

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

从Dockerfile转换EOL字符。

或者,有一个名为dos2unix的有用工具,可以将其安装在映像中并用于转换入口点脚本。假设使用 apt-get 的基于 Ubuntu Debian 的图像,可以按以下方式使用它。

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"]