Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Building Docker images on Windows: Entrypoint script "no such file or directory"

I wasted two days on this until I finally figured out my problem, so I thought I'd share. I'll outline the problem I was having here, and then outline the solutions in the answer.

My Dockerfile looked something like this,

FROM php:7.2-fpm

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

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

I had a file custom-docker-php-entrypont in the same directory.

#!/bin/sh

set -e

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

exec "$@"

However, when I ran docker-compose up -d and then docker-compose logs -f my php container show as failing with exit code 1 saying exec 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

I then loaded up the container with a different entrypoint command and used bash to look inside and confirm that the file was being copied into the location that I expected it to be.

I thought, "Maybe this is a permissions thing?" so I tried setting chmod 777 custom-docker-php-entrypoint, but that also didn't solve my problem. I also tried setting it to executable with chmod -x custom-docker-php-entrypoint, but that also didn't help.

like image 881
Michael Avatar asked Nov 06 '18 03:11

Michael


1 Answers

So, even though logs say "no such file or directory," the actual problem (at least in my case) was due to the difference in end-of-line (EOL) characters on Windows and Linux. Windows uses CRLF represent the end of a line and Unix/Linux uses LF.

I hadn't consider this as a potential problem since the files were freshly cloned from Github and were originally created on Linux. What I didn't know is that on Windows Git is set up to automatically convert EOL characters to CRLF.

Making Git retain original EOL characters (disabling autocrlf).

There are a few ways to go about doing this. autocrlf is the name of the attribute that decides whether git converts line endings. You'd only need to do one of the following options depending on what you need.

Disable autocrlf for one command

You can clone the files with the following to disable autocrlf as just a one time thing.

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

Specify EOL type in .gitattributes

If you have a single repo that you know you want to always have autocrlf disabled, you can specify it in that repo's .gitattributes file. Just add the following line to your .gitattributes file.

* text eol=lf

Disable autocrlf in Git's config file

Navigate to the folder where Git is installed on your machine. For me it was installed at C:\ProgramData\Git. Open config in a text editor. Change autocrlf=true to autocrlf=false.

enter image description here

Changing EOL characters on existing files.

If you've got existing entrypoint scripts that you need to convert, or if you're writing your entrypoint scripts in Windows in the first place, you can easily set the EOL type with most popular text editors. I'll outline how to do it in Vim, Notepad++, and Sublime, but it should be easy enough to figure out by searching "change EOL" and the name of your text editor of choice.

Using Vim

To change the line endings to be compatible with Linux, do :set ff=unix. To change them so that they are compatible with Windows, do :set ff=dos.

Using Notepad++

On the menu bar click on Edit and then go to EOL Conversion and select the desired conversion. You'll want to select Unix (LF) to make it compatible with Linux.

Using Sublime

On the menu bar click 'View' and go to 'Line Endings' and from there select the desired conversion. You'll want to select Unix to make it compatible with Linux.

Converting EOL characters from your Dockerfile.

Alternatively, there's a useful tool called dos2unix that you can install in your image and use to convert your entrypoint script. Assuming an Ubuntu or Debian based image which uses apt-get , you can use it in the following way.

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

If your Docker image is based on Alpine linux using apk for a package manager, you'll want to do something like this,

FROM alpine:latest

RUN apk --update add bash && \
    apk add dos2unix

COPY entrypoint.sh /

RUN dos2unix /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]

If your Docker image is based on Centos using yum as a package manager, you'll want to do something like this,

FROM centos:latest

RUN yum update -y && \
    yum install dos2unix -y

COPY entrypoint.sh /

RUN dos2unix /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]
like image 77
Michael Avatar answered Nov 01 '22 11:11

Michael