【问题标题】:Dockerfile Overwrite ARG valuesDockerfile 覆盖 ARG 值
【发布时间】:2017-12-22 19:07:52
【问题描述】:

我有一个包含 Scala 和 SBT 的 Dockerfile,如下所示:

# Scala and sbt Dockerfile
# Scala and SBT forked from: https://github.com/hseeberger/scala-sbt
# Adds Docker client installation additionally

# Pull base image
FROM  openjdk:$JAVA_VERSION

ARG SCALA_VERSION
ARG SBT_VERSION

# Scala expects this file
RUN touch /usr/lib/jvm/java-$JAVA_VERSION-openjdk-amd64/release

# Install Scala
## Piping curl directly in tar
RUN \
  curl -fsL http://downloads.typesafe.com/scala/$SCALA_VERSION/scala-$SCALA_VERSION.tgz | tar xfz - -C /root/ && \
  echo >> /root/.bashrc && \
  echo 'export PATH=~/scala-$SCALA_VERSION/bin:$PATH' >> /root/.bashrc

# Install sbt
RUN \
  curl -L -o sbt-$SBT_VERSION.deb http://dl.bintray.com/sbt/debian/sbt-$SBT_VERSION.deb && \
  dpkg -i sbt-$SBT_VERSION.deb && \
  rm sbt-$SBT_VERSION.deb && \
  apt-get update && \
  apt-get install sbt && \
  sbt sbtVersion

现在如果我想用它作为我的基础镜像,我有以下问题:

  1. 我能否覆盖我的新 Dockerfile 中的 ARG 参数,该 Dockerfile 将使用上述参数作为基础映像?

【问题讨论】:

  • 无法更改已构建的映像。您可能应该找到一些可以解决此问题的图像标签约定。

标签: docker arguments parameter-passing


【解决方案1】:

每个 Dockerfile 都会生成一个不可变的映像。所以你需要先构建一个特定的基础镜像,然后构建你自己的FROM它。

您可以采用这种方法:

Dockerfile.base:

# Scala and sbt Dockerfile
# Scala and SBT forked from: https://github.com/hseeberger/scala-sbt
# Adds Docker client installation additionally

# Pull base image
ARG JAVA_VERSION
FROM  openjdk:$JAVA_VERSION

ARG SCALA_VERSION
ARG SBT_VERSION

# Scala expects this file
RUN touch /usr/lib/jvm/java-$JAVA_VERSION-openjdk-amd64/release

# Install Scala
## Piping curl directly in tar
RUN \
  curl -fsL http://downloads.typesafe.com/scala/$SCALA_VERSION/scala-$SCALA_VERSION.tgz | tar xfz - -C /root/ && \
  echo >> /root/.bashrc && \
  echo 'export PATH=~/scala-$SCALA_VERSION/bin:$PATH' >> /root/.bashrc

# Install sbt
RUN \
  curl -L -o sbt-$SBT_VERSION.deb http://dl.bintray.com/sbt/debian/sbt-$SBT_VERSION.deb && \
  dpkg -i sbt-$SBT_VERSION.deb && \
  rm sbt-$SBT_VERSION.deb && \
  apt-get update && \
  apt-get install sbt && \
  sbt sbtVersion

您的孩子 Dockerfile Dockerfile.mine:

ARG JAVA_VERSION
ARG SCALA_VERSION
ARG SBT_VERSION
FROM basejava:java-$JAVA_VERSION-scala-$SCALA_VERSION-sbt-$SBT_VERSION
# Your app stuf here
# ...
# ...

构建示例:

 export JAVA_VERSION=latest
 export SCALA_VERSION=1.8
 export SBT_VERSION=0.13.9
 docker build . \
   -f Dockerfile.base \
   --build-arg JAVA_VERSION=$JAVA_VERSION \
   --build-arg SCALA_VERSION=$SCALA_VERSION \
   --build-arg SBT_VERSION=$SBT_VERSION \
   -t basejava:java-$JAVA_VERSION-scala-$SCALA_VERSION-sbt-$SBT_VERSION

 docker build . \
   -f Dockerfile.mine \
   --build-arg JAVA_VERSION=latest \
   --build-arg SCALA_VERSION=1.8 \
   --build-arg SBT_VERSION=0.13.9
   -t myjava:java-$JAVA_VERSION-scala-$SCALA_VERSION-sbt-$SBT_VERSION

方法 2,ONBUILD,zigarn 提到。

Dockerfile.base:

# Scala and sbt Dockerfile
# Scala and SBT forked from: https://github.com/hseeberger/scala-sbt
# Adds Docker client installation additionally

# Pull base image
ONBUILD ARG JAVA_VERSION
FROM  openjdk:$JAVA_VERSION

ONBUILD ARG SCALA_VERSION
ONBUILD ARG SBT_VERSION

# Scala expects this file
ONBUILD RUN touch /usr/lib/jvm/java-$JAVA_VERSION-openjdk-amd64/release

# Install Scala
## Piping curl directly in tar
ONBUILD RUN \
  curl -fsL http://downloads.typesafe.com/scala/$SCALA_VERSION/scala-$SCALA_VERSION.tgz | tar xfz - -C /root/ && \
  echo >> /root/.bashrc && \
  echo 'export PATH=~/scala-$SCALA_VERSION/bin:$PATH' >> /root/.bashrc

# Install sbt
ONBUILD RUN \
  curl -L -o sbt-$SBT_VERSION.deb http://dl.bintray.com/sbt/debian/sbt-$SBT_VERSION.deb && \
  dpkg -i sbt-$SBT_VERSION.deb && \
  rm sbt-$SBT_VERSION.deb && \
  apt-get update && \
  apt-get install sbt && \
  sbt sbtVersion

你的孩子Dockerfile.mine

FROM basejava
# Base ONLBUILD instructions are automatically inserted here.
# Your app stuf here
# ...
# ...

构建:

docker build . -f Dockerfile.base -t basejava

export JAVA_VERSION=latest
export SCALA_VERSION=1.8
export SBT_VERSION=0.13.9
docker build . \
   -f Dockerfile.mine \
   --build-arg JAVA_VERSION=$JAVA_VERSION \
   --build-arg SCALA_VERSION=$SCALA_VERSION \
   --build-arg SBT_VERSION=$SBT_VERSION \
   -t myjava:java-$JAVA_VERSION-scala-$SCALA_VERSION-sbt-$SBT_VERSION

【讨论】:

    【解决方案2】:

    ARG 值是在构建时定义的。
    构建基础映像后,您不能只更改 --build-arg 以在最终映像中获取另一个 SCALA_VERSION(或者您必须在新的 Dockerfile 中再次安装它)

    当前的 Dockerfile 就像其他 Dockerfile 的模板。
    您可以使用ONBUILD instruction 在构建其他镜像期间使用此镜像作为基础镜像来有效地进行安装。

    【讨论】:

    • 我不能在继承的 Dockerfile 中覆盖它吗?
    • 是的,你可以。从编辑后的 ​​Dockerfile 构建一个新镜像。
    • 是的,将会有一个从新的 Dockerfile 构建的新镜像,但是新的 Dockerfile 不会传递这些参数,但它们会覆盖它们。据我了解,似乎可以做到这一点。我会试试看!
    • 我添加了有关ONBUILD 指令的信息,可能会对您有所帮助
    猜你喜欢
    • 2019-07-17
    • 2017-03-13
    • 2019-04-22
    • 1970-01-01
    • 1970-01-01
    • 2018-02-12
    • 2017-02-03
    • 2021-11-22
    • 2022-01-19
    相关资源
    最近更新 更多