How Docker Containers Really Talk to Each Other with Networks : My First Real DevOps Lesson

When I started learning Docker with a simple Spring Boot + MongoDB project, the tutor gave us two commands:

# Run the Spring Boot app
docker run -d -p 8080:8080 --name springapp \
  --network jionetwork \
  -e MONGO_DB_HOSTNAME=mongo \
  -e MONGO_DB_USERNAME=devdb \
  -e MONGO_DB_PASSWORD=dev@123 \
  kkdevopsb5/springwebapp:1.0.0

# Run the MongoDB database
docker run -d --name mongo \
  --network jionetwork \
  -e MONGO_INITDB_ROOT_USERNAME=devdb \
  -e MONGO_INITDB_ROOT_PASSWORD=dev@123 \
  mongo

The app worked fine after running these. But inside my head, one big question popped up:

👉 Why exactly are we running these commands in this way?
How did the Spring Boot container know that the mongo container is the database?

At first, I thought it was magic. Later, after some digging, it made complete sense. Let me share what I discovered.


Step 1: Spring Boot Doesn’t Hardcode DB Configs

In the source code, I found this application.yaml:

spring:
  data:
    mongodb:
      host: ${MONGO_DB_HOSTNAME}
      port: 27017
      username: ${MONGO_DB_USERNAME}
      password: ${MONGO_DB_PASSWORD}
      database: users
      authentication-database: admin

Notice the ${...} placeholders.
Spring Boot expects environment variables to fill these values at runtime.

That’s why the tutor passed:

  • -e MONGO_DB_HOSTNAME=mongo

  • -e MONGO_DB_USERNAME=devdb

  • -e MONGO_DB_PASSWORD=dev@123

Without these, the app wouldn’t know where the database lives or how to log in.

👉 Learning point: As DevOps, our job is not to code the app, but to read the config files (like application.yaml) and know what environment variables the app expects.


Step 2: Why mongo Instead of an IP Address?

This is where Docker networks come in.
Both containers were attached to the same custom network jionetwork.

In Docker, when you create a custom network:

  • Every container in that network can talk to others by name, not IP.

  • Docker runs an internal DNS resolver that maps names → container IPs.

So when Spring Boot tries to connect to mongo:27017, Docker resolves mongo to the real container IP behind the scenes.

Analogy: Calling a Friend

Think of it like calling a friend:

  • Without Docker network → you must remember your friend’s phone number (IP address).

  • With Docker network → you just say their name (e.g., “Call mongo”), and your phone (Docker DNS) automatically finds the correct number.

This makes things stable: even if MongoDB container restarts and gets a new IP, the name mongo still works.

Learning point: The whole purpose of Docker networks is to allow containers to communicate using names instead of IPs.


Step 3: Separation of Build vs Runtime

Another thing that confused me:
“Why doesn’t the Dockerfile mention Mongo anywhere?”

Then I realized:

  • Dockerfile = build instructions (package the JAR, set workdir, expose port)

  • docker run with -e = runtime instructions (which DB host, which credentials)

This separation is good practice. It means the same app image can be reused for:

  • Local environment → maybe DB host = localhost

  • Staging → DB host = mongo-staging

  • Production → DB host = mongo-prod

All without rebuilding the image.


What I Wish I Knew Earlier

  • Every framework has its own config system:

    • Spring Boot → application.yaml

    • Node.js → .env

    • Python Django/Flask → settings.py or .env

  • As DevOps, you don’t need to write app logic, but you must know where to look for DB configs, ports, and credentials.

  • Docker custom networks give you name-based communication, powered by Docker’s built-in DNS.


Final Takeaway

At first, I thought my tutor skipped details. But later I realized this is real-world learning:
In companies, no one explains every line. You get a repo and some commands, and it’s your job to retrospect and figure out:

  • Why these environment variables?

  • How do containers find each other?

  • What’s handled at build time vs runtime?

And that reflection — the “why” behind the command — is what transforms you from just running Docker to actually understanding DevOps.


Tip for beginners like me:
Whenever you see docker run with -e flags, pause and check the app’s config files.
That’s where the missing link hides — and once you see it, the whole flow makes sense.


✨ That’s the story of how I learned that docker run isn’t just about starting a container — it’s about passing the right environment and letting Docker networking + DNS do the magic.


1
Subscribe to my newsletter

Read articles from Jai Vardhan Narayana directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Jai Vardhan Narayana
Jai Vardhan Narayana