Passing multiple classFile as argument to Dockerfile

Viewed 1406

I have a Dockerfile like this:

FROM java:8
ARG cName
ADD target/jar1.jar p2p.jar
ADD ci/docker_entrypoint.sh .
CMD ["bash", "docker_entrypoint.sh" , "$cName"]

I have a docker_entrypoint.sh which look :

java -cp p2p.jar $1

I have multiple classes to run and I am providing className as input parameter to dockerfile. I am running couple of commands to build and run docker.

docker build -f Dockerfile -t docker-p2p --build-arg cName=com.HelloWorld .
docker run docker-p2p

after running the second command I am getting below error:

Error: Could not find or load main class $cName

I am new to docker and I am not able to parameterise by dockerfile but when I mention a className "HelloWorld" in the dockerfile, it runs well. But when I try to pass parameters , it throws me out with this error.

2 Answers

You have to differ between docker run, cmd and entrypoint.

For your example you can use an entrypoint and set the parameter via an environment variable.

One simple and easy Dockerfile example could be:

FROM java:8
ENV NAME="John Dow"
ENTRYPOINT ["/bin/bash", "-c", "echo Hello, $NAME"]

with docker build . -t test and docker run -e NAME="test123" test

Also have a look at some further docu: docker-run-vs-cmd-vs-entrypoint.

If you do wind up with a Docker image that can do multiple things, it's a little unusual to create one image per task the way you're describing. You can pass additional command-line parameters in docker run or most other ways to start a container, and you can use that to control what the image does.

For example, you might want to set up your image so that you can run

docker run ... docker-p2p com.HelloWorld

passing the class name as an argument. I'd write an entrypoint script that wrapped this in a java call if appropriate (but passed through non-class names, like docker run ... sh):

#!/bin/sh
set -e
case "$1" of
  com.*) exec java "$@" ;;
  *) exec "$@" ;;
esac

The corresponding Dockerfile doesn't take any ARGs; it could be

FROM java:8

# I prefer COPY to ADD, unless you explicitly want automatic
# HTTP fetches and/or tar file extraction.
COPY target/jar1.jar /p2p.jar
COPY ci/docker_entrypoint.sh /

# Globally set the class path.  (A Docker image only does one thing.)
ENV CLASSPATH /p2p.jar

# Always launch the entrypoint script.
ENTRYPOINT ["/docker_entrypoint.sh"]

# Give a default command, which with our script is a class name.
CMD ["com.HelloWorld"]

If you actually want a container per task, you could create a base image that contained everything up to the ENTRYPOINT line, and then created derived images FROM that base image that just set a different CMD.

Related