I'm experiencing an issue with my Docker Compose setup. My service (currency-exchange
) depends on both a MySQL database and a naming server. When I add depends_on
with the service_healthy
condition for the naming server, the entire application fails to start. However, when I remove the dependency on the naming server, the application starts successfully, but the naming server cannot register the service.
The strange part is that depends_on
works perfectly with the MySQL container, but it fails when applied to the naming server.
Here is my docker-compose.yml
file:
services:
currency-exchange:
image: mmusernmae/microservices-currency-exchange-service:0.0.1-SNAPSHOT
ports:
- "8000:8000"
networks:
- currency-network
depends_on:
my-sql-db:
condition: service_healthy
naming-server:
condition: service_healthy
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://my-sql-db:3306/currency_exchange_db?createDatabaseIfNotExist=true&useSSL=false&allowPublicKeyRetrieval=true
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: mypass55
EUREKA_CLIENT_SERVICE_URL_DEFAULT_ZONE: http://naming-server:8761/eureka
my-sql-db:
image: mysql/mysql-server:latest
environment:
MYSQL_ROOT_PASSWORD: mypass55
MYSQL_DATABASE: currency_exchange_db
MYSQL_USER: root
MYSQL_PASSWORD: mypass55
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -h localhost -u root -pmypass55"]
timeout: 20s
retries: 10
ports:
- "3306:3306"
networks:
- currency-network
naming-server:
image: mmusernmae/microservices-naming-server:0.0.1-SNAPSHOT
ports:
- "8761:8761"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8761/"]
interval: 30s
timeout: 10s
retries: 5
networks:
- currency-network
networks:
currency-network:
What I've Tried:
depends_on
with condition: service_healthy
.condition: service_completed_successfully
.Despite these attempts, the issue persists. Does anyone have insights into why depends_on
might not work with the naming server but works with the MySQL container? Any suggestions on how to resolve this?
Final solution:
I found the root causes of the issue, and here’s how I resolved it:
Incorrect Health Check Configuration for Naming Server:
The health check for the naming server was not set up correctly. Specifically, the container did not have the curl
command available to perform the health check. To resolve this, I created a custom Dockerfile for the naming server, using a base image that includes curl
:
FROM openjdk:17-jdk-slim
VOLUME /tmp
RUN apt-get update && apt-get install -y curl
COPY target/*.jar app.jar
ENTRYPOINT ["java","-jar", "app.jar"]
This ensured that the health check could be performed successfully.
Eureka Client Service URL Configuration Issue:
After fixing the health check, the services still could not register with the naming server. I discovered that the problem was related to the configuration of the EUREKA_CLIENT_SERVICE_URL_DEFAULT_ZONE
property.
There is a known issue with camel-casing in Spring Boot, where EUREKA_CLIENT_SERVICE_URL_DEFAULT_ZONE
is incorrectly converted to eureka.client.serviceurl.defaultzone
instead of eureka.client.serviceUrl.defaultZone
.
To fix this, I updated the environment variable to use the correct format:
environment:
eureka.client.serviceUrl.defaultZone: http://naming-server:8761/eureka
This change allowed the services to register correctly with the naming server.
For more details, you can refer to this Stack Overflow thread, which helped me identify the configuration issue.