Spring Boot
Docker
External Configuration
Deployment
Containerization

Externalising Spring Boot properties when deploying to Docker

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Spring Boot applications are known for their ease of setup and powerful configuration capabilities. However, when deploying them as Docker containers, externalizing configuration becomes crucial for maintaining adaptable and secure systems. This article explores various techniques for managing Spring Boot properties in a Dockerized environment, maintaining flexibility without coupling configuration details to the container image.

Understanding the Need for Externalized Configuration

Externalizing configuration is essential for numerous reasons:

  • Environment-specific Configurations: Different environments (development, testing, production) require different settings.
  • Sensitive Information: Passwords and API keys should not be stored in the source code or Docker image.
  • Scalability: Applications must adapt without rebuilding Docker images.

Techniques for Externalizing Properties

Various methods can be employed to handle configuration management externally in Dockerized Spring Boot applications. Let's delve into some of the most effective strategies.

1. Using Docker Environment Variables

The simplest way to externalize configuration is by utilizing Docker’s inherent support for environment variables. These variables can be injected into the Spring Boot application by specifying them either in the docker run command or in a docker-compose.yml file.

In Docker CLI
bash
1docker run -e SPRING_DATASOURCE_URL=jdbc:mysql://localhost/testdb \
2    -e SPRING_DATASOURCE_USERNAME=root \
3    -e SPRING_DATASOURCE_PASSWORD=root \
4    my-spring-boot-app
In docker-compose.yml
yaml
1version: '3'
2services:
3  myapp:
4    image: my-spring-boot-app
5    environment:
6      - SPRING_DATASOURCE_URL=jdbc:mysql://localhost/testdb
7      - SPRING_DATASOURCE_USERNAME=root
8      - SPRING_DATASOURCE_PASSWORD=root

2. Using application-{profile}.properties

Spring Boot facilitates profile-based configurations. Each profile can have its own set of properties, which can be selected at runtime.

Structure
 
1src/main/resources/
2    application.properties
3    application-dev.properties
4    application-prod.properties

Select the active profile by passing the profile name as an environment variable or command-line argument when starting the Docker container.

bash
docker run -e SPRING_PROFILES_ACTIVE=prod my-spring-boot-app
yaml
1services:
2  myapp:
3    environment:
4      - SPRING_PROFILES_ACTIVE=prod

3. Mounting Config Volumes

Mounting a volume on the host system to /config or a different predefined directory can also perform property injection. The application.properties file or any other suitable file defining application settings can be placed in this directory.

bash
docker run -v /path/to/host/config:/config my-spring-boot-app

4. Spring Cloud Config

For sophisticated environments, Spring Cloud Config provides server and client-side support for centralized configuration management across distributed systems. The config server can access a version-controlled repository housing all application properties.

Config Server Setup

Configure the application to tell it which config server to use.

properties
spring.cloud.config.uri=http://my-config-server:8888

Combining Approaches

It's possible to combine these methods depending on requirements and organizational standards. For instance, a combination of Docker environment variables for sensitive data and volume mounts for other configurations creates a robust strategy.

Common Pitfalls

  1. Security Risks: Exposing sensitive information via environment variables or improperly secured volumes can lead to security breaches.
  2. Configuration Sprawl: Multiple sources of configurations may lead to redundancy and conflict. A well-documented configuration strategy is essential.
  3. Environment Synchronization: Ensure that environment variables and external configurations are synchronized correctly across various stages of deployment.

Table of Key Points

Configuration MethodImplementationUse Case
Docker Environment VariablesUse -e option in docker run or docker-compose.ymlQuick setup for environment-specific values
Profile-specific PropertiesUse application-{profile}.propertiesDifferentiation between environments using profiles
Config VolumesMount host configuration files to containerFlexible configuration without embedding in images
Spring Cloud ConfigCentralized management via Config ServerScalable solution for distributed systems needing shared configurations

Conclusion

Externalizing properties when deploying Spring Boot applications to Docker can significantly enhance flexibility, security, and ease of configuration management. Careful selection among environment variables, profile settings, volume mounts, and Spring Cloud Config, coupled with good practices, will ensure a robust configuration strategy for any deployment scenario.


Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.