如何从Java Gradle项目生成支持systemd的deb包并满足指定部署需求
生成带Systemd支持的Deb包的Gradle解决方案
我刚好做过类似的需求,用nebula-plugins/gradle-ospackage-plugin就可以实现(这个插件现在已经原生支持Systemd了,不用找替代方案),配合Shadow插件打包可执行Jar,就能完美满足你的要求。下面是一步一步的配置指南:
1. 引入必要的Gradle插件
首先在你的build.gradle(Groovy DSL)里添加这两个插件:
- Shadow插件:把Java项目打包成包含所有依赖的可执行Fat Jar
- Nebula OS Package插件:生成Deb/Rpm包,支持Systemd服务文件配置
plugins { id 'java' id 'com.github.johnrengelman.shadow' version '7.1.2' id 'nebula.ospackage' version '11.3.0' }
2. 配置可执行Jar(ShadowJar)
先把你的Java项目打包成可直接运行的Jar,指定主类入口:
shadowJar { manifest { attributes 'Main-Class': 'com.yourcompany.project.Main' // 替换成你的实际主类 } archiveBaseName.set('project') // 生成的Jar文件名前缀 archiveVersion.set('1.0.0') // 你的项目版本号 }
3. 配置Deb包生成规则
这部分是核心,我们要指定文件部署路径、生成Systemd服务文件,还要添加必要的安装脚本:
ospackage { // 基础包信息 packageName = 'project' version = '1.0.0' release = '1' arch = 'all' // 纯Java项目用all,如果有Native组件用amd64等 os = LINUX // 1. 部署Fat Jar到/var/project/bin/ from(shadowJar.archiveFile) { into '/var/project/bin' fileMode 0755 // 赋予可执行权限 } // 2. 部署配置文件到/etc/project/ from('src/main/resources/config') { // 替换成你的配置文件目录 into '/etc/project' fileMode 0644 // 配置文件通常用644权限 } // 3. 生成Systemd服务文件到/etc/systemd/system/ into('/etc/systemd/system') { from { // 动态生成service文件内容,你可以根据需求调整参数 def serviceContent = """[Unit] Description=Project Service After=network.target [Service] User=project Group=project WorkingDirectory=/var/project ExecStart=/usr/bin/java -jar /var/project/bin/${shadowJar.archiveFileName.get()} Restart=always RestartSec=3 Environment="JAVA_OPTS=-Xmx512m" // 可选:添加JVM参数 [Install] WantedBy=multi-user.target """ // 创建临时文件作为生成service的源 def tempFile = File.createTempFile('project', '.service') tempFile.text = serviceContent tempFile } rename { 'project.service' } fileMode 0644 // Systemd服务文件权限 } // 预安装脚本:创建必要的用户、组和目录 preInstall(''' getent group project || groupadd -r project getent passwd project || useradd -r -g project -d /var/project -s /sbin/nologin project mkdir -p /var/project /var/project/bin /etc/project chown project:project /var/project ''') // 安装后脚本:重载Systemd并启用服务 postInstall(''' systemctl daemon-reload systemctl enable project.service systemctl start project.service // 可选:安装后立即启动服务 ''') } // 确保Deb生成任务依赖ShadowJar任务,先打包Jar再生成Deb tasks.deb.dependsOn(tasks.shadowJar)
4. 生成Deb包
在项目根目录执行以下命令,生成的Deb包会在build/distributions目录下:
./gradlew deb
额外说明
- 如果你的配置文件需要模板替换(比如动态注入版本号),可以把service文件做成模板放在
src/main/resources,然后用expand()方法替换变量,比如:from('src/main/resources/project.service.template') { into '/etc/systemd/system' rename { 'project.service' } expand( jarFileName: shadowJar.archiveFileName.get(), projectVersion: version ) } - 如果你用Kotlin DSL(
build.gradle.kts),配置逻辑是一样的,只是语法需要调整成Kotlin风格。 - 安装Deb包后,你可以用
systemctl status project.service检查服务状态,用journalctl -u project.service查看日志。
内容的提问来源于stack exchange,提问作者Ali Ebrahiminejad
相关产品推荐
相关产品推荐

