Developing Spring Boot Project Using Maven Docker Container

This tutorial uses Docker.v.4.24.2, Maven.v.3.8.5, OpenJDK.v.17, and SpringBoot.v.3.3.

[1] Create Spring Boot Project

Download spring boot demo project

https://archive.org/download/spring-boot/spring-boot-3-3-3-maven-demo.zip

Unzip to c:\users\user\MySpringBoot\project101\

[2] Change directory to the project root folder

cd c:\users\user\MySpringBoot\project101\

Outcome:

[3] Build and Run Spring Boot Application

[3.1] Build Spring Boot Application.

docker run --rm -v ${PWD}:/app -w /app maven:3.8.5-openjdk-17-slim mvn clean package

Console Output:

Components of the Command

  1. docker run:

    • This is the command to create and start a new container from a specified image.
  2. --rm:

    • This option automatically removes the container once it exits. This is useful for keeping your environment clean by not leaving stopped containers behind.
  3. -v ${PWD}:/app:

    • This flag mounts a volume.

    • ${PWD} is an environment variable that refers to the current working directory on your host machine.

    • :/app specifies that this directory on the host should be accessible at the /app path inside the container.

    • This allows you to use files from your local directory within the Docker container.

  4. -w /app:

    • This option sets the working directory inside the container to /app.

    • This means that any commands you run inside the container will be executed in this directory.

  5. maven:3.8.5-openjdk-17-slim:

    • This is the name of the Docker image to use.

    • It specifies a Maven image that includes version 3.8.5 of Maven and OpenJDK 17, optimized for a smaller size (-slim).

  6. mvn clean package:

    • This is the command that will be executed inside the container.

    • mvn is the command-line tool for Maven.

    • clean is a Maven goal that removes the target directory, which contains compiled artifacts.

    • package is another Maven goal that compiles the project and packages it into a JAR file, which will be placed in the target directory.

[3.2] Run Spring Boot Application.

docker run --rm -it -p 8080:8080 -v ${PWD}/target/demo-0.0.1-SNAPSHOT.jar:/app/app.jar openjdk:17-slim java -jar /app/app.jar

Console Output:

Components of the Command

  1. docker run:

    • This command is used to create and start a new container from a specified image.
  2. --rm:

    • This option tells Docker to automatically remove the container once it stops running. This helps to keep your system clean by avoiding leftover stopped containers.
  3. -it:

    • This flag combines two options:

      • -i: Keeps STDIN open even if not attached, allowing you to interact with the container.

      • -t: Allocates a pseudo-TTY, which makes it possible to have a terminal interface. This is especially useful for interactive applications.

  4. -p 8080:8080:

    • This option maps port 8080 on your host machine to port 8080 in the container.

    • This allows you to access the application running inside the container via http://localhost:8080.

  5. -v ${PWD}/target/demo-0.0.1-SNAPSHOT.jar:/app/app.jar:

    • This flag mounts a volume.

    • ${PWD}/target/demo-0.0.1-SNAPSHOT.jar refers to the JAR file in the target directory of your current working directory on the host.

    • :/app/app.jar specifies that this JAR file will be accessible at /app/app.jar inside the container.

    • This allows the Docker container to run the specific JAR file created by your Maven build.

  6. openjdk:17-slim:

    • This is the name of the Docker image to use.

    • It specifies a lightweight OpenJDK 17 image, suitable for running Java applications.

  7. java -jar /app/app.jar:

    • This is the command that will be executed inside the container.

    • java is the Java runtime command.

    • -jar specifies that you are running a JAR file.

    • /app/app.jar is the path to the JAR file inside the container that you mounted from your host.

Web output:

The Whitelabel Error Page with a 404 status indicates that the application is running, but it doesn't have a mapping for the URL you accessed.

At the moment there is only one java file:

...\project101\src\main\java\com\example\demo\DemoApplication.java

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

Code Breakdown

package com.example.demo;
  • Package Declaration: This line defines that the class belongs to the com.example.demo package. Packages in Java are used to group related classes and help avoid naming conflicts.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
  • Imports: These lines import necessary classes from the Spring Boot framework:

    • SpringApplication: This class is used to bootstrap and launch a Spring application from a Java main method.

    • SpringBootApplication: This annotation indicates that this class is the primary configuration class for the Spring Boot application.

@SpringBootApplication
public class DemoApplication {
  • Class Declaration: This line defines a public class named DemoApplication.

  • @SpringBootApplication Annotation: This annotation is a convenience annotation that combines three important Spring annotations:

    • @Configuration: Indicates that the class can be used by the Spring IoC container as a source of bean definitions.

    • @EnableAutoConfiguration: Enables Spring Boot’s auto-configuration feature, which automatically configures your application based on the dependencies present on the classpath.

    • @ComponentScan: Enables component scanning, allowing Spring to find and register beans (like controllers) in the specified package and its sub-packages.

    public static void main(String[] args) {
  • Main Method: This is the entry point of the Java application. The main method is where the application starts executing.
        SpringApplication.run(DemoApplication.class, args);
  • Run Method: This line calls the run method of the SpringApplication class. It takes two arguments:

    • DemoApplication.class: This specifies the primary Spring component (the class annotated with @SpringBootApplication) to start the application context.

    • args: This is the command-line arguments passed to the application, which can be used for configuration.

    }
}
  • Closing Braces: These close the main method and the class definition.

Stop the server (i.e. Press CTRL+C in PowerShell console window).

[4] Add Hello World Controller

[4.1] Add a new Java file HelloController.java

Place the file according to the below folder/file structure:

src
└── main
    └── java
        └── com
            └── example
                └── demo
                    ├── DemoApplication.java
                    └── HelloWorldController.java

[4.2] Edit the controller file.

Edit as follows:

package com.example.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    @GetMapping("/")
    public String hello() {
        return "Hello, World!";
    }
}

Code Breakdown

package com.example.demo;
  • Package Declaration: This line specifies that the class belongs to the com.example.demo package. Packages are used in Java to group related classes and avoid naming conflicts.
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
  • Imports: These lines import necessary classes from the Spring framework:

    • GetMapping: This annotation is used to map HTTP GET requests to specific handler methods.

    • RestController: This annotation indicates that the class is a RESTful controller, meaning it handles web requests and responses.

@RestController
public class HelloController {
  • Class Declaration: This line defines a public class named HelloController.

  • @RestController Annotation: This tells Spring that this class will handle web requests and that the return values of its methods will be converted to JSON (or other formats) and sent in the HTTP response body.

    @GetMapping("/")
    public String hello() {
  • Method Declaration: This declares a method named hello that returns a String.

  • @GetMapping("/") Annotation: This maps HTTP GET requests for the root URL (/) to this method. When a request is made to the root URL, this method will be invoked.

        return "Hello, World!";
    }
}
  • Return Statement: The method returns the string "Hello, World!". This string will be sent as the HTTP response body when the root URL is accessed.

[4.3] Build and Run Spring Boot Application

Build Spring Boot Application (refer Step 3.1).

Run Spring Boot Application (refer Step 3.2).