Deploy Spring boot 3 application to Dokku environment with Dockerfile in 15 minutes
Tags: java, dokku, deployment, webdev
Published: 2023-08-24 03:15:17

**What you need**

About 15 minutes

IDE

- Spring Tool Suite (STS)
- IntelliJ
- VSCode

Environment

- Java 17
- Gradle 7.5+ or Maven 3.5+

A little knowledge about dokku and docker Here I use the ready-made Public IP with Ubuntu 22.04 TLS: 64.176.80.xxx

## Create a Spring boot 3
Source of web application creation from Spring homepage: [https://start.spring.io/](https://start.spring.io/)

Quick create link: [Link](https://start.spring.io/#!type=gradle-project&language=java&platformVersion=3.1.2&packaging=jar&jvmVersion=17&groupId=com.jackynote.dokkudemo&artifactId=spring-dokku-demo&name=spring-dokku-demo&description=Jacky%20create%20the%20first%20project%20and%20deploy%20to%20Dokku&packageName=com.jackynote.dokkudemo.spring-dokku-demo&dependencies=web)

If you use IntelliJ IDE to manage code and compile, you may encounter some errors like this:

> No matching variant of org.springframework.boot:spring-boot-gradle-plugin:3.1.2 was found

The workaround is pretty simple:

> Ctrl + Alt + S > Build, Execution, Deployment > Gradle > Gradle JVM -> java 17

Add a class `HomeController.java` in the directory `/src/main/java/com/jackynote/dokkudemo/springdokkudemo` with the following content, the goal is to see the application page The application can return a request with the complete response:

```Java
package com.jackynote.dokkudemo.springdokkudemo;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping
public class HomeController {
    @GetMapping
    ResponseEntity<String> getHome() {
        return ResponseEntity.accepted().body("Hello world!");
    }
}
```

You can then run the application using the Command line:

```Shell
./gradlew bootRun

```
Run the application on the browser at port: http://localhost:8080 and get the results returned from the browser as `Hello world`

Build the application and package it (jar file), the packaged application will be built in the folder: build/libs and you can find it:

```Shell
./gradlew build
# Run the jar file to see if it is correct for the debuging environment.
java -jar build/libs/spring-dokku-demo-0.0.1-SNAPSHOT.jar
```

## Deploy the application to Dokku with Dockerfile

To setup Dokku environment, you can read from official website: https://dokku.com/

**Create Dockerfile**

```Shell
cd /home/dokku/first-app
vi Dockerfile
```

And copy the content below or you can write your own script if you already have knowledge of docker and use them proficiently:

```Docker
FROM openjdk:17
MAINTAINER Andy <jackynote.pro@gmail.com>
 
RUN mkdir /app
WORKDIR /app/
ADD ./spring-dokku-demo-0.0.1-SNAPSHOT.jar /app/
  
CMD java -jar spring-dokku-demo-0.0.1-SNAPSHOT.jar
 
EXPOSE 8080
```
Push the jar file from the local environment on the prepared server at the directory created for the application using Dokku:

```Shell
# copy from the project folder to the application folder on the server
scp ~/<Project_Folder>/build/libs/spring-dokku-demo-0.0.1-SNAPSHOT.jar root@64.176.80.xxx:/home/dokku/first-app
root@64.176.80.xxx's password: ...
```

**Deploy Web Application**

SSH into the prepared server and execute the following scripts to deploy the application:

```Shell
# go to the project's folder
cd /home/dokku/first-app
# build app with pushed jar file and generated Dockerfile
docker build -t dokku/first-app .
# some settings like nginx, port mapping from docker to public environment
dokku proxy:set first-app nginx
dokku ports:add first-app http:8080:8080
# deploy application
dokku deploy first-app
```

After successfully deploying you will get the following successful results:

```Shell
-----> Deploying web (count=1)
       Attempting pre-flight checks (1.)
-----> Executing 1 healthchecks                                                        
       Running healthcheck name='default' type='uptime' uptime=10                      
       Healthcheck succeeded name='default'                                            
       All checks successful (1.)
=====> Start of first-app container output (1.)
         .   ____          _            __ _ _
        /\\\\\\\\ / ___'_ __ _ _(_)_ __  __ _ \\\\ \\\\ \\\\ \\\\
       ( ( )\\\\___ | '_ | '_| | '_ \\\\/ _` | \\\\ \\\\ \\\\ \\\\
        \\\\\\\\/  ___)| |_)| | | | | || (_| |  ) ) ) )
         '  |____| .__|_| |_|_| |_\\\\__, | / / / /
        =========|_|==============|___/=/_/_/_/
        :: Spring Boot ::                (v3.1.2)
       2023-08-22T09:41:22.960Z  INFO 6 --- [           main] c.j.d.s.SpringDokkuDemoApplication       : Starting SpringDokkuDemoApplication v0.0.1-SNAPSHOT using Java 17.0.2 with PID 6 (/app/spring-dokku-demo-0.0.1-SNAPSHOT.jar started by root in /app)
       2023-08-22T09:41:22.967Z  INFO 6 --- [           main] c.j.d.s.SpringDokkuDemoApplication       : No active profile set, falling back to 1 default profile: "default"
       2023-08-22T09:41:25.282Z  INFO 6 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
       2023-08-22T09:41:25.306Z  INFO 6 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
       2023-08-22T09:41:25.307Z  INFO 6 --- [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.11]
       2023-08-22T09:41:25.583Z  INFO 6 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
       2023-08-22T09:41:25.586Z  INFO 6 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2495 ms
       2023-08-22T09:41:26.906Z  INFO 6 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
       2023-08-22T09:41:26.943Z  INFO 6 --- [           main] c.j.d.s.SpringDokkuDemoApplication       : Started SpringDokkuDemoApplication in 4.908 seconds (process running for 6.896)
=====> End of first-app container output (1.)
=====> Triggering early nginx proxy rebuild
-----> Running post-deploy
 !     Detected IPv4 domain name with nginx proxy enabled.
 !     Ensure the default nginx site is removed before continuing.
-----> Renaming containers
       Container type (1) is no longer defined. Removing state
-----> Checking for postdeploy task
       No postdeploy task found, skipping
```
Try accessing the application from the browser via the address: `http://64.176.80.xxx:8080/`

If you cannot access the application from the internet with a public IP, then it may be necessary to open port 8080 from your server:

```Shell
sudo ufw allow 80
sudo ufw allow 443
sudo ufw allow 8080
```