Table of Contents

Project setup

  • Language: Kotlin
  • Framework: Spring Boot (Uses application.yaml instead of application.properties)
  • Build tool: Gradle
  • Migration tool: Liquibase [this is new to me!]
  • Persistence layer: Postgres, an instance configured to run in Docker container
  • Testing: JUnit 5 and Testcontainers (for integration with the database)

Intention for running or testing locally

Here is how I intend to run and test this project locally.

  • Docker engine needs to be running in the background, for running the app and test suites to run.
  • App runs locally and connects to Postgres database instance in a docker container (in two terminal windows: docker-compose up and ./gradlew bootRun
  • The test suites (unit and integration) will spin up and down their own docker containers.

Steps

  1. Use Spring Initializr to generate a template
  2. Minimal steps to set up and connect a Postgres instance in Docker
  3. Minimal steps to set up Liquibase
  4. Get the one and only default SpringBootTest to run. This test checks that the context loads, i.e. the app could compile and run properly with all the specified dependencies loaded in the context.

More deets for individual steps

2. Setting up Postgres in docker

  • Configure datasource in application.yaml .
spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/compose-postgres
    username: compose-postgres
    password: compose-postgres
    driverClassName: org.postgresql.Driver
  • Create docker-compose.yaml as instructions for Docker to run the container with Postgres instance:
version: '2'

services:
  db:
    // this or other images listed on https://hub.docker.com/_/postgres
    image: 'postgres:13.1-alpine'
    container_name: spring-kt-app-db
    // Remember to expose the port!
    ports:
      - 5432:5432
    environment:
      - POSTGRES_USER=compose-postgres
      - POSTGRES_PASSWORD=compose-postgres

Detailed look

  • Run docker-compose up to create the container for the database:
// this name is defined in container_name: spring-kt-app-db rather than the service definition 'db'
Creating spring-kt-app-db … done

Attaching to spring-kt-app-db
// some other logs
  • Verify that you could get into the Postgres instance:
// substitute "db" with the container name
docker exec -it db bash

// substitute compose-postgres with the username
psql -h localhost -U compose-postgres

// list all the databases available
\l 

// list all the schemas available
\dn

#quit with Ctrl + D

3. Setup Liquibase

  • Create the master changelog file for Liquibase and place in the default package.
    • The default path and filename is classpath:/db/changelog/db.changelog-master.yaml
  • Since Spring Boot runs Liquibase database migrations automatically on application startup, the app could not start at this point because there is no migration available. So we have to disable Liquibase in application.yaml
spring:
  liquibase:
    enabled: false