Search code examples
bashdockerdockerfileglibcdocker-entrypoint

Add shell or bash to a docker image (Distroless based on Debian GNU/Linux)


I want add shell or bash to my image to execute installation command.

I have copied the /bin/bash on my VM on to my image on Dockerfile:

COPY /bin/bash /bin/

But when I execute the docker command:

 docker run -it --entrypoint "/bin/bash" <my_image>

Then I get the following error :

/bin/bash: error while loading shared libraries: libtinfo.so.5: cannot open shared object file: No such file or directory

Thanks for your help


Solution

  • You can do it by copying the statically compiled shell from official busybox image in a multi-stage build in your Dockerfile. Or just COPY --from it.

    The static shell doesn't have too many dependencies, so it will work for a range of different base images. It may not work for some advanced cases, but otherwise it gets the job done.

    The statically compiled shell is tagged with uclibc. Depending on your base image you may have success with other flavours of busybox as well.

    Example:

    FROM busybox:1.35.0-uclibc as busybox
    
    FROM gcr.io/distroless/base-debian11
    
    # Now copy the static shell into base image.
    COPY --from=busybox /bin/sh /bin/sh
    
    # You may also copy all necessary executables into distroless image.
    COPY --from=busybox /bin/mkdir /bin/mkdir
    COPY --from=busybox /bin/cat /bin/cat
    
    ENTRYPOINT ["/bin/sh", "/entrypoint.sh"]
    

    The single-line COPY --from directly from image would also work:

    FROM gcr.io/distroless/base-debian11
    
    COPY --from=busybox:1.35.0-uclibc /bin/sh /bin/sh
    
    ENTRYPOINT ["/bin/sh", "/entrypoint.sh"]