如何根据另一个变量的值更新dockerfile中的变量?

时间:2018-11-07 21:59:10

标签: bash docker docker-compose command-line-interface

在将其发送到JAVA_ARGS命令之前,需要更新java -server变量。

当用户调用./script/server -d时,我想附加调试参数。这是我的./script/server的相关部分:

for i in "$@"
do
case $i in
    -d|--debug)
    DEBUG_ARGS="--build-arg DEBUG_MODE=true"
    shift
    ;;
    -h|--help)
    display_usage
    exit
    ;;
    *)
    echo "Unknown option"
    exit 1
    ;;
esac
done

docker-compose build ${DEBUG_ARGS} app
docker-compose up

这是我的docker-compose.yml的摘录

services:
  app:
    environment:
      ...
      JAVA_ARGS: -Xms2048m -Xmx3072m
      JAVA_ARGS_DEBUG: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5080

这似乎可行,我认为我的dockerfile正在正确检测到DEBUG_MODE=true变量。这是我的dockerfile :(某些内容已删除)

FROM openjdk:8-alpine

ARG DEBUG_MODE=false
ENV DEBUG_MODE ${DEBUG_MODE}

ARG JAVA_ARGS=
ENV JAVA_ARGS ${JAVA_ARGS}    

RUN if [ $DEBUG_MODE == "true" ]; \
        then echo "Debug mode on."; JAVA_ARGS=$JAVA_ARGS $JAVA_ARGS_DEBUG; \
        else echo "Debug mode off."; \
    fi;

RUN echo "Echoing JAVA_ARGS: "; \
    echo "${JAVA_ARGS}";

ENTRYPOINT ["/docker-entrypoint.sh"]
CMD java -server ${JAVA_ARGS} -jar /app/app.jar

我正确地看到Debug mode on.输出到控制台。

但是echo "${JAVA_ARGS}";为空。而且,的确,当到达最后一行时,args不会传递给java命令,并且不会启用调试。

我的bash非常不稳定,您知道为什么我无法在最终命令中更新和使用该var吗?

1 个答案:

答案 0 :(得分:1)

您应该使这些选项在运行时可配置,而不要尝试将设置“引入”到Docker映像中。 (如果该映像具有3 GB的堆大小硬编码,我可以在只有1 GB RAM或64 GB的系统上运行它吗?)

您的Dockerfile会提示ENTRYPOINT脚本,这是放置此类设置的好地方。我们可以将Dockerfile缩减为:

FROM openjdk:8-alpine
WORKDIR /app
COPY app.jar docker-entrypoint.sh ./
ENTRYPOINT "/app/docker-entrypoint.sh"
CMD ["java", "-jar", "app.jar"]

然后,入口点脚本可以根据命令行选项或环境变量进行决策:

#!/bin/sh
if [ -n "$JAVA_OPTS" ]; then
  JAVA_OPTS="-Xms2048m -Xmx3072m"
fi
if [ -n "$DEBUG_MODE" ]; then
  JAVA_OPTS="$JAVA_OPTS -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5080"
fi
export JAVA_OPTS
exec "$@"

然后运行它:

docker run --rm -p127.0.0.1:5080:5080 -e DEBUG_MODE=yes myimage

您将运行相同的图像“用于调试”或“用于真实”;您不需要重新编译它,也不必为如何设置变量制定docker build时间决定。