我对Docker完全是个新手。我有以下想法:我需要提供单一的图像,将能够基于运行时参数,如配置文件/阶段和python是包含或不执行不同的脚本。
这些脚本是许多可以从外部覆盖的参数。我搜索了类似的问题,但没有找到任何类似的问题。
我有以下想法,但似乎很难支持和丑陋,我希望有人能提供更好的解决方案:

图像内容是原始的:
FROM openjdk:8
#ARG py_ver=2.7
#RUN if [-z "$py_ver" ] ; then echo python version not provided ; else echo python version is $py_ver ; fi
#FROM python:${py_ver}
# set the working directory in the container
WORKDIR /models
# copy the dependencies file to the working directory
COPY training.sh execution.sh requirements/ ./
#RUN pip install --no-cache-dir -r requirements.txt
ENV profile="training"
ENV pythonEnabled=false
RUN if [ "$profile" = "training" ]; then \
command="java=/usr/bin/java training.sh"; \
else \
command="java=/usr/bin/java execution.sh"; \
fi
ENTRYPOINT ["${command}"]我想我有几个问题: 1)我需要有一个图像,但基于运行时参数,我需要选择合适的运行脚本;2)我必须将大量的参数传递给训练和执行脚本(app。6-7个参数)。使用"-e“有点困难。3)我的图像可以下载所有的python版本,并在args版本中指定的运行时使用。
我修改了docker-compose,但如果您需要管理多个服务,它会有所帮助。这不是我的案子。我有一个带有不同设置参数和准备流程的服务。有没有人建议比在运行时python版本和配置文件中选择意大利面if-else条件更好的方法?
发布于 2020-12-22 03:12:32
从两个部分来看这个问题可能会有所帮助。首先,您如何控制您正在使用的运行时;第二,您如何控制容器运行时发生的事情?
Docker镜像通常只包含一个应用程序,但是如果有大量的代码库和几种调用它的方法,您可以将它们打包在一起。例如,在Python中,Flask应用程序和关联的芹菜工人可能捆绑在一起。无论如何,这个映像仍然只包含一个语言解释器和相关的库:您不会用三个版本的Python和四个版本的支持库来构建一个映像。
对于控制构建到映像中的单语言解释器和库栈的事情,正如您所展示的那样,ARG是正确的方法:
ARG py_ver=3.9
RUN apt-get install python${py_ver}
ARG requirements=requirements.txt
RUN pip install -r ${requirements}如果您需要为多个语言版本构建相同的映像,您可以使用shell循环或类似的自动化来构建:
for py_ver in 3.6 3.7 3.8 3.9; do
docker build --build-arg py_ver="$py_ver" -t "myapp:python${py_ver}" .
done
docker run ... myapp:python3.9至于在启动容器时运行的内容,您有几个选择。您可以在启动容器时提供一个替代命令,最简单的做法是丢弃Dockerfile结尾处的整个"profile“部分,只需提供:
docker run ... myapp:python3.9 \
training.sh您提到有几个调用涉及更多内容。您可以将它们包装在shell脚本中
#!/bin/sh
java -Dfoo=bar -Dbaz.quux.meep=peem ... \
-jar myapp.jar \
arg1 arg2 arg3然后将它们COPY到您的映像中,放入通常的可执行文件路径中
COPY training-full.sh /usr/local/bin然后,您可以将该脚本作为主容器命令运行
docker run ... myapp:python3.9 training-full.sh您可以在这里小心地使用ENTRYPOINT。重要的细节是the CMD gets passed to the ENTRYPOINT as command-line arguments,并且在您的Dockerfile文件中,ENTRYPOINT通常必须具有JSON数组语法。原则上,你可以使用它来创建人工的“命令”:
#!/bin/sh
case "$1" of
training)
shift
exec training.sh foo bar "$@"
;;
execution)
shift
exec execution.sh "$@"
;;
*)
exec "$@"
;;
esac然后,您可以通过以下几种方式启动容器
docker run --rm myapp:python3.9 training
docker run --rm myapp:python3.9 execution 'hello world'
docker run --rm myapp:python3.9 ls -l /
docker run --rm -it myapp:python3.9 bashhttps://stackoverflow.com/questions/65397307
复制相似问题