将多个classFile作为参数传递给Dockerfile

时间:2018-12-21 12:14:34

标签: docker dockerfile

我有一个像这样的Dockerfile:

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

我有一个看起来像docker_entrypoint.sh的

java -cp p2p.jar $1

我有多个要运行的类,并且我将className作为输入参数提供给dockerfile。我正在运行几个命令来构建和运行docker。

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

运行第二个命令后,出现以下错误:

Error: Could not find or load main class $cName

我是Docker的新手,我无法通过dockerfile进行参数设置,但是当我在dockerfile中提及className“ HelloWorld”时,它运行良好。但是,当我尝试传递参数时,它会把我带出这个错误。

2 个答案:

答案 0 :(得分:2)

您必须在docker run cmd entrypoint 之间有所区别。

在您的示例中,您可以使用入口点并通过环境变量设置参数。

一个简单的Dockerfile示例可能是:

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

带有docker build . -t testdocker run -e NAME="test123" test

还可以查看其他文档:docker-run-vs-cmd-vs-entrypoint

答案 1 :(得分:1)

如果您确实可以使用可以执行多种操作的Docker映像,则按照您描述的方式为每个任务创建一个映像是很不寻常的。您可以通过docker run或其他大多数方式来传递其他命令行参数来启动容器,并可以使用它来控制图像的作用。

例如,您可能需要设置图像以便可以运行

docker run ... docker-p2p com.HelloWorld

将类名作为参数传递。我会编写一个入口点脚本,如果合适的话,将其包装在java调用中(但通过非类名传递,例如docker run ... sh):

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

相应的Dockerfile不包含任何ARG;可能是

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"]

如果您实际上希望为每个任务提供一个容器,则可以创建一个包含ENTRYPOINT行之前所有内容的基础图像,然后创建派生图像FROM,该基础图像只是设置了一个不同的{ {1}}。