Skip to content

Spring Boot + Postgres DevContainer Setup to get you started with Spring Boot 3.5, OpenJDK 21 and Postgres 17.5. Batteries included.

License

Notifications You must be signed in to change notification settings

CWACoderWithAttitude/dc-spring-boot-mvp

Repository files navigation

TL;DR

Get your Spring Development booted. Plain & simple. Batteries included.

Project to get you started with building REST based webservices. Just Spring Boot and Postgres.

This is a stripped down version of dc-spring-boot-all-in-one which is a full blown devcontainer that includes Spring Boot, OpenJDK 21, Prometheus, AlertManager, Grafana and Mailcatcherfor building REST APIs with Spring Boot. It includes a lot of additional features like monitoring, testing, and more.

What’s inside?

This is an opinionated devcontainer.

It is not meant to be a complete solution for all use cases. It rather get you started. If you have any suggestions or feedback, please let me know.

Let’s have a look at the main components:

  • OpenJDK 21

  • Spring Boot 3.5.0

  • Maven 3.9.9

  • Postgres DB 17.5

  • Bruno Collection

All this implements this API

Screenshot of the Game Service OpenAPI UI

Components

Spring Boot - OpenJDK 21

Develop your Spring Boot 3.5 Service on OpenJDK 21.

For illustration I added an example REST-Service that manages data on games. This service exposes some technical metrics: JVM, Hibernate, Spring-Booot (Requests, Errors, etc.) and application specific metrics like the number of games in the database.

To assist your journey of building high quality web services:

  • Swagger / Open-API info is exposed on /swagger-ui/index.html.

  • Mavens JaCoCo plugin generates code coverage reports each time run ./mvnw package. The report is stored in target/site/jacoco/index.html. (Use the included Live server extension to view the report in your browser.)

games jacoco report
  • Basic build pipeline based on GitHub Actions is included. It runs the tests, builds the app and generates the JaCoCo report. The JaCoCo-Report is published to the project website

How to use this devcontainer?

Pre-Requisites

To use this devcontainer, you need to have the following prerequisites installed:

Once you have these prerequisites installed, you can open the devcontainer in VS Code.

Open the DevContainer

  1. Clone the repository:

git clone https://github.com/CWACoderWithAttitude/dc-spring-boot-mvp.git
cd dc-spring-boot-mvp
  1. Open the repository in Visual Studio Code. You can do this by either opening the folder in VS Code or by using the command line:

code -n .
  1. Open the Command Palette (Ctrl+Shift+P or Cmd+Shift+P on macOS) and select Remote-Containers: Open Folder in Container…​.

Default settings start the game-service on local port 9088.

The service implements a REST service that manages games. It allows you to create, read, update and delete games.

The Game-Service Open-API page show an overview of available endpoints.

You can access the service at http://localhost:8088. See Makefile for a list of commands to run the service, tests, and more. The make target fires up the spring-boot:run command which listens for file changes and automatically reloads the service when you change the code.

Makefile

The Makefile in the root folder provides convenient commands for building, running, testing, and maintaining the project. Below is a list of available targets:

Target Description

check_docker_compose_config

Validates the Docker Compose configuration for the devcontainer.

sb_clean

Cleans the Maven build artifacts for the game-service module.

sb_build

Builds the game-service module using Maven and creates a JAR file.

sb_run

Starts the game-service Spring Boot application in development mode (auto-reloads on code changes).

sb_debug

Starts the game-service Spring Boot application in debug mode (listening on port 8000 for a debugger).

build

Builds the Docker image for the game-service.

run

Runs the game-service Docker container (builds the image first if needed).

asciidoc2docbook

Converts AsciiDoc documentation to DocBook XML using Asciidoctor in Docker.

clean

Removes generated documentation files and build artifacts.

docbook2md

Converts DocBook XML documentation to Markdown using Pandoc in Docker.

generate_markdown

Cleans, converts AsciiDoc to DocBook, then to Markdown (full documentation conversion pipeline).

To use a target, run make <target> in the project root. For example, make sb_run will start the application.

For more details, see the Makefile itself.

Architecture Diagram

A picture is worth a thousand words. So let’s have a look at the architecture diagram of the devcontainer.

flowchart TD
    subgraph DevContainer: dc-spring-boot-mvp
        direction TB
        VSCode[VS Code<br/>]
        GamesService[games-service<br/>Java 21, Maven]
        Workspace[src workspace folder]
        User[vscode user]
    end

    VSCode -- connects to --> GamesService
    GamesService -- mounts --> Workspace
    GamesService -- runs as --> User
    GamesService -- postStartCommand --> Make[sb_run ]
    GamesService -- tools --> Node[Node.js, npm, eslint]
    GamesService -- tools --> Maven[Maven ]
Loading

Testing

I ship my examples with Bruno collections.

Please find the games api collection in the bruno folder.

You can import them into Bruno by clicking on the + icon in the top left corner and selecting Import Collection.

There’s a CLI tool to run collections, too:

❯ bru run . --reporter-html results.html
Running Folder

Create Game (200 ) - 71 ms
   ✓ assert: res.status: eq 200
   ✓ should return status 200 (OK)
   ✓ id of the create game entity should be greater than 0
Get all games (200 ) - 87 ms
   ✓ assert: res.status: eq 200
Get game by existing id (200 ) - 10 ms
   ✓ assert: res.status: eq 200
Get game by non-existing id (404 ) - 7 ms
   ✓ assert: res.status: eq 404
Update Game - existing id (200 ) - 16 ms
Monitoring - Metrics (200 ) - 11 ms
Monitoring - Info (200 ) - 2 ms
Monitoring - Health (200 ) - 4 ms
Delete Game by existing id (204 ) - 12 ms
   ✓ assert: res.status: eq 204
Delete Game by non existing id (404 ) - 9 ms
   ✓ assert: res.status: eq 404
Upload Games from JSON File (415 ) - 9 ms
Update Game - non existing id (200 ) - 7 ms

Requests:    12 passed, 12 total
Tests:       2 passed, 2 total
Assertions:  6 passed, 6 total
Ran all requests - 245 ms

Requests:    12 passed, 12 total
Tests:       2 passed, 2 total
Assertions:  6 passed, 6 total
Bruno CLI Report

I like Bruno - open source, local execution, no cloud services required. Support for GUI and CLI. Excellent support for adding asserts and test to your requests.

Persistence

Is implemented by Postgres This setup ships with an empty database. Using Bruno you can easily create items or upload the a set of default games. By default the service default games are loaded from file:///./games-service/src/(resources/board-games.json on startup if the db is empty.

Monitoring

Never underestimate the importance of monitoring your app. It is crucial to know how your app is doing in production. The demo app exposes default Spring Boot Actuator endpoints. This includes metrics, health, info and more. Some technical spring boot metrics. GamesController shows how to expose custom metrics.

For the sake of simplicity processing, rendering or gathering metrics is out of scope of this example.

Please refer to the "all-in-one" version.

DB Frontend

Adminer is a web based DB management tool that can be used to manage your database. It can be reached at http://localhost:8010 > DB Adminer. Please lookup the DB password fron .env file.

link:.devcontainer/.env[role=include]

Why DevContainer?

When developing a REST API you need to think about a lot of things.

You need to think about how to implement and test your code. And make sure it runs in a container.

This is a lot of stuff to think about. So I thought it would be a good idea to build a full blown REST API that covers all these topics. The goal is to show you how to do all this stuff in a simple way. The goal is not to build the best API ever.

Works on my machine!

We all "know"this is a bad slogan. But what if "works on my machine" simply means: great - ship it. What if we could turn "works on my machine" into "works in a container"? An envirnment that is consistent regardless of the host system.

Why devcontainers?

I want to show you why we should embrace the slogan "It works on my machine". Using devcontainers it is easy to build a product in an environment that’s pretty close to your prod env.

Let’s face it - we all have different machines and different setups. When using containers starting from day one you can be suree

ToDos

Topic here are listed in arbitrary order. They are not sorted by priority or anything else.

  • Test Guhub Actions locally with act

  • ✓ - publish JaCoCo Report to Project Website

  • ✓ - add a Makefile to run the service, tests, and more

  • ❏ - Automate conversion of asciidoc 2 markdown. Makefile contains generate_markdown: clean asciidoc2docbook docbook2md to do exactly that. It should be added to the build pipeline to generate the markdown file automatically…​

  • ❏ - addd appropriate icons to the architecture diagram

  • ❏ - fix test mocks for metrics and counters

  • ✓ - upgrade postgreso to a more recent version

  • ❏ - add more tests

About

Spring Boot + Postgres DevContainer Setup to get you started with Spring Boot 3.5, OpenJDK 21 and Postgres 17.5. Batteries included.

Topics

Resources

License

Stars

Watchers

Forks

Languages