Spring Boot: Multistage Dockerfile and Spring Application Profiles

Kanan Rahimov
2 min readAug 21, 2023
Application profiles and Multistage Dockerfile for Spring Boot

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.

--

--