Post

Deploy Spring Boot App as linux init.d service with Gradle via ssh

Intro

Let’s try to deploy Spring Boot app on a remote host with Gradle via ssh. For example, we can add gradle deploy task for previously created telegram bot and deploy it to my Raspberry pi

Create (extend) gradle build script

Full project source code available here

I will use gradle-ssh-plugin which provides convenient features for ssh connection and command execution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
plugins {
    id 'org.springframework.boot' version '2.7.5'
    id 'io.spring.dependency-management' version '1.1.0'
    id 'org.hidetake.ssh' version '2.10.1'
    id 'java'
}

ext {
    lombokVersion = '1.18.24'
    telegrambotsVersion = '6.1.0'
}

repositories {
    mavenCentral()
}

sourceCompatibility = JavaVersion.VERSION_11

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
    implementation 'org.springframework.boot:spring-boot-starter-logging'
    implementation "org.telegram:telegrambots-spring-boot-starter:${telegrambotsVersion}"

    // LOMBOK
    compileOnly "org.projectlombok:lombok:${lombokVersion}"
    annotationProcessor "org.projectlombok:lombok:${lombokVersion}"
    testCompileOnly "org.projectlombok:lombok:${lombokVersion}"
    testAnnotationProcessor "org.projectlombok:lombok:${lombokVersion}"

    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

test {
    useJUnitPlatform()
}

tasks.named('bootJar') {
    launchScript()
}

remotes {
    raspberrypi {
        host = '192.168.0.25'
        user = 'kali'
        password = 'kali'
    }
}

task deploy {
    dependsOn bootJar
    doLast {
        ssh.run {
            session(remotes.raspberrypi) {
                execute "sudo service $project.name stop", ignoreError: true
                put from: "$buildDir/libs/${project.name}.jar", into: "/home/kali/$project.name"
                execute "sudo ln -s /home/kali/$project.name/${project.name}.jar /etc/init.d/$project.name", ignoreError: true
                execute "sudo systemctl daemon-reload"
                execute "sudo systemctl enable $project.name"
                execute "sudo service $project.name start"
            }
        }
    }
}

wrapper {
    gradleVersion = '7.5.1'
    distributionType = Wrapper.DistributionType.BIN
}
  • sudo service $project.name stop stop service if exists and active
  • put from: "$buildDir/libs/${project.name}.jar", into: "/home/kali/$project.name" put built artifact to the remote
  • sudo ln -s /home/kali/$project.name/${project.name}.jar /etc/init.d/$project.name create symbolic link in /etc/init.d
  • sudo systemctl daemon-reload restart daemon to pick up new service
  • sudo systemctl enable $project.name make service run at startup
  • sudo service $project.name start start service

Deploy telegram bot as linux init.d service

1
2
3
4
5
6
7
8
9
10
11
12
14:16:38: Executing 'deploy'...

> Task :compileJava
> Task :processResources
> Task :classes
> Task :bootJarMainClassName
> Task :bootJar
> Task :deploy

BUILD SUCCESSFUL in 39s
5 actionable tasks: 5 executed
14:17:18: Execution finished 'deploy'.

Check service status

Bot Test service <service-name> status

This post is licensed under CC BY 4.0 by the author.
Buy me a coffee