Michael Weiner

September 24, 2023

Debugging an Odd Docker Image Build Failure

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:

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.

About Michael Weiner

Hey, visitor! I'm Michael, a software engineer based in Minnesota, USA. I am an IBMer working on IBM Cloud Kubernetes Service. Feel free to poke around some of my work at michaelweiner.org. Below are some of my personal thoughts on business and my experiences in the computer science industry. Thanks for reading!