docker-compose
spring boot
application.properties
environment variables
configuration management

docker-compose - externalize spring application.properties

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Externalizing Spring Boot configuration lets you change environment-specific settings without rebuilding the application image. In a Docker Compose setup, the usual options are mounting a configuration file, injecting environment variables, or pointing Spring Boot at an additional config location.

Use environment variables for simple properties

Spring Boot can bind many property values directly from environment variables. This is often the simplest option for secrets, hostnames, ports, and feature flags.

yaml
1services:
2  app:
3    image: myorg/my-spring-app:latest
4    ports:
5      - "8080:8080"
6    environment:
7      SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/appdb
8      SPRING_DATASOURCE_USERNAME: appuser
9      SPRING_DATASOURCE_PASSWORD: secret
10      SERVER_PORT: 8080

A property such as spring.datasource.url maps to SPRING_DATASOURCE_URL. This works well when the value is short and naturally scalar.

Mount an external application.properties file

For larger configuration sets, mounting a file is easier to maintain than expressing everything as environment variables.

yaml
1services:
2  app:
3    image: myorg/my-spring-app:latest
4    ports:
5      - "8080:8080"
6    volumes:
7      - ./config/application.properties:/config/application.properties:ro
8    environment:
9      SPRING_CONFIG_ADDITIONAL_LOCATION: file:/config/

In this setup:

  • the local file lives outside the image
  • Docker mounts it into the container at /config/application.properties
  • 'SPRING_CONFIG_ADDITIONAL_LOCATION tells Spring Boot to read that directory'

This is a good fit when developers want one committed base config and separate overrides for development, staging, and production.

Override only what changes

You do not need to move every setting out of the image. A common pattern is to keep defaults in the packaged application and override only environment-specific values from Compose.

For example, the application jar might contain:

properties
logging.level.root=INFO
spring.jpa.open-in-view=false
management.endpoints.web.exposure.include=health,info

Then Compose can override the deployment-specific parts:

yaml
1services:
2  app:
3    image: myorg/my-spring-app:latest
4    environment:
5      SPRING_PROFILES_ACTIVE: docker
6      SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/appdb
7      SPRING_REDIS_HOST: redis

That keeps the container image reusable while still allowing deployment differences.

Externalize profile-specific files

If your application uses profiles such as dev, staging, and prod, you can mount a profile-specific file and activate it explicitly.

yaml
1services:
2  app:
3    image: myorg/my-spring-app:latest
4    volumes:
5      - ./config/application-docker.properties:/config/application-docker.properties:ro
6    environment:
7      SPRING_PROFILES_ACTIVE: docker
8      SPRING_CONFIG_ADDITIONAL_LOCATION: file:/config/

Spring Boot will merge the active profile file with the default configuration, following its normal precedence rules.

End-to-end Compose example

yaml
1services:
2  db:
3    image: postgres:16
4    environment:
5      POSTGRES_DB: appdb
6      POSTGRES_USER: appuser
7      POSTGRES_PASSWORD: secret
8
9  app:
10    image: myorg/my-spring-app:latest
11    depends_on:
12      - db
13    ports:
14      - "8080:8080"
15    volumes:
16      - ./config/application.properties:/config/application.properties:ro
17    environment:
18      SPRING_CONFIG_ADDITIONAL_LOCATION: file:/config/
19      SPRING_PROFILES_ACTIVE: docker

This setup keeps the jar unchanged while Compose supplies the database connection and any deployment-specific file overrides.

Common Pitfalls

The most common mistake is mounting the file into the container but never telling Spring Boot where to read it. If the file is outside Spring Boot’s default search path, set SPRING_CONFIG_ADDITIONAL_LOCATION or SPRING_CONFIG_LOCATION appropriately.

Another issue is mixing profile activation and file placement incorrectly. Mounting application-prod.properties does nothing unless the matching profile is active or the file is imported explicitly.

Path confusion also causes failures. The path on the left side of the volume mapping is the host path, while the path on the right side is the container path. Verify both, especially when running Compose from a different working directory.

Finally, avoid baking secrets into application.properties inside the image if the deployment needs different credentials per environment. Use environment variables, secrets management, or mounted files with the appropriate access controls.

Summary

  • Use environment variables for simple Spring Boot overrides.
  • Mount an external properties file when the configuration set is larger or easier to manage as a file.
  • Point Spring Boot at mounted config with SPRING_CONFIG_ADDITIONAL_LOCATION or a similar setting.
  • Activate profiles explicitly when you rely on profile-specific property files.
  • Keep the image generic and push environment-specific values to Compose or a secrets system.

Course illustration
Course illustration

All Rights Reserved.