Home > front end >  Εxecute commands with args and override entrypoint on docker run
Εxecute commands with args and override entrypoint on docker run

Time:09-22

I am trying to override the entrypoint in a docker image with a script execution that accepts arguments, and it fails as follows

▶ docker run --entrypoint "/bin/sh -c 'my-script.sh arg1 arg2'" my-image:latest
docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "/bin/sh -c 'myscript.sh arg1 arg2'": stat /bin/sh -c 'my-script.sh arg1 arg2': no such file or directory: unknown.

However when I exec to the container, the above command succeeds:

▶  docker run --entrypoint sh -it my-image:latest
~ $ /bin/sh -c 'my-script.sh arg1 arg2'
Success

Am I missing sth in the syntax?

CodePudding user response:

Remember that arguments after the container image name are simply passed to the ENTRYPOINT script. So you can write:

docker run --entrypoint my-script.sh my-image:latest arg1 arg2

For example, if I have my-script.sh (mode 0755) containing:

#!/bin/sh

for arg in "$@"; do
    echo "Arg: $arg"
done

And a Dockerfile like this:

FROM docker.io/alpine:latest

COPY my-script.sh /usr/local/bin/
ENTRYPOINT ["date"]

Then I can run:

docker run --rm --entrypoint my-script.sh my-image arg1 arg2

And get as output:

Arg: arg1
Arg: arg2

If you want to run an arbitrary sequence of shell commands, you can of course do this:

docker run --rm --entrypoint sh my-image \
  -c 'ls -al && my-script.sh arg1 arg2'

CodePudding user response:

If you need to do this at all regularly, you can refactor your Dockerfile to make this easier to do.

A Docker container's main process is run by concatenating together the "entrypoint" and "command" argument lists. In a Dockerfile, these come from the ENTRYPOINT and CMD directives. In the docker run command this is trickier: anything after the image name is the "command" part, but the "entrypoint" part needs to be provided by the --entrypoint argument, it needs to be before the image name, and it can only be a single word.

If you need to routinely replace the command, the syntax becomes much cleaner if you set it using CMD and not ENTRYPOINT in the Dockerfile.

# Dockerfile
CMD ["some", "main", "command"] # not ENTRYPOINT

If you make this change, then you can just put your alternate command after the image name in the docker run command, without a --entrypoint option and without splitting the command string around the image name.

docker run my-image:latest /bin/sh -c 'my-script.sh arg1 arg2'

I will somewhat routinely recommend a pattern where ENTRYPOINT is a wrapper script that does some first-time setup, then does something like exec "$@" to run the command that's passed to it as arguments. That setup is compatible with this CMD-first approach: the entrypoint wrapper will do its setup and then run the override command instead of the image's command.

  • Related