This week I was building a simple Docker image to use for some debugging and ran into an odd case that was rather frustrating to track down.
I wanted a simple Docker image that contained the ibmcloud CLI and some plugins for that CLI that would simply sleep indefinitely. So, I created a rather simple Dockerfile:
I wanted a simple Docker image that contained the ibmcloud CLI and some plugins for that CLI that would simply sleep indefinitely. So, I created a rather simple Dockerfile:
FROM alpine RUN curl -fsSL https://clis.cloud.ibm.com/install/linux | sh RUN ibmcloud plugin install container-service -r "IBM Cloud" ENTRYPOINT ["tail", "-f", "/dev/null"]
Things seemed straightforward enough. I went and attempted to build the image and ran into the following issue:
[+] Building 10.6s (6/6) FINISHED docker:desktop-linux => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 276B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/alpine:latest 5.8s => [1/3] FROM docker.io/library/alpine@sha256:7144f7bab3d4c2648d7e59409f15ec52a18006a128c733fcff20d3a4a54ba44a 4.3s => => resolve docker.io/library/alpine@sha256:7144f7bab3d4c2648d7e59409f15ec52a18006a128c733fcff20d3a4a54ba44a 0.0s => => sha256:7e01a0d0a1dcd9e539f8e9bbd80106d59efbdf97293b3d38f5d7a34501526cdb 1.47kB / 1.47kB 0.0s => => sha256:7264a8db6415046d36d16ba98b79778e18accee6ffa71850405994cffa9be7de 3.40MB / 3.40MB 4.0s => => sha256:7144f7bab3d4c2648d7e59409f15ec52a18006a128c733fcff20d3a4a54ba44a 1.64kB / 1.64kB 0.0s => => sha256:c5c5fda71656f28e49ac9c5416b3643eaa6a108a8093151d6d1afc9463be8e33 528B / 528B 0.0s => => extracting sha256:7264a8db6415046d36d16ba98b79778e18accee6ffa71850405994cffa9be7de 0.2s => [2/3] RUN curl -fsSL https://clis.cloud.ibm.com/install/linux | sh 0.2s => ERROR [3/3] RUN ibmcloud plugin install container-service -r "IBM Cloud" 0.2s ------ > [3/3] RUN ibmcloud plugin install container-service -r "IBM Cloud": 0.164 /bin/sh: ibmcloud: not found ------ Dockerfile:7 -------------------- 5 | # RUN apk add --no-cache curl 6 | RUN curl -fsSL https://clis.cloud.ibm.com/install/linux | sh 7 | >>> RUN ibmcloud plugin install container-service -r "IBM Cloud" 8 | 9 | ENTRYPOINT ["tail", "-f", "/dev/null"] -------------------- ERROR: failed to solve: process "/bin/sh -c ibmcloud plugin install container-service -r \"IBM Cloud\"" did not complete successfully: exit code: 127
Oddly enough, the error message indicated that the `RUN ibmcloud plugin install container-service -r "IBM Cloud"` instruction in the Dockerfile failed.
exit code: 127
The exit code of 127 isn't super helpful but it gave a starting point for some Google-ing. After talking with a colleague, he mentioned that the image might not have curl installed. It is true that alpine doesn't usually come with curl installed, but I was skeptical that this was the problem since the log output from my attempt to build the image seemed to indicate that the curl instruction was successful:
=> [2/3] RUN curl -fsSL https://clis.cloud.ibm.com/install/linux | sh 0.2s
The next easiest attempt at a solution was to simply add an instruction into my Dockerfile to install curl into the image:
FROM alpine RUN apk add --no-cache curl RUN curl -fsSL https://clis.cloud.ibm.com/install/linux | sh RUN ibmcloud plugin install container-service -r "IBM Cloud" ENTRYPOINT ["tail", "-f", "/dev/null"]
And sure enough, running a docker build command on this updated Dockerfile resulted in a successful image build.
So, to those who are more versed in the Docker build engine than I am: why would the `RUN curl -fsSL https://clis.cloud.ibm.com/install/linux | sh` command in the Dockerfile not result in a failure if curl isn't present in the image? My guess is that the `| sh` part of that instruction masked the error, but even then I would still expect shell to complain about running a curl command when curl isn't present.
In hindsight, the fact that the curl instruction only took 0.2 seconds to complete during the first attempt at building the image should've been a dead giveaway that something wasn't right. After spending so much time fighting this particular issue, I hope this write up might help someone else in the future.