简体   繁体   中英

Override Dockerfile CMD by docker run command with arguments

I have a Dockerfile with CMD. I want to override this command by docker run command but in my command there are arguments. the command is something like that: MyAppName -DataBase myDataBase -Port myPort -AnotherARG arg The arguments are difference in any container launch that means that I must not feed all argument at every container launch (there are a lot of arguments) how can I do this? Thanks

So what is the problem?

If command line is completely different on every launch, you'd better not declare CMD nor ENTRYPOINT at your Dockerfile , but provide it each time on launch:

docker run -it ubuntu /bin/sh -c "echo Hello World"

If there is common part, lets say you always need a shell, but arguments differ, then you declare ENTRYPOINT in your Dockerfile like:

Dockerfile

FROM ubuntu
....
ENTRYPOINT ['/bin/sh']

And provide the remaining arguments on launch:

docker run -it mycontainer -c 'Hello World!

You need to remember:

  • Arguments, provided in docker run are concatenated to Dockerfile 's ENTRYPOINT

  • Arguments, provided in docker run override Dockerfile 's CMD

  • You should use ENTRYPOINT ['blah', 'blah'] syntax instead of ENTRYPOINT blah blah in Dockerfile for this to work

As @grapes says in their answer,

Arguments, provided in docker run are concatenated to Dockerfile 's ENTRYPOINT

So you can write a custom ENTRYPOINT script that looks at the command that's getting passed in and rewrite it if you need to.

#!/bin/sh
#
# docker-entrypoint.sh
#
# The Dockerfile CMD, or any "docker run" command option, gets
# passed as command-line arguments to this script.

# Abort on any error (good shell hygiene)
set -e

# If we're running "myAppName", provide default options
if [ "$1" = "MyAppName" ]; then
  # Remove the command from the option list (we know it)
  shift

  # Then run it with default options plus whatever else
  # was given in the command
  exec MyAppName -OptionOne default -OtherOption foo "$@"
fi

# Otherwise just run what was given in the command
exec "$@"

The conditional block there ensures that, for instance, if you want a debugging shell with docker run --rm -it ... sh it doesn't get your application-specific options added in. You can get arbitrarily complex here, setting default environment variables, trying to further parse the command line, and so on. It's important to exec the main process in the entrypoint script so that the application becomes the main container process and it doesn't keep the entrypoint as a parent (you want docker stop to send its signals to your process and not a wrapper shell).

Again quoting @grapes:

You should use ENTRYPOINT ['blah', 'blah'] syntax instead of ENTRYPOINT blah blah in Dockerfile for this to work

So your Dockerfile might end like:

...
COPY docker-entrypoint.sh /
RUN chmod +x docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["MyAppName"]

(The chmod step is unnecessary if the file is already executable on your local system before it gets COPY d in. The square brackets and quotes on both ENTRYPOINT and CMD are critical.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM