skip to Main Content

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?

3

Answers


  1. 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'
    
    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
  3. Not pretty but this worked for me:

    docker run image "/bin/bash" "-c" "source ~/.bashrc && /bin/bash"
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search