In the AdventureTube backend microservices architecture, configuration management is handled through a collaboration between Spring Cloud Config Server and environment (.env
) files. This setup ensures consistency, flexibility, and secure handling of configuration data across different stages of deployment.
π§© Background of env.XXX
File Design
The original idea behind creating env.XXX
files was for Docker-based environments, because Docker Compose provides the --env-file
option, which:
Loads environment variables before any container starts
Makes those variables available to Spring Boot during early startup
Ensures full compatibility with
spring.config.import
, Maven build steps, and Config Server resolution
However, when running services outside Docker β such as during local development or Maven test execution β there is no native mechanism for loading .env
files unless manually handled. This is where the custom DotenvEnvironmentPostProcessor
comes in:
It uses the
dotenv
package to load.env
files manuallyIt applies these values to the Spring
Environment
during application startupBut it runs too late to influence
application.yml
values such as${CONFIG_SERVER_URL}
inspring.config.import
As a result, for non-Docker scenarios, the only reliable ways to make CONFIG_SERVER_URL
work early are:
Manually setting environment variables in IntelliJ Run Configurations
Defining them in the parent
pom.xml
using themaven-surefire-plugin
, like the following example:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<environmentVariables>
<SPRING_PROFILES_ACTIVE>mac</SPRING_PROFILES_ACTIVE>
<CONFIG_SERVER_URL>http://192.168.1.105:9297</CONFIG_SERVER_URL>
</environmentVariables>
</configuration>
</plugin>
π§ Role of .env
Files
.env
files are used only during the bootstrap phase of each service, mainly in development or local setups. Their purpose is to define variables such as:
SPRING_PROFILES_ACTIVE=dev
CONFIG_SERVER_URI=http://localhost:8888
These values help Spring Boot determine:
Which profile to activate
Where to locate the Config Server
.env
files should never be committed to Git, especially if they contain secrets.
βοΈ Role of Spring Cloud Config Server
The Config Server serves as the central source of configuration for all microservices. It pulls configuration files from a Git repository and distributes them based on:
Application name (e.g.
auth-service
,member-service
)Active profile (e.g.
dev
,qa
,prod
)
π Example Config Repo Structure:
config-repo/
βββ auth-service-dev.yml
βββ auth-service-qa.yml
βββ member-service-dev.yml
βββ application.yml
Sample auth-service-dev.yml
:
spring:
datasource:
url: jdbc:postgresql://localhost:5432/authdb
username: dev_user
password: ${DB_PASSWORD}
Secrets like
DB_PASSWORD
are injected via environment variables or a Vault service β not stored in Git.
π Collaboration Flow
Developer loads a
.env
file to exportSPRING_PROFILES_ACTIVE
andCONFIG_SERVER_URI
Spring Boot reads
bootstrap.yml
and connects to the Config ServerThe service requests its config from
config-server/{app-name}-{profile}.yml
The Config Server delivers environment-specific configurations
Secrets are injected dynamically, not stored statically
π§ͺ Current Environment Setup
Environment | Description | Profile |
---|---|---|
π§βπ» Developer | Local Mac with .env file | dev |
π QA Server | Raspberry Pi (via NGINX Proxy Manager) | qa |
βοΈ Production | AWS (to be implemented) | prod |
π Service Initiation Paths
The AdventureTube backend supports three distinct initiation processes, each utilizing the combination of .env
files and the Config Server:
1. π§ͺ Maven Build/Test Process
Used when compiling or packaging the application via Maven.
Runs tests by default unless explicitly skipped (
-DskipTests
).Test phase can pick up environment variables if set in the terminal or CI.
If
CONFIG_SERVER_URL
is needed, it must be injected via Maven profile or system properties β.env
post-processing won’t apply early enough.
2. π» IntelliJ Runtime Process
Used when running individual services via IntelliJ Run Configurations.
Environment variables (
SPRING_PROFILES_ACTIVE
,CONFIG_SERVER_URL
) are set through the Run Configβs Environment Variables section.This process allows live dev/testing with a fully wired Config Server setup.
3. π³ Docker Compose Process
Initiated via
docker-compose up
.Uses the
--env-file
option orenv_file:
directive indocker-compose.yml
to inject variables.These variables are set as real OS-level environment variables, and are available immediately during the Spring Boot config bootstrap phase.
β οΈ Subtle but Critical Distinction: .env
via Docker vs. PostProcessor
Source | When Available to Spring Boot | Can Influence spring.config.import ? |
---|---|---|
.env via --env-file in Docker | β Before Spring Boot starts | β Yes |
.env via DotenvEnvironmentPostProcessor | β After initial config loading starts | β No |
β
Why Docker’s .env
Works
Docker injects variables before the Spring application launches
These are true environment variables, so Spring can resolve them in early YAML parsing (e.g.,
${CONFIG_SERVER_URL}
inspring.config.import
)
β Why DotenvEnvironmentPostProcessor
Is Too Late
PostProcessors run after Spring has already loaded
application.yml
Any placeholder like
${CONFIG_SERVER_URL}
inspring.config.import
will fail to resolve if it’s only set in.env
via this PostProcessor
β Best Practices Summary
π Do not commit secrets to Git β use Vault or env vars
π Use
.env
for local-only bootstrap needsπ Use Spring Config Server for centralized, versioned config
π³ For Docker, use
--env-file
orenv_file:
to inject values earlyπ Avoid relying on
.env
files for early YAML resolution β use OS env vars or system properties
This structure provides a scalable, secure, and environment-agnostic way to manage configuration in Spring Boot microservices.