Docker & Kubernetes Deployment
Docker Compose for Local Development — App + DB + Redis + Kafka
Orchestrating all dependencies locally with a single command.
Interview: Local infrastructure orchestration. Expect questions on service networking, container start ordering, profile-based configuration injection, and volume data persistence.
Introduction
Orchestrating databases, caches, and message brokers manually on developer machines is error-prone. A developer might run a different database version or config parameter than production, leading to unexpected runtime errors.
**Docker Compose** orchestrates all application dependencies with a single command. By containerizing your Spring Boot service, databases, and message brokers, you ensure that every team member runs an identical development environment.
Why It Matters
Using Docker Compose streamlines developer onboarding, isolates local storage, and enables testing integrations (like DB queries, Redis caching, or Kafka events) locally before pushing changes.
Overriding Spring Properties with Environment Variables
Spring Boot automatically maps uppercase environment variables containing underscores to configuration properties. For example:
SPRING_DATASOURCE_URLoverridesspring.datasource.urlSPRING_DATA_REDIS_HOSToverridesspring.data.redis.hostSPRING_KAFKA_BOOTSTRAP_SERVERSoverridesspring.kafka.bootstrap-servers
Practical Example
Let's write a docker-compose.yml file orchestrating our application alongside PostgreSQL, Redis, and a Kafka cluster:
Quick Quiz
Q1: How does the Spring Boot application container find and connect to the database container inside the Compose network?
A) By using the public IP address of the developer's host computer.
B) By querying the docker network's embedded DNS using the database service name (postgres-db) as the hostname.
C) It communicates via localhost on shared ports.
D) It must run in the host network namespace.
Answer: B — Docker Compose creates a default bridge network. It resolves container service names to their dynamic container IPs automatically.
Scenario-Based Challenge
Production Scenario:
You configure your app container with depends_on: [postgres-db]. When you run docker compose up, the app container crashes because it tries to connect to PostgreSQL before the database has finished initializing. Why did this happen, and how do you resolve it?
To prevent the app from starting before the database is fully initialized:
1. **Understand raw depends_on:** By default, depends_on only waits for the dependency container to start, not for its internal database service to be ready to accept connections.
2. **Add a Healthcheck:** Define a health check command under the database service (e.g. using pg_isready).
3. **Add service_healthy Condition:** Update the depends_on directive in the app service to require the database container to be healthy before starting:
depends_on:
postgres-db:
condition: service_healthy
Interview Questions
1. How do you persist PostgreSQL data across "docker compose down" commands?
Use Docker Volumes. Map a named volume (e.g. pgdata) to the database data directory (/var/lib/postgresql/data) inside the database service container definition. Docker volumes persist on the host filesystem independently of the container lifecycle.
Production Considerations
Never store production passwords directly in your local docker-compose.yml file. Use an external .env file to define sensitive parameters locally and add it to your .gitignore.