Recently, I encountered a problem that Docker image could not run at work. After the summary, I found that there were several interesting points in the problem, which were worth recording for future use and could also avoid others to step on the pit.

First, run the image error

My development environment is Windows, using Docker Desktop as the local Docker environment. Recently, in a project, I needed to make a WAR package into a Docker image and push it to the warehouse. However, I found that the image could not run, and the following error was reported:

# docker run --rm -it manager
standard_init_linux.go:207: exec user process caused "no such file or directory"
Copy the code

Checking the Dockerfile file is very simple:

FROM openjdk:8-jre-alpine

ADD entrypoint.sh entrypoint.sh
ADD *.war app.war

EXPOSE 8088

RUN chmod 755 entrypoint.sh
ENTRYPOINT ["./entrypoint.sh"]
Copy the code

The image is a basic image based on openJDK. Copy entryPoint. sh and *.war to the image and use entrypoint.sh as the default startup script. This should be fine at first glance, and the WAR package will also run locally using java-JAR.

2. Check the mirror

So what about this mirror image? There are only two files in this image, one is entrypoint. Sh and one is war package. Do these two files not ADD to the image?

Docker run –rm -it manager sh docker run –rm -it manager sh Docker run –rm — it manager /bin/bash docker run –rm — it manager ls docker run –rm — it manager ls

If entryPoint is configured for the image, use the following method to check the image:

# docker run --rm -it --entrypoint sh manager
Copy the code

After entering the container, use ls to see all the files in the container, no problem:

/ # ls
app.war        entrypoint.sh  lib            opt            run            sys            var
bin            etc            media          proc           sbin           tmp
dev            home           mnt            root           srv            usr
Copy the code

War works fine with java-jar app.war, but strangely, the./entrypoint.sh script does not:

/ # ./entrypoint.sh
sh: ./entrypoint.sh: not found
Copy the code

This script file is clearly here, but the error not found, which made me doubt life, encountered a supernatural event.

Three, the trouble caused by line change

I had to keep googling and found out that there were a lot of people like me on the web, and the most likely reason the script didn’t work was because sha-bang wrote it wrong. , usually written on the first line of a shell file, to specify the command line interpreter. Something like this:

/ # cat entrypoint.sh
#! /bin/sh
blabla
Copy the code

The /bin/sh file is also found by ls /bin/sh. While thinking hard, a thought flashed through my mind. Could there be hidden characters? When such supernatural events are encountered, they are likely to be related to hidden characters. /bin/sh ^M = /bin/sh ^M = /bin/sh ^M

/ # cat -v entrypoint.sh
#! /bin/sh^M
blabla
Copy the code

Suddenly, it becomes clear that this is not the newline character under Windows? Line breaks are to blame.

Use dos2UNIX to convert the Windows-formatted newlines in the entrypoint.sh file to UNIX format, use docker build again, this time finally run successfully.

Git configuration

It had already ended here, but then a small thing happened and I found another pit, and I found the root cause of this problem. After I solved the problem, I went to share it with my colleague. However, after listening to my sharing, my colleague said he had never encountered this problem before, and showed me the Docker build and Docker Run on his computer. Everything was normal and there was no error. Why is there a problem with build on my computer? Looking at the puzzled smile my colleague gave me, I was confused all over again.

I asked him to send me entrypoint.sh, and when I checked, his newline format turned out to be UNIX, but my local code newline was Windows. Git status: nothing to commit, working tree clean: local code is the same as repository.

Looking at Git’s configuration file and comparing it with his, I found a very likely suspect:

[core]
	autocrlf = true
Copy the code

Git may be manipulating your code while it is pulling it. If you have the triggering LF = true, Git automatically changes LF to CRLF when you check out code and then changes CRLF to LF when you push it. This seems like a nice feature, but actually has a big bug, for example, like me, directly in the local image, or need to directly upload the shell file to the Linux server to run, may cause problems. Key This configuration is enabled by default on Windows, so it is recommended to turn it off:

$ git config --global core.autocrlf false
Copy the code

Summary of the pit

  • Pit 1: If mirroring is configuredentrypoint.docker run“Should be added--entrypointParameter to check the mirror
  • Pit 2: Script run times not found, most likely becauseSha-BangCheck if there are hidden characters in the script file, such as the newline character of Windows.
  • Pit 3: It is recommended to disable Gitautocrlfconfiguration

reference

  1. How to see docker image contents
  2. Standard_init_linux.go:175 exec user process caused no such file
  3. GitHub first pit: automatic line feed conversion
  4. Customize Git – Configure Git