I have a Dockerfile that has Scala and SBT as below:
# 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
Now if I want to use this as my base image, I have the following question:
relevant docs. When building a Docker image from the commandline, you can set ARG values using –build-arg: $ docker build --build-arg some_variable_name=a_value. Running that command, with the above Dockerfile, will result in the following line being printed (among others): Oh dang look at that a_value.
ARG and ENV Availability When using Docker, we distinguish between two different types of variables - ARG and ENV. ARG are also known as build-time variables. They are only available from the moment they are ‘announced’ in the Dockerfile with an ARG instruction up to the moment when the image is built.
It seems that docker build won't overwrite a file it has previously copied. I have a dockerfile with several copy instructions, and files touched in earlier COPY directives don't get overwritten by later ones. A simplified example (although it also happens if the first copy is an entire directory that happens to contain the file in question):
You can use the ARG command inside a Dockerfile to define the name of a parameter and its default value. This default value can also be overridden using a simple option with the Docker build command.
Each Dockerfile produces an immutable image. So you need first build an specific base image, and then build your own FROM
it.
You can take this approach:
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
Your child 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
# ...
# ...
Build example:
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
Approach 2, ONBUILD, mentioned by 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
Your child Dockerfile.mine
FROM basejava
# Base ONLBUILD instructions are automatically inserted here.
# Your app stuf here
# ...
# ...
Build:
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
ARG
values are defined at build time.
Once your base image is built, you cannot just change the --build-arg
to get another SCALA_VERSION
inside your final image (or you have to install it again in you new Dockerfile)
The present Dockerfile is like a template for other Dockerfile.
You could use the ONBUILD
instruction to effectively do the installations during the build of other images using this one as base image.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With