Skip to content

Latest commit

 

History

History
251 lines (195 loc) · 11.4 KB

_assembly.adoc

File metadata and controls

251 lines (195 loc) · 11.4 KB

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.

Table 1. Assembly Configuration (<image> : <build> )
Element Description

name

Assembly name, which is maven by default. This name is used for the archives and directories created during the build. This directory holds the files specified by the assembly. If an external Dockerfile is used than this name is also the relative directory which contains the assembly files. If multiple assemblies are provided, they must each have a unique name.

targetDir

Directory under which the files and artifacts contained in the assembly will be copied within the container. The default value for this is /<assembly name>, so /maven if name is not set to a different value. This option has no meaning when an external Dockerfile is used.

inline

Inlined assembly descriptor as described in Assembly Descriptor below.

descriptor

Path to an assembly descriptor file, whose format is described Assembly Descriptor below.

descriptorRef

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 targetDir should be exported as a volume. This value is true by default except in the case the targetDir is set to the container root (/). It is also false by default when a base image is used with from since exporting makes no sense in this case and will waste disk space unnecessarily.

ignorePermissions

Specification if existing file permissions should be ignored when creating the assembly archive with a mode dir. This value is false by default. This property is deprecated, use a permissions of ignore instead.

mode

Mode how the how the assembled files should be collected:

  • dir : Files are simply copied (default),

  • tar : Transfer via tar archive

  • tgz : Transfer via compressed tar archive

  • zip : Transfer via ZIP archive

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:

  • ignore to use the permission as found on files regardless on any assembly configuration

  • keep to respect the assembly provided permissions, exec for setting the executable bit on all files (required for Windows when using an assembly mode dir)

  • auto to let the plugin select exec on Windows and keep on others.

keep is the default value.

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

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 user[:group[:run-user]]. The user and group can be given either as numeric user- and group-id or as names. The group id is optional.

If a third part is given, then the build changes to user root before changing the ownerships, changes the ownerships and then change to user run-user which is then used for the final command to execute. This feature might be needed, if the base image already changed the user (e.g. to 'jboss') so that a chown from root to this user would fail. (This third user part has been marked as deprecated and will not be supported in future versions of this plugin.)

For example, the image jboss/wildfly use a "jboss" user under which all commands are executed. Adding files in Docker always happens under the UID root. These files can only be changed to "jboss" is the chown command is executed as root. For the following commands to be run again as "jboss" (like the final standalone.sh), the plugin switches back to user jboss (this is this "run-user") after changing the file ownership. For this example a specification of jboss:jboss:jboss would be required.

In the event you do not need to include any artifacts with the image, you may safely omit this element from the configuration.

Assembly Descriptor

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 to dir)

  • 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:

Table 2. Predefined Assembly Descriptors
Assembly Reference Description

artifact-with-dependencies

Attaches project’s artifact and all its dependencies. Also, when a classpath file exists in the target directory, this will be added to.

artifact

Attaches only the project’s artifact but no dependencies.

dependencies

Attaches only the project’s dependencies. Also, when a classpath file exists in the target directory, this will be added too.

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 target/ directory.

rootWar

Copies the artifact as ROOT.war to the exposed directory. I.e. Tomcat will then deploy the war under the root context.

Examples
<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:

  1. Release dependencies (in jar format) added to /work/lib

  2. Snapshot dependencies (in jar format) added to /work/lib

  3. The created artifact with the name ${project.build.finalName}.${artifact.extension} added to /work

Maven peculiarities when including the artifact

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 the install phase is set in an execution. Then you can use a plain mvn install for building the artifact and creating the image.

<executions>
  <execution>
    <id>docker-build</id>
    <goals>
       <goal>build</goal>
    </goals>
  </execution>
</executions>
Example

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:

Example
<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.