Hi,
I need to pass artifactId, groupId and other Maven properties as ENV values in the Dockerfile.
With Maven filtering I would expect the following to work after proper configuration of the Maven plugin:
ENV ARTIFACT_ID=@artifactId@ GROUP_ID=@groupId@
Would it be possible to add support for Maven filtering or is there another way I can achieve this?
As a work-around I suppose I could copy the docker file from somewhere to the project root with filtering enabled but this seems like a roundabout way to do it.
I'd prefer a way to filter the Dockerfile directly, but as a workaround, I copy with filtering.
My src/main/docker/Dockerfile:
FROM anapsix/alpine-java
ENTRYPOINT ["/usr/bin/java", "-jar", "/usr/share/${project.artifactId}/${project.build.finalName}.jar"]
ADD ${project.build.finalName}.jar /usr/share/${project.artifactId}/${project.build.finalName}.jar
Relevant portion of the pom.xml:
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<id>filter-dockerfile</id>
<phase>generate-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}</outputDirectory>
<resources>
<resource>
<directory>src/main/docker</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.3.0</version>
<executions>
<execution>
<id>default</id>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
<configuration>
<contextDirectory>${project.build.directory}</contextDirectory>
</configuration>
</plugin>
Okay, I'm all for a more integrated experience but I cannot find any examples of how to inject maven properties and dependency info, as well as applying profiles into a Docker file (which was very easy with docker-maven-plugin).
Injecting a single maven property with copy-resources + filtering is okay for small stuff but I imagine it could get tiring.
Any hints as to the best practices to apply ?
From the answer https://stackoverflow.com/questions/23521889/how-to-get-maven-groupid-artifactid-project-version-to-the-command-line, you can get groupId and artifactId, and feed it into Dockerfile either using ARG or ENV.. could be an alternative workaround for now.
Just curious though, what's going to be the use case for this feature request?
@freesoft: in my bootstrap shell script I retrieve the configuration of my microservice from a web service. As the configuration is dependant on the GAV of my JAR file I need to somehow pass these parameters during the build phase of my Docker image.
Another related usecase is what @jdmarble illustrated in the comment above: you might want to place the jar, its configuration, log files etc in a structure that depends on which JAR you are adding.
This is useful where you have a Docker volume that is shared between multiple containers and want to avoid overwriting the files of the shared folder structure. Think having separate log files for all your Microservices.
@bcopy
Injecting a single maven property with copy-resources + filtering is okay for small stuff but I imagine it could get tiring.
I believe all maven properties (as well as system properties and other things) are available when filtering via the resources plugin. Or do you mean it would be tiring if you want to inject things that are not already maven properties?
It requires additional boilerplate configuration that unnecessarily weighs down the plugin configuration.
I think filtering should be enabled per default with an option to disable filtering or optionally change the filter token.
Something like:
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.3.0</version>
<executions>
<execution>
<id>default</id>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
<configuration>
<contextDirectory>${project.build.directory}</contextDirectory>
<!-- default value -->
<filter>true</filter>
<filterToken>@</filterToken>
</configuration>
</plugin>
:+1: would be very useful for us as well.
I'm hoping to perhaps whip up a patch for this on the weekend if anyone is interested. Will post here with a pull request once ready.
I believe the custom build args added in #41 should make this easier, as you can now pass things as ARGs to Dockerfile. Does this solve the need?
@freesoft I think I missed your point on using ARG's for building from your comment above.
@mattnworb I believe you would be able to do...
<configuration>
<buildArgs>
<artifactId>${project.artifactId}</artifactId>
<groupId>${project.groupId}</groupId>
</buildArgs>
</configuration>
... and then in the Dockerfile...
ARG artifactId
ARG groupId
ENV ARTIFACT_ID=${artifactId} GROUP_ID=${groupId}
This is in my opinion the better solution as it does not require any additional placeholders or preprocessing of the Dockerfile.
Also I like that the standard ARG mechanism explicitly enumerates all parameters required for the build and that the image can be created without Maven.
Closing as I believe this removes the need for filtering.
@chrsoo I agree that being able to build without maven is a plus, but at the very least, the plugin should provide some built-in build arguments (with or without a configurable prefix).
For instance, the build arguments and corresponding maven properties could be populated automatically
artifactId
groupId
etc...
because I honestly feel that this plug-in just intends to ignore any maven benefits and adds a really unnecessary layer for docker file handling. Using a good old templating engine and some Maven generated properties file would be less cumbersome than this approach (and still be maven independent).
@bcopy Well... They way I see it there is a simple, standard way to parameterise the Docker build and this resolves the basic case of customising a generic Dockerfile for a specific artifact.
Adding a full blown templateing engine and pre-processing would just increase the temptation to make overly complex Dockerfile templates using conditionals, import of file fragments, ... and this seems to be an anti-feature to me. Especially given the project goals which explicitly starts over on a blank page after bad experiences with a solution that was too complex.
To me there is still a lot of added value as I use the plugin to render the same basic Dockerfile for highly standardised Microservices. The only that really change are the artifact names that governs locations of log files, configuration files etc. This together with including build output as the content of the Docker image goes a long way.
This said I agree it would be nice to get even easier access to all Maven properties. You could imagine an approach that if the Dockerfile lists a build arg it would automatically use any matching Maven property, if it exists. This is what you meant, right?
@all what do you say about adding support for a configuration entry such as
<configuration>
<!--
Any Maven property prefixed with the value of 'buildArgPrefix' is matched against Dockerfile
ENV build args. If there is a match between the property name (without the prefix) it
is supplied as an argument to the Docker build. E.g. with the prefix 'project.' the standard
Maven property 'project.artifactId' would be used as a build argument for the Dockerfile
entry
ENV artifactId
-->
<buildArgPrefix>project.</buildArgPrefix>
</configuration>
It would make some sense to make this configuration parameter multivalued to allow different hierarchies of Maven properties to be used as build args as I think there might be an issue with ENV variables containing dots...
Indeed, this would hit the spot !! Cheers
On 6 Aug 2017 17:18, "Christoffer SOOP" notifications@github.com wrote:
@bcopy https://github.com/bcopy Well... They way I see it there is a
simple, standard way to parameterise the Docker build and this resolves the
basic case of customising a generic Dockerfile for a specific artifact.Adding a full blown templateing engine and pre-processing would just
increase the temptation to make overly complex Dockerfile templates using
conditionals, import of file fragments, ... and this seems to be an
anti-feature to me. Especially given the project goals which explicitly
starts over on a blank page after bad experiences with a solution that was
too complex.To me there is still a lot of added value as I use the plugin to render
the same basic Dockerfile for highly standardised Microservices. The only
that really change are the artifact names that governs locations of log
files, configuration files etc. This together with including build output
as the content of the Docker image goes a long way.This said I agree it would be nice to get even easier access to all Maven
properties. You could imagine an approach that if the Dockerfile lists a
build arg it would automatically use any matching Maven property, if it
exists. This is what you meant, right?@ALL https://github.com/all what do you say about adding support for a
configuration entry such as
project.
It would make some sense to make this configuration parameter multivalued
to allow different hierarchies of Maven properties to be used as build args
as I think there might be an issue with ENV variables containing dots...—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/spotify/dockerfile-maven/issues/20#issuecomment-320513303,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAekNfipI75n_QG2lOi3AhdiqCztSc2Aks5sVdlWgaJpZM4Nx9rc
.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
(Adding comment to prevent automatic closure by the stale bot)
This feature request is still relevant, please consider for implementation!
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
ping
This would be very useful for my use case as well. I'm going to use the filtering workaround until then.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Most helpful comment
It requires additional boilerplate configuration that unnecessarily weighs down the plugin configuration.
I think filtering should be enabled per default with an option to disable filtering or optionally change the filter token.
Something like: