Why won't my docker-entrypoint.sh execute? - docker

My ENTRYPOINT script doesn't execute and throws standard_init_linux.go:175: exec user process caused "no such file or directory". Why so?
Doesn't Work
$ docker build -t gilani/trollo . && docker run gilani/trollo
Sending build context to Docker daemon 126 kB
Step 1 : FROM vault:latest
---> 1f127f53f8b5
Step 2 : MAINTAINER Amin Shah Gilani <gilani#payload.tech>
---> Using cache
---> 86b885ca1c81
Step 3 : COPY vaultConfig.json /vault/config
---> Using cache
---> 1a2be2fa3acd
Step 4 : COPY ./docker-entrypoint.sh /
---> Using cache
---> 0eb7c1c992f1
Step 5 : RUN chmod +x /docker-entrypoint.sh
---> Running in 251395c4790f
---> 46aa0fbc9637
Removing intermediate container 251395c4790f
Step 6 : ENTRYPOINT /docker-entrypoint.sh
---> Running in 7434f052178f
---> eca040859bfe
Removing intermediate container 7434f052178f
Successfully built eca040859bfe
standard_init_linux.go:175: exec user process caused "no such file or directory"
Dockerfile:
FROM vault:latest
MAINTAINER Amin Shah Gilani <gilani#payload.tech>
COPY vaultConfig.json /vault/config
COPY ./docker-entrypoint.sh /
RUN chmod +x /docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]
docker-entrypoint.sh:
#!/bin/bash
echo 'Hello World!'
Works
$ docker build -t gilani/trollo . && docker run gilani/trollo
Sending build context to Docker daemon 126 kB
Step 1 : FROM vault:latest
---> 1f127f53f8b5
Step 2 : MAINTAINER Amin Shah Gilani <gilani#payload.tech>
---> Using cache
---> 86b885ca1c81
Step 3 : COPY vaultConfig.json /vault/config
---> Using cache
---> 1a2be2fa3acd
Step 4 : ENTRYPOINT echo 'hello world'
---> Using cache
---> ef5792a1f252
Successfully built ef5792a1f252
'hello world'
Dockerfile:
FROM vault:latest
MAINTAINER Amin Shah Gilani <gilani#payload.tech>
COPY vaultConfig.json /vault/config
ENTRYPOINT ["echo", "'hello world'"]

I was tearing my hair out with an issue very similar to this. In my case /bin/bash DID exist. But actually the problem was Windows line endings.
In my case the git repository had an entry point script with Unix line endings (\n). But when the repository was checked out on a windows machine, git decided to try and be clever and replace the line endings in the files with windows line endings (\r\n).
This meant that the shebang didn't work because instead of looking for /bin/bash, it was looking for /bin/bash\r.
The solution for me was to disable git's automatic conversion:
git config --global core.autocrlf input
Then check out the repository again and rebuild.
Some more helpful info here:
How to change line-ending settings
and here
http://willi.am/blog/2016/08/11/docker-for-windows-dealing-with-windows-line-endings/

the vault:latest image does not contain /bin/bash which you try to call with your shebang #!/bin/bash. You should either change that to #!/bin/sh or completely remove the shebang from your script.

Another possibility:
Check that the file is not saved with Windows line endings (CRLF). If it is, save it with Unix line endings (LF) and it will be found.

Without seeing your image, my initial idea is that you don't have /bin/bash in your image. Changing the first line of your docker-entrypoint.sh to:
#!/bin/sh
will likely resolve it.

I struggled for hours because I haven't noticed anywhere explained that you need to copy the file in the location where the VM can access the file, preferably globally like so:
COPY docker-entrypoint.sh /usr/local/bin/
(I had thought it should just be automatically accessible since it's part of the dockerfile context)

Gosh I struggled for 2–3 hours!!
Thanks to #Ryan Allen
For my case it was CRLF problem. I am working on puppet manifests over ATOM for jenkins setup.
Make sure if you are using ATOM or any other IDE on windows, when you take your file ( especially .sh) to unix, convert it to unix format. It worked like magic once converted.
Here is what I added in my puppet file:
exec {'dos2unix':
path => ['/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/opt/puppetlabs/bin'],
command => 'dos2unix /dockerwork/puppet/jenkins/files/*',
subscribe => File['/dockerwork/puppet/jenkins/files/init.sh'],
}

I came here with a similar issue while troubleshooting my attempt to build a Dockerfile "entry point" (entrypoint.sh) bash shell script (to be executed within the .NET Core SDK 2.2 image). The start of the script had the line #!/bin/bash, and during execution of docker-compose up (after successfully building with docker-compose build, the logging reported web_1 | ./entrypoint.sh: line 1: #!/bin/bash: No such file or directory.
Checking the file with VS Code, I noticed it was reporting the following encoding:
UTF-8 with BOM
Clicking on this, I would get the option to Save with encoding:
I chose to save as UTF-8 (utf8), which resolved the issue.
NOTE: I also found this SO article What's the difference between UTF-8 and UTF-8 without BOM?

My case was that the alpine image I was using didn't come with bash at all...
RUN apk-install bash did the trick obviously

Another reason this error comes up is if your Windows User password changes.
In my case my entrypoint.sh line endings were LF but I was still getting the error. Our admin has a mandatory password reset about every month or so. Whenever this happens I would run into the error. If this is your reason you may need to reset your credentials in docker settings under "Shared Drives".
Unselect the drive and apply. Then reselect the drive and apply. It will prompt you for your password.

This problem is to do with line endings and I solved it with the solution below
Convert the DOS file to a unix format. This removes any wired line endings.
dos2unix - is available in alpine as well as other Linux distributions.
I used it like so: RUN apk add dos2unix && dos2unix /entry.sh

Sorry for hacking -- this is not a response to the question, but a description of a different problem and it's solution that has the same symptoms.
I had
ENTRYPOINT ["/usr/bin/curl", "-X", "POST", "http://myservice:8000", \
"-H", "Content-Type: application/json", \
"-d", '{"id": "test"}' \
]
I was getting the error:
/bin/bash: [/usr/bin/curl,: No such file or directory
It turns out it's the single quotes that messed it up. Docker documentation has a note:
The exec form is parsed as a JSON array, which means that you must use double-quotes (“) around words not single-quotes (‘).
Blockquote
Solution -- use double quotes instead of single and escape nested double quotes:
ENTRYPOINT ["/usr/bin/curl", "-X", "POST", "http://myservice:8000", \
"-H", "Content-Type: application/json", \
"-d", "{\"id\": \"test\"}" \
]

None of the solutions worked for me but I was able to solve the error by setting WORKDIR to the same directory that contained the entrypoint script. No amount of cd'ing would work but somehow WORKDIR solved it

Related

Why is docker not completely deleting my file?

I am trying to build using:
FROM mcr.microsoft.com/dotnet/core/sdk:2.1 AS builder
COPY pythonnet/src/ pythonnet/src
WORKDIR /pythonnet/src/runtime
RUN dotnet build -f netstandard2.0 -p:DefineConstants=\"MONO_LINUX\;XPLAT\;PYTHON3\;PYTHON37\;UCS4\;NETSTANDARD\" Python.Runtime.15.csproj
# copy myApp csproj and restore
COPY src/myApp/*.csproj /src/myApp/
WORKDIR /src/myApp
RUN dotnet restore
# now copy everything else as separate docker step
# (copy to staging folder, remove csproj, and copy down - so we don't overwrite project above)
WORKDIR /
COPY src/myApp/ ./staging/src/myApp
RUN rm ./staging/src/myApp/*.csproj \
&& cp -r ./staging/* ./ \
&& rm -rf ./staging
This was working fine, and in Windows 10 still does, but in CentOS 7 I get:
Step 10/40 : RUN rm ./staging/src/myApp/*.csproj && cp -r ./staging/* ./ && rm -rf ./staging
---> Running in 6b17ae0fae89
cp: cannot stat './staging/src/myApp/myApp.csproj': No such file or directory
Using ls instead of cp throws a similar file not found error, so it looks like Docker still knows about myApp.csproj but cannot see it since it has been removed.
Is there a way around this? I have tried using rsync but similar problems.
I simply ignored the issue by tacking on ;exit 0 on the offending lines. Not great, but does the job.
EDIT: This worked for me as I cannot upgrade the version of CemtOS. If you can, check out Alexander Block's answer.
I don't know specifically how to solve this problem as there's a lot of context in the filesystem that you haven't (and probably can't) share with us.
My suggestion on a strategy is that you:
comment out all lines from the failing one 'til the end of the Dockerfile
build the partial image
docker exec -it [image] bash to jump into the image
poke around and figure out what's going wrong
repeat 1-4 until things work as expected
It's not as fun as a perfectly insightful answer of course but this is a relentlessly effective algorithm even if it's tedious and annoying.
EDIT
My wild guess is that somehow, someway the linux machine doesn't have the file where it's expected for some reason and so it doesn't get copied into the image at all and that's why the docker build process can't find it. But there's no way to know without debugging the build process.
cp -r will stop and fail with that cannot stat <file> message whenever the source is a symbolic link and the target of the link does not exist. It will not copy links to non-existent files.
So my guess is that after you run COPY src/myApp/ ./staging/src/myApp your file ./staging/src/myApp/myApp.csproj is a symbolic link to a non-existent file. Why the following RUN rm ./staging/src/*.csproj doesn't remove it and stays silent about that, I don't know the answer to that.
To help demonstrate my theory, see below showing cp failing on a symlink on Centos 7.
[547] $ docker run --rm -it centos:7
Unable to find image 'centos:7' locally
7: Pulling from library/centos
524b0c1e57f8: Pull complete
Digest: sha256:e9ce0b76f29f942502facd849f3e468232492b259b9d9f076f71b392293f1582
Status: Downloaded newer image for centos:7
[root#a47b77cf2800 /]# ln -s /tmp/foo /tmp/bar
[root#a47b77cf2800 /]# ls -l /tmp/foo
ls: cannot access /tmp/foo: No such file or directory
[root#a47b77cf2800 /]# ls -l /tmp/bar
lrwxrwxrwx 1 root root 8 Jul 6 05:44 /tmp/bar -> /tmp/foo
[root#a47b77cf2800 /]# cp /tmp/foo /tmp/1
cp: cannot stat '/tmp/foo': No such file or directory
[root#a47b77cf2800 /]# cp /tmp/bar /tmp/2
cp: cannot stat '/tmp/bar': No such file or directory
Notice how you copy reports that it cannot stat either the source or destination of the symbolic link. It's the exact symptom you are seeing.
If you just want to get past this, you can try tar instead of cp or rsync.
Instead of
cp -r ./staging/* ./
use this instead:
tar -C ./staging -cf - . | tar -xf -
tar will happily copy symlinks that don't exist.
You've very likely encountered a kernel bug that has been fixed a long time ago in more recent kernels. As of https://de.wikipedia.org/wiki/CentOS, CentOS 7 is based on the Linux Kernel 3.10, which is pretty old already and does not have good Docker support in regard to the storage backend (overlay filesystem).
CentOS tried to backport needed fixes and features into 3.10, but seems to not have succeeded fully when it comes to overlay support. There are multiple (slightly different) issues regarding this which you can find when searching for "CentOS 7 overlay driver" on the internet. All of them have in common that removing of files from parent overlays does not work as expected.
For me it looks like rm calls on files return success, even though the files are not fully removed. Directory listings (e.g. by ls or shell expansion as in your case) then still list the file, while accessing the file then fails (no matter if read, write or deletion of the file).
I assume that what you've seen is just another incarnation of these issues. You should either switch to CentOS 8 or upgrade your Kernel (which is not officially supported by CentOS as far as I understand). Or even more radical, switch to a distribution which is used more often in combination with Docker and generally offers more recent Kernels, e.g. Debian or Ubuntu.

/bin/sh: 1: /go/src/test.sh: not found

I am trying to build this dockerfile, the file is copied successfully but I keep getting the following error:
docker build --no-cache=true -f Dockerfile-Gobase .
Sending build
context to Docker daemon 34MB
Step 1/3 : FROM golang:1.11.2 ---> df6ac9d1bf64
Step 2/3 : COPY ./test.sh /go/src/ ---> 38a538f0289d
Step 3/3 : RUN (ls -l /go/src/ && cd /go/src/ && /go/src/test.sh)
---> Running in 089de53d11f0
total 4
-rwxr-xr-x 1 root root 34 Jan 24 03:22 test.sh
/bin/sh: 1: /go/src/test.sh: not found
The command '/bin/sh -c (ls -l /go/src/ && cd /go/src/ &&
/go/src/test.sh)' returned a non-zero code: 127
These are the file codes
Dockerfile-Gobase
FROM golang:1.11.2
COPY ./test.sh /go/src/
RUN (ls -l /go/src/ && cd /go/src/ && /go/src/test.sh)
test.sh
#!/bin/sh
echo "hello world"
You eliminated the first cause by checking that the script exists in the container with an ls. This also eliminated Linux file permissions.
Next possible cause is that your interpreter isn't in the container, but showing the script we see that it's #!/bin/sh. And /bin/sh is included with your base image.
What's left that I can think of are windows line feeds in the file, a missing library somewhere, or perhaps security tools like SE Linux/AppArmor with a strict configuration. In this case, it looks like windows line feeds were there cause. You just need to configure your editor to output with Linux style line feeds. Otherwise Linux is looking for /bin/sh\R to run (where \R is the carriage return), and that command does not exist.
This is included in my DockerCon 18 talk which includes lots of other tips you may find useful when starting out.

Docker entrypoint not found although in PATH (and executable)

I am creating a simple image with the following Dockerfile
FROM docker:latest
COPY docker-entrypoint.sh /usr/local/bin
ENTRYPOINT ['docker-entrypoint.sh']
Inside my container:
/ # ls -al $(which docker-entrypoint.sh)
-rwxrwxr-- 1 root root 476 Jul 26 07:30 /usr/local/bin/docker-entrypoint.sh
So the entrypoint file is both in the PATH and executable;
But when running
docker run -v /var/run/docker.sock:/var/run/docker.sock -it imageinit
/bin/sh: [docker-entrypoint.sh]: not found
I am aware of this SO question, but this is about the problem of PATH and file permissions (already addressed);
Interestingly your issues seems to be with the type of quotes you have chosen to use. If you change this line:
ENTRYPOINT ['docker-entrypoint.sh']
to
ENTRYPOINT ["docker-entrypoint.sh"]
then everything starts to work as expected.
If you check the documentation for the type of ENTRYPOINT you are using all of the examples have double quotes.
I suspect what is happening when you use the single quotes is that docker is parsing this as the shell form of ENTRYPOINT and trying to execute a script called [docker-entrypoint.sh] which would explain the error message (as obviously no script of that name will exist).
I was getting exactly the same error under the same circumstances (although no single quotes problem) when the docker-entrypoint.sh script contained carriage returns, converting the script with dos2unix docker-entrypoint.sh fixed the issue for me.
I face the same issue and the reason i found on another stack over flow answer is line encoding difference, I got my docker file from one of open source project,
and I building and deploying my file on Docker Desktop for Winodw,
I changed my Docker & .sh file encoding from
CRLF -> LF and it worked, you can use VS code for same it have bootom right corner option to convert CRLF to LF.

Dockerfile's RUN command doesn't find script

Using Docker Toolbox on Windows 10, Docker cannot build an image from my Dockerfile because it doesn't find a script (install-composer) that was copied to the image.
FROM php:7.2.5-apache
COPY scripts/install-composer /usr/bin
RUN chmod +x /usr/bin/install-composer
RUN /usr/bin/install-composer
The error I get, when reating the last RUN command, is:
/bin/sh: 1: /usr/bin/install-composer: not found
The chmod command does work however, indicating the file does actually exist in the image.
A very simple problem but a very misleading error.
The problem was caused by wrong file endings. Git was set up to convert the project files into Windows (CRLF) file endings. I reinstalled Git with the setting "Checkout as-is, commit Unix-style", deleted and recloned the repository, and it fixed the problem.
When it comes to explaining the misleading and confusing error message, my guess is that the file install-composer was actually found and executed. What it is actually saying was that was not found. This empty name was simply the CR caught between two LF (in other words, an empty line) and sh interpreted it as a call to a script file.
Try and group those RUN commands:
RUN chmod +x /usr/bin/install-composer && \
ls -alrth /usr/bin/install* && \
/usr/bin/install-composer
That way, you will see if the file is indeed copied and present.
You can also try, for your second RUN:
RUN /bin/bash -c "/usr/bin/install"
(assuming your script uses bash, and you have a bash installed in your image)

How to debug any sh file inside Dockerfile?

Echo statements are not printing in console when i build container.
I am able to see the information as below
Step 1/3 : FROM jboss/wildfly:latest
b4680c565eae
Step 2/3 : ADD customization /opt/jboss/wildfly/customization/
bc78405babec
Removing intermediate container 7b22667b3310
Step 3/3 : CMD /opt/jboss/wildfly/customization/execute.sh
Running in 76f8bfe9ac95
5cb0fa9482f4
Removing intermediate container 76f8bfe9ac95
Successfully built 5cb0fa9482f4
Successfully tagged madhu/wildfly-mysql-javaee7:latest
execute.sh file includes echo statements, but not writing to console.
Would be interested to know, how we should be able to debug the script.
The script specified in CMD is not executed at build time -- it's executed at runtime. You need to attempt a docker run to see its output.
If you want more output (and/or more useful output -- when used to show commands being executed, echo tends to throw away important details such as the difference between literal and syntactic spaces) your echos provide, modify the CMD or the script to set the -x shell command. You can do this by putting set -x in your script (under the shebang), or amending the CMD, to something like: CMD ['/bin/bash', '-x', '/opt/jboss/wildfly/customization/execute.sh'] (using /bin/bash if the shebang is #!/bin/bash, /bin/sh if the shebang is /bin/sh, etc).

Resources