I was building an Alpine Linux image which had a bash script called in the Dockerfile that was failing with the dreaded "127" error.
Short Answer:
Using the troubleshooting procedure later described, I discovered that there were actually (2) faults causing the 127 error:
Fault 1 Fix: Missing Package: In the Dockerfile I hadn't included bash with the other Alpine packages.
RUN apk add --no-cache --update bash app1 app2
Fault 2 Fix: docker buildx build command had a syntax error. I had added a bunch of tags and my local context (the "dot") ended up between them. I moved it to the end of the build command and with the other fix, all was happy:
time docker buildx build --no-cache --platform linux/arm64 \
-t f1linux/testrepo:test1 -t f1linux/testrepo:test2 -t \
f1linux/testrepo:test3 -f Dockerfile.COPY . --progress=plain
The 127 error feedback had me chasing a solution for the part of the Dockerfile calling the script when the error was actually consequential from a missing package and a syntax error in the build command.
Below follows how I isolated this compound fault
Troubleshooting Procedure:
Since the part of the Dockerfile calling the bash script was found to be CORRECT, showing changes to correct code only serves to confuse. As such, I won't cover this territory, but limit review to steps taken to isolate where the fault really lived.
Exclude Line Endings Issues:
After making no progress clearing the error in the part of the Dockerfile which downloads & executes the script, I began investigating non-obvious potential causes: non-printing characters.
Check Line Endings: Compare file encodings & line endings of the script being called in your Dockerfile and failing with scripts known to execute correctly in other Dockerfiles:
file -k script-Not-WORKING.sh
file -k script-WORKING.sh
Fix Line Ending Issues: Compare output of git status before and after git normalize to see if anything changed. If anything has, commit those changes.
git status
git add --renormalize .
git status
In my case renormalize made no changes and thereby excluded issues with Line Endings as being causal.
Reduce Complexity:
So I tried tweaks to how the script was called in the Dockerfile without success and neither could I see issues with encodings or line endings. I had to reduce complexity as much as possible.
Dockerfile: I copied & trimmed my Dockerfile down to the fewest lines and made (2) changes to the stripped-down version:
Change 1: I added a line which listed did an ls to validated it was both present and executable in --progress=plain feedback during the build
Change 2: I commented-out the name of the failing script and changed it to testscript.sh
FROM docker.io/alpine:latest
LABEL com.F1Linux.image.version="001.000.000"
RUN apk add --no-cache --update app1 app2
COPY --chmod=755 scripts-config /root/scripts-config/
RUN ls -al /root/scripts-config/
#RUN /root/scripts-config/realscript.sh
RUN /root/scripts-config/testscript.sh
Script: Next I created testscript.sh to prove in principle that a script could be executed successfully and this would help exclude any issues with the script itself (excluding the she-bang) being causal of the fault:
#!/bin/bash
echo "Hello World"
After creating it I chmod 777 the short test script
NOTE: chmod 777 is dangerous and should never EVER be used on a live production system. After you're done testing delete this file.
Docker buildx build: I simplified this by removing --build-arg and BUILDVAR= parameters, as all but 1 tag:
time docker buildx build --no-cache --platform linux/arm64 \
-t f1linux/testrepo:test1 . -f Dockerfile.COPY --progress=plain
Remark the --no-cache as a parameter: this ensures we start with a clean slate each build.
Execution:
Executing the simplified docker buildx build command still failed, but slightly differently this time. The local context "dot" was now no longer sandwhiched between tags, so the test script was failing with an error 2. Although an error, it wasn't the 127 error, so progress was made by identifying the fault in the build command.
A bit of Googling and I found a Stack post about adding the bash package. I executed the simplified build command again with the additional package and the test script was now successfully executing.
Armed with the knowledge gained in my reduced complexity test environment, I was able to fix the failing Dockerfile and the build command.
Conclusion:
Hope both the short answer and how I arrived at it helps others stuck. I also wanted to ensure I wrote this down in case I ever get into this kind of pain again...
RUN sh /tmp/install-deps.shecho $(...)instead of just running the command directly? (RUN ls -l /tmp/install-deps.shwithout theechowrapper.)shgave anillegal optionerror. Yes, it is executable, and I use the echo because I tried just an ls and I wasn't seeing the results when I randocker-compose build --no-cache