Всем привет! Это моя первая статья на Хабар.
В этой статье я хочу поделиться о том, как я упаковывал Spring boot приложение в RPM пакет.
Для начала хочу рассказать, что все примеры когда и скрипты написаны на JAVA в Ubuntu.
После долгих проблем с разворачиванием приложения, которое мы писали заказчику, он подумал, и сказал, что на выходе хочет получать приложение упакованное в RPM, так чтобы когда этот пакет будет распакован ему практически ничего не надо было делать, чтобы запустить наше приложение. Ну и как полагается хорошему разработчику не знаешь, идешь искать ответ на свой вопрос в Интернете.
Опустим не совсем нужный текст, так как я думаю, что самое интересное это код.
Первое, что я хочу сказать то, что для сборки проекта мы использовали Maven. Прочитав кучу, статьей испробовав множество разных вариантов мы решили нашу задачу.
И так упакованное приложение в RPM пакет позволяет нам описать сценарии, которые будут происходить при распаковке нашего пакета.
Вот готовый pom.xml, который упакует наш проект в RPM пакет.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.your.project</groupId>
<artifactId>Test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Test</name>
<description>Test</description>
<properties>
<java.version>11</java.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>rpm-maven-plugin</artifactId>
<version>2.2.0</version>
<executions>
<execution>
<goals>
<goal>rpm</goal>
</goals>
</execution>
</executions>
<configuration>
<disabled>true</disabled>
<group>Test</group>
<mappings>
<mapping>
<directory>/opt/youruser/backend/resources</directory>
<username>youruser</username>
<groupname>youruser</groupname>
<filemode>755</filemode>
<sources>
<source>
<location>${project.basedir}/config/config.yml</location>
</source>
</sources>
</mapping>
<mapping>
<directory>/opt/youruser/backend</directory>
<username>youruser</username>
<groupname>youruser</groupname>
<filemode>755</filemode>
<sources>
<source>
<location>${project.basedir}/target/Test-0.0.1-SNAPSHOT.jar</location>
</source>
</sources>
</mapping>
<mapping>
<directory>/home/youruser</directory>
<username>youruser</username>
<groupname>youruser</groupname>
<filemode>755</filemode>
<sources>
<source>
<location>${project.basedir}/scripts/backend.sh</location>
</source>
</sources>
</mapping>
</mappings>
<preinstallScriptlet>
<scriptFile>${project.basedir}/scripts/preinstall.sh</scriptFile>
<fileEncoding>utf-8</fileEncoding>
</preinstallScriptlet>
<postinstallScriptlet>
<scriptFile>${project.basedir}/scripts/postinstall.sh</scriptFile>
<fileEncoding>utf-8</fileEncoding>
</postinstallScriptlet>
</configuration>
</plugin>
</plugins>
</build>
</project>
Теперь давайте подробно рассмотрим каждую секцию нашего pom.xml.
<groupId>org.codehaus.mojo</groupId>
<artifactId>rpm-maven-plugin</artifactId>
<version>2.2.0</version>
<executions>
<execution>
<goals>
<goal>rpm</goal>
</goals>
</execution>
</executions>
Здесь мы указываем, что для нашей сборки следую включить приведенный плагин, а также его цель это собрать RPM.
<mapping>
<directory>/opt/youruser/backend/resources</directory>
<username>youruser</username>
<groupname>youruser</groupname>
<filemode>755</filemode>
<sources>
<source>
<location>${project.basedir}/config/config.yml</location>
</source>
</sources>
</mapping>
Каждая секция делает следующее:
<directory> /opt/youruser/backend/resources - во время распаковки RPM архива положит в указанную директорию файл, который указан ${project.basedir}/config/config.yml. Указанный файл перед упаковкой должен лежать в указанной директории.
Данная операция будет осуществлена от имени youruser, который указан в тегах <username>;
Тег <filemode> говорит, о том какие права мы ходим присвоить указанному файлу после распаковки.
Таким же образом мы описываем требования ко всем файлам в том, числе и к JAR файлу, если мы хотим, чтобы он был упакован в наш RPM.
<preinstallScriptlet>
<scriptFile>${project.basedir}/scripts/preinstall.sh</scriptFile>
<fileEncoding>utf-8</fileEncoding>
</preinstallScriptlet>
Эта часть когда говорит о том, что перед установкой нашего RPM пакета выполни этот скрипт. Скрипт должен находиться по указанному адресу, для того, чтобы он мог быть упакован в RPM.
<postinstallScriptlet>
<scriptFile>${project.basedir}/scripts/postinstall.sh</scriptFile>
<fileEncoding>utf-8</fileEncoding>
</postinstallScriptlet>
Эта часть когда говорит о том, что после установки нашего RPM пакета выполни этот скрипт. Скрипт должен находиться по указанному адресу, для того, чтобы он мог быть упакован в RPM.
В этой статье не рассматриваются такие моменты как написание скриптов, однако скажу, что с помощью скриптов мы можем создавать юзеров, необходимые директории, сервисы, а также многое другое, то есть описать всю подготовительную работу, которую необходимо сделать для развертывания нашего приложения.
sudo yum localinstall YOUR_package.noarch.rpm
Данная команда распакует Ваш RPM пакет и выполнит все инструкции, которые вы указали при сборке Maven.