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
You can run achieve that by running:
or
in case your image has only
sh
availableIn either case, you are just running a container from the desired image and then running either
/bin/bash
orsh
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).Here’s a list of things to check:
Use
CMD
and notENTRYPOINT
in the Dockerfile. The command after thedocker run
image name overrides the DockerfileCMD
, and if both anENTRYPOINT
and aCMD
are present then theCMD
gets passed as arguments to theENTRYPOINT
. You can work around this usingdocker run --entrypoint
as described in @MarcosParreiras’s answer but there’s no benefit to usingENTRYPOINT
here; just useCMD
instead.Make sure your script can execute normally. It should be executable (as in
chmod +x
), and it should begin with a "shebang" lineOutside 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 DockerfileCOPY
will preserve the executable bit and you don’t need toRUN chmod
in the Dockerfile.(You can do the same thing with your
entrypoint.sh
script and omit the explicitsh
interpreter from theCMD
.)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, thenpip 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:
And you should be able to run exactly the
docker run
command you initially proposed