Enterprise Java

Docker Compose for Spring Boot application with PostgreSQL

In this blog post you will learn how to configure Spring Boot application with PostgreSQL for running with Docker Compose.

This blog post covers:

  • Spring Boot application Dockerfile configuration with clean separation between dependencies and resources
  • Docker Compose configuration for running the application with PostgreSQL

Prerequisites

  • Docker
  • Java 13
  • Terminal
  • httpie (or curl)

Application

  • Generate the Maven based Spring Boot application with Spring Web, Spring Data JPA, Spring Data REST, PostgreSQL JDBC Driver dependencies.

The source code for this article can be found on Github: https://github.com/kolorobot/spring-boot-tc

Dockerfile

  • Create Dockerfile
  • Base Docker image uses Alpine Linux:
1
FROM openjdk:13-alpine
  • Do not run the application as root:
1
2
RUN addgroup -S spring && adduser -S spring -G spring
USER spring:spring
  • Do not deploy the fat-jar into the container, but rather split dependencies and application classes and resources into separate layers:
1
2
3
4
ARG DEPENDENCY=target/dependency
COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY ${DEPENDENCY}/META-INF /app/META-INF
COPY ${DEPENDENCY}/BOOT-INF/classes /app

Note: ARG can be used to adjust the directory, in case you you have Gradle based project: docker build --build-arg DEPENDENCY=build/dependency -t spring-boot-tc .

  • Run the application inside the containers by pointing the main class and the libs in the java command:
1
ENTRYPOINT ["java","-cp","app:app/lib/*","pl.codeleak.samples.springboot.tc.SpringBootTestcontainersApplication"]

The complete Dockerfile:

1
2
3
4
5
6
7
8
FROM openjdk:13-alpine
RUN addgroup -S spring && adduser -S spring -G spring
USER spring:spring
ARG DEPENDENCY=target/dependency
COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY ${DEPENDENCY}/META-INF /app/META-INF
COPY ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","pl.codeleak.samples.springboot.tc.SpringBootTestcontainersApplication"]

New to Docker? Docker explained in 12 minutes: https://www.youtube.com/watch?v=YFl2mCHdv24

Docker Compose

  • Create docker-compose.yml
  • We will have two services: db for PostgreSQL database and app for the application
    • db service will use the postgres image from a public repository, it will expose port 5432 to the host and it will pass the environment properties POSTGRES_* to the container to setup the database name, user and password.
    • app service will use the local build we created earlier, it will expose port 9000 to the host and it will pass the environment properties that will override the datasource configuration of the application (application.properties). The app service will depend on db service. The datasource URL uses the db as hostname which reflects the name of the db service.

The complete docker-compose.yml:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
version: '3'
 
services:
  db:
    image: "postgres"
    ports:
      - "5432:5432"
    environment:
      POSTGRES_DB: tc
      POSTGRES_USER: tc
      POSTGRES_PASSWORD: tc
  app:
    build: .
    ports:
      - "9000:8080"
    environment:
      SPRING_DATASOURCE_URL: jdbc:postgresql://db/tc
      SPRING_DATASOURCE_USERNAME: tc
      SPRING_DATASOURCE_PASSWORD: tc
    depends_on:
      - db

New to Docker Compose? Docker Compose explained in 12 min: https://www.youtube.com/watch?v=Qw9zlE3t8Ko

Running the application

  • Package the application

$ ./mvnw clean package

To skip the tests use: -DskipTests=true

  • Extract libraries from fat-jar

$ mkdir -p target/dependency && (cd target/dependency; jar -xf ../*.jar)

  • Run with docker-compose

$ docker-compose build && docker-compose up

  • Verify the application is running and responding to requests
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$ http get :9000/owners
 
HTTP/1.1 200
Connection: keep-alive
 
{
    "_embedded": {
        "owners": []
    },
    "_links": {
        "profile": {
            "href": "http://localhost:8080/profile/owners"
        },
        "self": {
            "href": "http://localhost:8080/owners{?page,size,sort}",
            "templated": true
        }
    },
    "page": {
        "number": 0,
        "size": 20,
        "totalElements": 0,
        "totalPages": 0
    }
}

Source code

The source code for this article can be found on Github: https://github.com/kolorobot/spring-boot-tc

References

See also

Published on Java Code Geeks with permission by Rafal Borowiec, partner at our JCG program. See the original article here: Docker Compose for Spring Boot application with PostgreSQL

Opinions expressed by Java Code Geeks contributors are their own.

Rafal Borowiec

Software developer, Team Leader, Agile practitioner, occasional blogger, lecturer. Open Source enthusiast, quality oriented and open-minded.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Google Translate
3 years ago

Hi…
I’m Elena gillbert.Spring Boot, Spring Security, JPA, and Docker Prerequisites: Docker; JDK 1.8; Maven 3.* Install and run the project. download/clone the project; Build the project using following maven command from project root folder where pom.xml file place.

Back to top button