I find myself often repeating dockerfile
content. For example for a typical spring-boot
application, this would be as follows:
FROM $BUILD_IMAGE as build
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src src
RUN mvn package
RUN java -Djarmode=layertools -jar target/application.jar extract
FROM $RUNTIME_IMAGE
COPY --from=build /application/dependencies/ ./
COPY --from=build /application/spring-boot-loader/ ./
COPY --from=build /application/snapshot-dependencies/ ./
COPY --from=build /application/application/ ./
EXPOSE 8081
ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]
Here only 3 things are dynamic based on the project that executes the dockerfile: pom.xml
, src
, EXPOSE <port>
. Everything else is always the same.
Question: is it possible to create some kind of "template", so that I can "feed" the template with those 3 dynamic files or folders?
I would not want to copy the dockerfile
into all of my projects 1:1. I would prefer if I could use the dockerfile as a base definition, and reference it from all of my spring-boot projects.
We can achieve this with the ARG
directive (docs.docker.com
). Here is an example Dockerfile
:
# syntax=docker/dockerfile:1
ARG TAG
FROM ubuntu:$TAG
ARG FILE_TO_COPY
ARG EXPOSE_PORT
COPY $FILE_TO_COPY file.txt
CMD cat file.txt
EXPOSE $PORT_TO_EXPOSE
There is a semantic difference between any ARG
before the first FROM
and any arg after the first FROM
: the former can be used within the FROM
directive, e.g. to define the tag or digest. Its value is not available in a build stage. The latter belongs to a build stage, and thus in only accessible within the build stage. This behaviour is specified here (docs.docker.com
).
We can build the image, specifying the build arguments:
$ docker build \
--build-arg TAG=18.04 \
--build-arg FILE_TO_COPY=foo.txt \
--build-arg PORT_TO_EXPOSE=8080 \
--tag test \
.
and then run it:
$ docker run -it --rm test
bar
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