Home > Enterprise >  starting container process caused: exec: "/bin/sh": stat /bin/sh: no such file or director
starting container process caused: exec: "/bin/sh": stat /bin/sh: no such file or director

Time:10-01

I am trying to build my dockerfile as shown thus:

ARG IMG_TAG=latest

# Compile the gaiad binary
FROM golang:1.18-alpine AS gaiad-builder
WORKDIR /usr/src/app
COPY go.mod go.sum* ./
RUN go mod download
COPY . .
ENV PACKAGES curl make git libc-dev bash gcc linux-headers eudev-dev python3
RUN apk add --no-cache $PACKAGES
RUN CGO_ENABLED=0 make install

# Add to a distroless container
FROM distroless.dev/static:$IMG_TAG
ARG IMG_TAG
COPY --from=gaiad-builder /go/bin/gaiad /bin

RUN gaiad init Edima 
    # && wget https://raw.githubusercontent.com/cosmos/mainnet/master/genesis/genesis.cosmoshub-4.json.gz \
    # && gzip -d genesis.cosmoshub-4.json.gz \
    # && mv genesis.cosmoshub-4.json ~/.gaia/config/genesis.json 

# RUN gaiad start --x-crisis-skip-assert-invariants

EXPOSE 26656 26657 1317 9090
USER 0

ENTRYPOINT ["gaiad", "start"]

But I am getting an error when I run docker build ., the error is shown:

 => ERROR [stage-1 3/3] RUN /bin/gaiad init Edima                                                                                                                               0.4s
------
 > [stage-1 3/3] RUN /bin/gaiad init Edima:
#16 0.432 container_linux.go:380: starting container process caused: exec: "/bin/sh": stat /bin/sh: no such file or directory
------
executor failed running [/bin/sh -c /bin/gaiad init Edima]: exit code: 1

COuld anyone help with how to solve this error?

CodePudding user response:

A "distroless" image usually only contains a very minimal set of libraries and configuration files. It won't contain, for example, a shell, so you can't run shell commands.

The approach I'm used to seeing for a distroless (or similarly scratch) based image is to do all of the necessary setup in previous steps, then COPY content into the final image. Whatever work gaiad init does, if it can reasonably be built into an image, it should be done in a previous stage, and then its result COPYed in.

FROM golang:1.18-alpine AS gaiad-builder
...
RUN CGO_ENABLED=0 make install

# still in the build stage
ENV HOME=/
RUN /go/bin/gaiad init Enima

FROM distroless.dev/static:$IMG_TAG
# (don't RUN anything in the final "FROM distroless" build stage)
COPY --from=gaiad-builder /go/bin/gaiad /gaiad
COPY --from=gaiad-builder /.gaiad/ /.gaiad/
ENV HOME=/
ENTRYPOINT ["/gaiad", "start"]

If that's not an option, then (like ENTRYPOINT and CMD) the RUN directive comes in two forms. If you RUN some command then Docker automatically runs that via a shell; but the distroless image doesn't have a shell, which leads to the /bin/sh: no such file or directory error. You can also pass a JSON array to RUN, which doesn't invoke a shell, but also requires you to manually split up words yourself, and can't do things like environment-variable substitution:

RUN ["gaiad", "init", "Edima"]

If that's not an option, then a distroless image won't work for you. The comments hint at wanting to download more files and run a sequence of commands in the final image. Since you build the application using an Alpine-based image, you can change the final image to match

FROM alpine
COPY --from=gaiad-builder /go/bin/gaiad /bin/
# which includes a POSIX /bin/sh, so this now works again
RUN gaiad init Enima
  • Related