Docker Compose for the Whole System
Run ShopEase Locally with One Command
Docker Compose starts all services plus the infrastructure they need (databases, Kafka, Zipkin) on one Docker network. Containers find each other by service name (kafka:9092, postgres:5432).
x-service-env: &service-env # shared variables, merged into each service below
SPRING_PROFILES_ACTIVE: docker
EUREKA_CLIENT_SERVICEURL_DEFAULTZONE: http://discovery-server:8761/eureka
SPRING_KAFKA_BOOTSTRAP_SERVERS: kafka:9092
MANAGEMENT_ZIPKIN_TRACING_ENDPOINT: http://zipkin:9411/api/v2/spans
SPRING_DATASOURCE_USERNAME: shopease
SPRING_DATASOURCE_PASSWORD: shopease
services:
postgres:
image: postgres:16
environment:
POSTGRES_USER: shopease
POSTGRES_PASSWORD: shopease # local only; use secrets in real environments
volumes:
- ./infra/create-databases.sql:/docker-entrypoint-initdb.d/init.sql # product_db, order_db, payment_db
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U shopease"]
interval: 5s
retries: 10
kafka:
image: apache/kafka:3.8.0 # KRaft mode, no ZooKeeper
environment:
KAFKA_NODE_ID: 1
KAFKA_PROCESS_ROLES: broker,controller
KAFKA_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:9093
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
healthcheck:
test: ["CMD-SHELL", "/opt/kafka/bin/kafka-broker-api-versions.sh --bootstrap-server localhost:9092 > /dev/null"]
interval: 10s
retries: 10
zipkin:
image: openzipkin/zipkin
ports: ["9411:9411"]
discovery-server:
build: ./discovery-server
ports: ["8761:8761"]
product-service:
build: ./product-service
environment:
<<: *service-env
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/product_db
depends_on:
postgres: { condition: service_healthy }
kafka: { condition: service_healthy }
order-service:
build: ./order-service
environment:
<<: *service-env
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/order_db
depends_on:
postgres: { condition: service_healthy }
kafka: { condition: service_healthy }
payment-service:
build: ./payment-service
environment:
<<: *service-env
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/payment_db
depends_on:
postgres: { condition: service_healthy }
kafka: { condition: service_healthy }
api-gateway:
build: ./api-gateway
ports: ["8080:8080"] # the ONLY service port published to the host
environment:
EUREKA_CLIENT_SERVICEURL_DEFAULTZONE: http://discovery-server:8761/eureka
depends_on: [discovery-server]
volumes:
pgdata:Note: x-service-env: &service-env defines a YAML anchor (Compose ignores top-level keys starting with x-), and <<: *service-env merges it into each service, so shared variables are written once. Of the business services only the gateway publishes a port (plus the Zipkin and Eureka dashboards); product, order and payment are reachable only inside the Compose network.
Start, Inspect, Stop
Example
docker compose up -d --build
docker compose ps
docker compose logs -f order-service
docker compose up -d --scale payment-service=2 # two instances, Eureka balances between them
docker compose down # add -v to delete the database volume tooExample output
NAME IMAGE SERVICE STATUS PORTS shopease-api-gateway-1 shopease-api-gateway api-gateway Up 40 seconds 0.0.0.0:8080->8080/tcp shopease-discovery-server-1 shopease-discovery-server discovery-server Up 41 seconds 0.0.0.0:8761->8761/tcp shopease-kafka-1 apache/kafka:3.8.0 kafka Up 52 seconds (healthy) 9092/tcp shopease-order-service-1 shopease-order-service order-service Up 30 seconds 8082/tcp shopease-payment-service-1 shopease-payment-service payment-service Up 30 seconds 8084/tcp shopease-postgres-1 postgres:16 postgres Up 52 seconds (healthy) 5432/tcp shopease-product-service-1 shopease-product-service product-service Up 30 seconds 8081/tcp shopease-zipkin-1 openzipkin/zipkin zipkin Up 52 seconds 0.0.0.0:9411->9411/tcp
Tip: For local development of one service, run only the infrastructure in Compose and the service in your IDE. Spring Boot 3.1+ can even start the Compose file for you with the spring-boot-docker-compose dependency.