🔥 Launch Offer: Interview Preparation Bundle @ ₹2,499 ₹9,999 • 75% OFF. Offer expires in 🔥 Launch Offer: Interview Preparation Bundle @ ₹2,499 ₹9,999 • 75% OFF. Offer expires in Interview Preparation Bundle @ ₹2,499 ₹9,999

00:00:00 Get Bundle
home spring boot spring-cloud-config-docker-the-professional-way-to-configure-microservices
Interview guide Spring Boot 36 sections

Spring Cloud Config + Docker: The Professional Way to Configure Microservices

One of the most common challenges when building Spring Boot microservices is making the same application work seamlessly in different environments. For example: You run the application from…

Start reading
By javainterviewprep June 10, 2026 8 min read

One of the most common challenges when building Spring Boot microservices is making the same application work seamlessly in different environments.

For example:

  • You run the application from IntelliJ on your local machine.
  • Later, you deploy the same application inside Docker.
  • Eventually, you may deploy it to Kubernetes or a cloud platform.

The problem is that each environment has different ways of reaching the Config Server.

If you hardcode one URL, another environment will fail.

Many beginners solve this by maintaining multiple configuration files or changing the source code before deployment.

Professional teams don’t do that.

Instead, they let Spring Boot’s configuration hierarchy handle everything.

In this article, you’ll learn:

  • Why localhost works locally but not inside Docker
  • How Docker overrides application.yml
  • How Spring Boot decides which property to use
  • Why environment variables have higher priority
  • How Docker networking works internally
  • The complete execution flow
  • Interview questions and answers

By the end, you’ll understand how one JAR file can run perfectly in both local and Docker environments without changing a single line of code.


The Problem

Suppose you have the following architecture.

                    Client Microservice
│
│
â–¼
Spring Cloud Config Server
│
â–¼
Git Repository

Every microservice needs to contact the Config Server during startup to fetch its configuration.

But the Config Server address changes depending on where the application runs.

Local Development

Config Server

http://localhost:8071

Docker

Config Server

http://configserver:8071

Why are they different?

Let’s understand.


Running the Application Locally

Suppose you start the Config Server directly from IntelliJ.

Config Server
Running on your laptop

Port 8071

Now your Accounts service also runs from IntelliJ.

Both applications are running on the same operating system.

+--------------------------------+

Your Laptop

Accounts Service

Config Server

+--------------------------------+

Since both applications are running on the same machine, they communicate using localhost.

Your application.yml looks like this:

spring:
application:
name: accounts

config:
import: "configserver:http://localhost:8071"

server:
port: 8080

During startup, Spring Boot reads:

configserver:http://localhost:8071

Then it contacts the Config Server.

Accounts Service
│
â–¼
localhost:8071
│
â–¼
Config Server
│
â–¼
Git Repository

Everything works perfectly.


Why Doesn’t localhost Work Inside Docker?

Now imagine every application is running inside its own container.

+--------------------+
| Accounts Container |
+--------------------+

+--------------------+
| Config Container |
+--------------------+

Many developers assume:

localhost:8071

will still work.

It won’t.

This is because localhost always refers to the current machine or container.

Inside the Accounts container,

localhost

means

Accounts Container

NOT

Config Server Container

So Spring Boot tries to find the Config Server inside the Accounts container itself.

There isn’t one.

The result:

Connection Refused

or

UnknownHostException

depending on the configuration.


How Docker Solves This Problem

Docker Compose automatically creates an internal network.

For example,

services:

configserver:

accounts:

loans:

cards:

Docker creates something similar to:

Internal Docker Network

Every service name automatically becomes a DNS hostname.

configserver

accounts

cards

loans

Now the Accounts service can simply call

http://configserver:8071

Docker internally converts

configserver

into the Config Server container’s IP address.

No IP address needs to be written manually.


Why Not Put configserver in application.yml?

Some beginners write:

spring:
config:
import: "configserver:http://configserver:8071"

Looks good.

Until they run the application locally.

Spring Boot now tries to resolve

configserver

through the operating system.

Windows or macOS says:

Who is configserver?

There is no such hostname.

Because Docker isn’t running the application.

The result:

java.net.UnknownHostException: configserver

This is why we keep

localhost

inside the source code.


The Professional Solution

Instead of modifying the source code for Docker, Docker overrides the property using an environment variable.

Your application.yml remains:

spring:
application:
name: accounts

config:
import: "configserver:http://localhost:8071"

Now create a common Docker Compose configuration.

services:

microservice-configserver-config:

environment:

SPRING_CONFIG_IMPORT: "configserver:http://configserver:8071"

SPRING_PROFILES_ACTIVE: "default"

Then every service extends it.

accounts:

extends:
file: common-config.yml
service: microservice-configserver-config

environment:
SPRING_APPLICATION_NAME: "accounts"

Notice something interesting.

We never changed

application.yml

Instead,

Docker simply injects

SPRING_CONFIG_IMPORT

during container startup.


How Does Spring Boot Know Which Value to Use?

Spring Boot loads configuration from multiple sources.

Each source has a priority.

Higher-priority sources override lower-priority ones.

A simplified priority order is:

PriorityConfiguration Source
HighestCommand-line arguments
2Java System Properties
3Environment Variables
4application.properties / application.yml
LowestDefault values inside code

Because Docker sets

SPRING_CONFIG_IMPORT

as an environment variable,

Spring Boot ignores the value from

application.yml

and uses the Docker value instead.

No code changes.

No rebuild.

No separate JAR.


Complete Startup Flow (Local)

application.yml
│
â–¼
configserver:http://localhost:8071
│
â–¼
Spring Boot
│
â–¼
Config Server
│
â–¼
Git Repository

Complete Startup Flow (Docker)

application.yml
│
â–¼
localhost:8071
│
â–¼
Docker Environment Variable

SPRING_CONFIG_IMPORT
=configserver:http://configserver:8071
│
â–¼
Overrides application.yml
│
â–¼
Spring Boot
│
â–¼
configserver:8071
│
â–¼
Docker DNS
│
â–¼
Config Server Container
│
â–¼
Git Repository

What Happens Internally During Startup?

Let’s follow the sequence step by step.

Step 1

Docker starts the Accounts container.

docker-compose up

↓

Step 2

Docker injects environment variables.

SPRING_CONFIG_IMPORT

SPRING_APPLICATION_NAME

SPRING_PROFILES_ACTIVE

↓

Step 3

Spring Boot starts.

↓

Step 4

Spring Boot reads all property sources.

application.yml

Environment Variables

System Properties

Command Line

↓

Step 5

Spring Boot merges all configurations.

↓

Step 6

Environment variables override duplicate keys.

application.yml

↓

SPRING_CONFIG_IMPORT

wins

↓

Step 7

Spring Boot contacts

configserver:8071

↓

Step 8

Docker DNS resolves

configserver

↓

Step 9

The Config Server returns configuration from the Git repository.

↓

Step 10

The Accounts service starts successfully.


Why Use a Common Docker Configuration?

Instead of repeating the same environment variables in every service, create a reusable configuration.

common-config.yml

Then each service extends it.

Benefits:

  • No duplication
  • Easier maintenance
  • Consistent configuration across all services
  • Easier to add new microservices
  • Single place to modify common settings

This follows the DRY (Don’t Repeat Yourself) principle.


Common Mistakes

Mistake 1

Using

configserver

inside application.yml.

Result:

UnknownHostException

when running locally.


Mistake 2

Using

localhost

inside Docker.

Result:

Connection refused

because localhost refers to the current container.


Mistake 3

Creating different source code for Docker and local execution.

Result:

  • Multiple configuration files
  • Maintenance headaches
  • Deployment errors

Mistake 4

Building separate JAR files for different environments.

This defeats the purpose of externalized configuration.

A single application artifact should work everywhere.


Best Practices

  • Keep application.yml suitable for local development.
  • Override environment-specific values using environment variables.
  • Use Docker service names for inter-container communication.
  • Store shared Docker configuration in a common Compose file.
  • Never hardcode environment-specific values into application code.
  • Build once, deploy everywhere.

Interview Questions and Answers

Q1. How do you configure Spring Cloud Config to work both locally and in Docker?

Answer:

“In my client microservices, I configure the Config Server URL as http://localhost:8071 in application.yml so the application works when running from IntelliJ or any local environment. For Docker deployments, I don’t change the source code. Instead, I override the property using the environment variable SPRING_CONFIG_IMPORT=configserver:http://configserver:8071. Spring Boot gives higher priority to environment variables than application.yml, so the Docker value automatically replaces the local value. This allows the same JAR or Docker image to work in both environments without any code changes.”


Q2. Why doesn’t localhost work inside Docker?

Answer:

Because localhost always points to the current container. If the Accounts service uses localhost:8071, it tries to connect to port 8071 within its own container instead of the Config Server container.


Q3. Why does configserver work inside Docker?

Answer:

Docker Compose creates an internal network and automatically registers each service name as a DNS hostname. Therefore, configserver resolves to the IP address of the Config Server container, allowing other containers to communicate using the service name.


Q4. Why not keep configserver in application.yml?

Answer:

Because when running the application directly from the IDE, the operating system has no knowledge of the Docker service name configserver. This results in an UnknownHostException. Using localhost for local development and overriding it in Docker avoids this issue.


Q5. Why are environment variables preferred for environment-specific configuration?

Answer:

Environment variables externalize configuration from the application. They allow the same application artifact to run across development, testing, staging, and production environments without rebuilding or modifying the source code. Spring Boot’s property precedence ensures they override values defined in configuration files.


Key Takeaways

  • localhost works only when the client and Config Server run on the same machine.
  • Inside Docker, localhost refers to the current container, not another service.
  • Docker Compose automatically exposes service names as DNS hostnames.
  • Spring Boot gives environment variables higher priority than application.yml.
  • SPRING_CONFIG_IMPORT overrides the Config Server URL at runtime.
  • A single JAR or Docker image can be reused across local, Docker, and cloud environments without code changes.
  • Centralizing shared Docker settings in a common Compose file improves maintainability and follows the DRY principle.

By understanding Spring Boot’s configuration precedence and Docker’s networking model, you can design microservices that are portable, maintainable, and production-ready—using the same codebase and the same application artifact in every environment.