Mikhail Potter

Spring boot debian package

Recently got a task to create a debian package with Spring boot application to facilitate deployment process. The target OS is Ubuntu 14.04 and the application build system is Maven. Surfing the web, I found only one relative article described how to achieve the goal, however it uses Gradle ospackage plugin, which is not compatible with Maven builds. Thus, I started to find out the best way to create debian packages using Maven and how to apply the knowledge to make a package with Spring boot application. Complete source of the project could be found on GiHub.

Among various options I have chosen jdeb Maven plugin. It allows to create debian packages on any platform, pretty mature and well documented.

Spring boot introductory tutorial was taken as a source project. The only thing that modified is spring boot maven plugin configuration. It is necessary to make jar fully executable to be able to launch it as a service on Unix systems.

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <executable>true</executable>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Separate module is responsible for creating debian package with executable jar. Firstly, the main artifact is copied using maven dependency plugin

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.10</version>
    <executions>
        <execution>
            <id>copy</id>
            <phase>package</phase>
            <goals>
                <goal>copy</goal>
            </goals>
            <configuration>
                <artifactItems>
                    <artifactItem>
                        <groupId>com.springframework</groupId>
                        <artifactId>gs-spring-boot</artifactId>
                        <version>1.0.0</version>
                        <overWrite>true</overWrite>
                        <outputDirectory>${project.build.directory}</outputDirectory>
                        <destFileName>${build.finalName}.jar</destFileName>
                    </artifactItem>
                </artifactItems>
            </configuration>
        </execution>
    </executions>
</plugin>

And then debian package is created

<plugin>
    <artifactId>jdeb</artifactId>
    <groupId>org.vafer</groupId>
    <version>1.5</version>
    <configuration>
        <controlDir>${project.build.directory}/classes/control</controlDir>
        <deb>${project.build.directory}/${build.finalName}.deb</deb>
    </configuration>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>jdeb</goal>
            </goals>
            <configuration>
                <dataSet>
                    <data>
                        <src>${project.build.directory}/${build.finalName}.jar</src>
                        <type>file</type>
                        <mapper>
                            <type>perm</type>
                            <prefix>/var/${build.finalName}</prefix>
                            <filemode>755</filemode>
                        </mapper>
                    </data>
                    <data>
                        <type>link</type>
                        <symlink>true</symlink>
                        <linkName>/etc/init.d/${build.finalName}</linkName>
                        <linkTarget>/var/${build.finalName}/${build.finalName}.jar</linkTarget>
                    </data>
                </dataSet>
            </configuration>
        </execution>
    </executions>
</plugin>

Data tags specify two entities for packaging:

Another important thing is control directory, that is specified in plugin configuration:

<controlDir>${project.build.directory}/classes/control</controlDir>

Looking at the directory contents you can find control file. It is like a pom.xml for Maven, but for debian packages. It specifies package name, description, dependencies upon other packages, etc. Detailed fields description can be found at debian documentation.

Package: ${build.finalName}
Version: ${project.version}
Section: misc
Priority: optional
Architecture: all
Depends: oracle-java8-installer | openjdk-8-jre
Maintainer: Michael Potter <supermegapotter@gmail.com>
Description: Spring boot Hello World application
Distribution: development

Other control files description could be found at debian documentation.

The only thing that is left is create a package by executing mvn clean package.

#spring-boot #maven #debian