The <assembly>
element within <build>
has an XML structure and defines how build artifacts and other files can enter the Docker image.
Multiple <assembly>
elements may be specified by adding them to an <assemblies>
element.
If both <assembly>
and <assemblies>
are present in <build>
, the <assembly>
element is treated as if it were the last child of <assemblies>
.
When multiple assemblies are provided, each will be added as a separate layer in the image.
Element | Description |
---|---|
name |
Assembly name, which is |
targetDir |
Directory under which the files and artifacts contained in the assembly will be copied within the container. The default value for this is |
Inlined assembly descriptor as described in Assembly Descriptor below. |
|
Path to an assembly descriptor file, whose format is described Assembly Descriptor below. |
|
Alias to a predefined assembly descriptor. The available aliases are also described in Assembly Descriptor below. |
|
dockerFileDir |
Directory containing an external Dockerfile. This option is deprecated, please use <dockerFileDir> directly in the <build> section. |
exportTargetDir |
Specification whether the |
ignorePermissions |
Specification if existing file permissions should be ignored
when creating the assembly archive with a mode |
mode |
Mode how the how the assembled files should be collected:
The archive formats have the advantage that file permission can be preserved better (since the copying is independent from the underlying files systems), but might triggers internal bugs from the Maven assembler (as it has been reported in #171) |
permissions |
Permission of the files to add:
|
tarLongFileMode |
Sets the TarArchiver behaviour on file paths with more than 100 characters length. Valid values are: "warn"(default), "fail", "truncate", "gnu", "posix", "posix_warn" or "omit" |
User and/or group under which the files should be added. The user must already exist in the base image. It has the general format If a third part is given, then the build changes to user For example, the image |
In the event you do not need to include any artifacts with the image, you may safely omit this element from the configuration.
With using the inline
, descriptor
or descriptorRef
option
it is possible to bring local files, artifacts and dependencies into
the running Docker container. A descriptor
points to a file
describing the data to put into an image to build. It has the same
format as for creating assemblies with the
maven-assembly-plugin with following exceptions:
-
<formats>
are ignored, the assembly will allways use a directory when preparing the data container (i.e. the format is fixed todir
) -
The
<id>
is ignored since only a single assembly descriptor is used (no need to distinguish multiple descriptors)
Also you can inline the assembly description with a inline
description
directly into the pom file. Adding the proper namespace even allows for
IDE autocompletion. As an example, refer to the profile inline
in
the data-jolokia-demo
's pom.xml.
Alternatively descriptorRef
can be used with the name of a
predefined assembly descriptor. The following symbolic names can be
used for descriptorRef
:
Assembly Reference | Description |
---|---|
artifact-with-dependencies |
Attaches project’s artifact and all its dependencies. Also, when a |
artifact |
Attaches only the project’s artifact but no dependencies. |
dependencies |
Attaches only the project’s dependencies. Also, when a |
release-dependencies |
Attaches only the project’s released (non-snapshot) dependencies. |
snapshot-dependencies |
Attaches only the project’s snapshot dependencies. |
project |
Attaches the whole Maven project but without the |
rootWar |
Copies the artifact as |
<images>
<image>
<build>
<assembly>
<descriptorRef>artifact-with-dependencies</descriptorRef>
.....
will add the created artifact with the name ${project.build.finalName}.${artifact.extension}
and all jar dependencies in the targetDir
(which is /maven
by default).
All declared files end up in the configured targetDir
(or /maven
by default) in the created image.
<images>
<image>
<build>
<assemblies>
<assembly>
<name>deps-release</name>
<descriptorRef>release-dependencies</descriptorRef>
<targetDir>/work/lib</targetDir>
</assembly>
<assembly>
<name>deps-snapshot</name>
<descriptorRef>snapshot-dependencies</descriptorRef>
<targetDir>/work/lib</targetDir>
</assembly>
<assembly>
<descriptorRef>artifact</descriptorRef>
<targetDir>/work</targetDir>
</assembly>
</assemblies>
.....
</build>
</image>
</images>
will create three layers:
-
Release dependencies (in jar format) added to /work/lib
-
Snapshot dependencies (in jar format) added to /work/lib
-
The created artifact with the name
${project.build.finalName}.${artifact.extension}
added to /work
If the assembly references the artifact to build with this pom, it is required that the package
phase is included in the run. Otherwise the artifact file, can’t be found by docker:build
. This is an old outstanding issue of the assembly plugin which probably can’t be fixed because of the way how Maven works. We tried hard to workaround this issue and in 90% of all cases, you won’t experience any problem. However, when the following warning happens which might lead to the given error:
[WARNING] Cannot include project artifact: io.fabric8:helloworld:jar:0.20.0; it doesn't have an associated file or directory.
[WARNING] The following patterns were never triggered in this artifact inclusion filter:
o 'io.fabric8:helloworld'
[ERROR] DOCKER> Failed to create assembly for docker image (with mode 'dir'): Error creating assembly archive docker: You must set at least one file.
then you have two options to fix this:
-
Call
mvn package {plugin}:build
to explicitly run "package" and "docker:build" in a chain. -
Bind
build
to an to an execution phase in the plugin’s definition. By default{plugin}:build
will bind to theinstall
phase is set in an execution. Then you can use a plainmvn install
for building the artifact and creating the image.
<executions>
<execution>
<id>docker-build</id>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
In the following example a dependency from the pom.xml is included and
mapped to the name jolokia.war
. With this configuration you will end
up with an image, based on busybox
which has a directory /maven
containing a single file jolokia.war
. This volume is also exported
automatically.
<assembly>
<inline>
<dependencySets>
<dependencySet>
<includes>
<include>org.jolokia:jolokia-war</include>
</includes>
<outputDirectory>.</outputDirectory>
<outputFileNameMapping>jolokia.war</outputFileNameMapping>
</dependencySet>
</dependencySets>
</inline>
</assembly>
Another container can now connect to the volume an 'mount' the
/maven
directory. A container from consol/tomcat-7.0
will look
into /maven
and copy over everything to /opt/tomcat/webapps
before
starting Tomcat.
If you are using the artifact
or artifact-with-dependencies
descriptor, it is
possible to change the name of the final build artifact with the following:
<build>
<finalName>your-desired-final-name</finalName>
...
</build>
Please note, based upon the following documentation listed here, there is no guarantee the plugin creating your artifact will honor it in which case you will need to use a custom descriptor like above to achieve the desired naming.
Currently the jar
and war
plugins properly honor the usage of finalName
.