skip to Main Content

I have created a docker image from a Dockerfile. Projects working perfectly. I’ve a few tests and to invoke those tests I’ve created a run_tests.sh file, I’ve made the file executable too.

So, when I run docker run -it --rm <image_name> run_tests.sh it should output the test result, instead it outputting server ip address it listening to.

How to run bash script from a Docker Image without entering it’s shell?

This is my Dockerfile…

FROM python:3.8-slim-buster

RUN pip install --upgrade pip
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

WORKDIR /app

COPY requirements.txt /app/requirements.txt

# install dependencies
RUN pip install -r requirements.txt
RUN apt-get update
RUN apt-get install gnupg -y

# copy project
COPY . /app/

# making executable test file and entrypoint file for bash shell
RUN chmod +x run_tests.sh 
RUN chmod +x entrypoint.sh

COPY ./entrypoint.sh /
ENTRYPOINT ["sh", "/entrypoint.sh"]

2

Answers


  1. You can run achieve that by running:

    docker run --rm --entrypoint '' <image_name> /bin/bash -c './run_tests.sh'
    

    or

    docker run --rm --entrypoint '' <image_name> sh -c './run_tests.sh'
    

    in case your image has only sh available

    In either case, you are just running a container from the desired image and then running either /bin/bash or sh with the -c flag, that allows you to define the command to run from a string. Also, by setting --entrypoint '', you are overriding the default entrypoint set on the Dockerfile. When you have an entrypoint set, the docker command would be appended as parameters for that, so we override the entrypoint to be an empty one.

    Also, you should no use the options -it in this case, given that they are used when you want to interact with the container (i.e access the terminal within the container).

    Login or Signup to reply.
  2. Here’s a list of things to check:

    Use CMD and not ENTRYPOINT in the Dockerfile. The command after the docker run image name overrides the Dockerfile CMD, and if both an ENTRYPOINT and a CMD are present then the CMD gets passed as arguments to the ENTRYPOINT. You can work around this using docker run --entrypoint as described in @MarcosParreiras’s answer but there’s no benefit to using ENTRYPOINT here; just use CMD instead.

    CMD ["sh", "/entrypoint.sh"]
    

    Make sure your script can execute normally. It should be executable (as in chmod +x), and it should begin with a "shebang" line

    #!/bin/sh
    # ^^^ as the very very first thing in the script
    

    Outside Docker you should be able to run ./run_tests.sh and it should run without explicitly naming an interpreter. If the file is executable on the host (and checked into source control as executable) then Dockerfile COPY will preserve the executable bit and you don’t need to RUN chmod in the Dockerfile.

    (You can do the same thing with your entrypoint.sh script and omit the explicit sh interpreter from the CMD.)

    Put the script in $PATH somewhere. /usr/local/bin is often a good choice.

    (In a Python context, if your setup.cfg file contains setuptools entry points, then pip install will put its wrapper scripts into /usr/local/bin and you can just run them; this is done automatically.)

    Putting these all together, you’d get a Dockerfile like:

    COPY entrypoint.sh run_tests.sh /usr/local/bin
    # RUN chmod +x /usr/local/bin/*
    CMD ["entrypoint.sh"]
    

    And you should be able to run exactly the docker run command you initially proposed

    docker run -it --rm image_name run_tests.sh
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search