skip to Main Content

I have a bash script that I want to dockerize but I’m having issues with both the ENTRYPOINT and CMD directives.

Here’s my Dockerfile:

FROM ubuntu:22.04

# NOTE: these can be overridden with `--build-arg KEY=VALUE`
ARG ...

WORKDIR /scripts
COPY . .

# Install required packages
RUN ...

# Make sure the script is executable
RUN chmod a+x my-script.sh

# Set the entrypoint to use bash
ENTRYPOINT [ "bash" ]

# Run the script
CMD [ "my-script.sh", "-u", $URL, "-k", $KEY, "-d", $DEBUG ]

I’ve done a few iterations and I kept getting different kind of errors. I’ve already deleted the images that I built and the containers so I don’t have the errors to share.

Basically, I want to build an image that would run my bash script when I start a container using that image. I already saw What is the difference between CMD and ENTRYPOINT in a Dockerfile? but I’m still left confused on how to properly use these two directives.

2

Answers


  1. CMD provide defaults for an executing container.

    CMD can provide options for ENTRYPOINT.

    ENTRYPOINT allows you to configure commands that will always run for
    an executing container.

    Imagine that it will be executed like:

    ENTRYPOINT CMD
    

    It can have many different presentation but in your specific example, it should be

    /bin/bash -c my-script.sh -u $URL -k $KEY -d $DEBUG
    

    Therefore

    ENTRYPOINT [ "bash", "-c" ]
    
    # Run the script
    CMD [ "my-script.sh", "-u", $URL, "-k", $KEY, "-d", $DEBUG ]
    
    Login or Signup to reply.
  2. Make sure the first line of the script has a correct "shebang" line.

    #!/bin/bash
    #^^^^^^^^^^ must be very very first line in the script
    # (if you're not using bash features, this can be /bin/sh)
    

    Make sure the script is executable on the host system.

    # outside any Docker context or setup
    chmod +x my-script.sh
    

    Put the entire command line in (preferably) CMD. Don’t explicitly say "bash" anywhere.

    # no ENTRYPOINT at all
    CMD my-script.sh -u "$URL" -k "$KEY" -d "$DEBUG"
    

    Especially avoid the pattern you show of naming only the interpreter in the ENTRYPOINT. If you want to run an alternate command, you still need to type out the entire command, but it must be a shell script or else it won’t run (docker run --rm your-image ls -l will fail as you’ve shown it, for example). There’s an argument to make the script itself be the ENTRYPOINT and the CMD be only the arguments.

    The approach I generally take is that CMD is a complete command on its own. There is a useful pattern of having ENTRYPOINT be a wrapper script that does some first-time setup and then ends in exec "$@" to run the CMD. There are also some interesting use cases of replacing the command at container start time (for debugging; to run a Web server and background worker off the same code base) and CMD is a little easier to override when you need to.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search