Member-only story
Spring Boot: Multistage Dockerfile and Spring Application Profiles
I needed to automate the deployment process using GCP Cloud Run and Cloud Build for my NEST backend-as-a-service project.
One specific challenge was separating build and run processes using Dockerfile and Spring Profiles.
The reason for this is when the build runs in the GCP Cloud Build, the database is unavailable, so I needed to override these settings and unblock the build process (or make it independent from the data source — a separate Postgres DB).
This step-by-step tutorial explains how I used multistage Dockerfile and separate Spring Profiles to achieve this call.
Step 1: Define your default Spring Boot configuration
Add bootstrap.yaml:
spring:
datasource:
url: jdbc:postgresql://localhost:5432/nest
username: nest-server
password: secret
driver-class-name: org.postgresql.Driver
liquibase:
enabled: false
change-log: classpath:/db/changelog/changelog.yaml
management:
server:
port: 8881
server:
port: 8880
To enable the bootstrap configuration, you need to add spring-cloud-starter-bootstrap
the dependency:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>4.0.4</version>
</dependency>
Once you have a bootstrap configuration, other additional application configuration files will derive from it and can override its settings (we will see this in the example below).
Step 2: Build-specific Spring Boot profile
The second step is to have a separate profile with an in-memory database.
spring:
datasource:
url: jdbc:h2:mem:nest;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
username: sa
password:
driver-class-name: org.h2.Driver
liquibase:
enabled: false
change-log: classpath:/db/changelog/changelog.yaml
management:
server:
port: 8881
server:
port: 8880
Here, the H2 database engine is used as an in-memory database.