Spring cloud config server not working with docker compose
I have a spring cloud config server and packaged as a docker image, then I have a spring cloud eureka server that is also packaged as a docker image.
When I run two applications using docker I get the following error.
discovery-service_1 | 2017-06-24 15:36:12.059 INFO 5 --- [ main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at: http://config-service:9001
discovery-service_1 | 2017-06-24 15:36:12.997 WARN 5 --- [ main] c.c.c.ConfigServicePropertySourceLocator : Could not locate PropertySource: I/O error on GET request for "http://config-service:9001/cls-discovery-service/default": Connection refused (Connection refused); nested exception is java.net.ConnectException: Connection refused (Connection refused)
Even though the configuration service is up and running successfully, service discovery still doesn't find it for some reason.
The Dockerfile used here is
version: '2'
services:
config-service:
image: cloudsea/cls-config-service
ports:
- 9001:9001
expose:
- "9001"
discovery-service:
image: cloudsea/cls-discovery-service
depends_on:
- config-service
environment:
CLOUD_SEA_CONFIG_SERVER_URI: http://config-service:9001
EUREKA_DEFAULT_ZONE_URL: http://discovery-service:8761/eureka/
ports:
- 8761:8761
links:
- config-service:config-service
Below bootstrap.properties for DISCOVERY SERVICE
spring.cloud.config.uri = ${CLOUD_SEA_CONFIG_SERVER_URI:http://localhost:9001}
spring.application.name = ${SPRING_APPLICATION_NAME:cls-discovery-service}
Below is cls-discovery-service.properties for DISCOVERY service located in github.
server.port=${SERVER_PORT:8761}
eureka.client.registerWithEureka: false
eureka.client.fetchRegistry: false
eureka.client.serviceUrl.defaultZone: ${EUREKA_DEFAULT_ZONE_URL:http://localhost:8761/eureka/}
eureka.server.eviction-interval-timer-in-ms: 1000
I am guessing that there is something wrong with my docker-compose.yml, but I am not sure.
Any help would I stick with this for hours ... heading close to the days :(
I solved it by adding this config to the bootstrap.yml discovery service .
spring:
cloud:
config:
failFast: true
retry:
initialInterval: 3000
multiplier: 1.3
maxInterval: 5000
maxAttempts: 20
Then add spring-boot-starter-aop and spring-retry to maven discovery services ... p>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>${spring-boot-starter-aop.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>${spring-retry.version}</version>
</dependency>
The problem is they both start at the same time. But the discovery service depends on the configuration service.
When you start the discovery service, it will tell you " Remove configuration from server " again and again until the configuration service is ready.
Once the configuration service has started, the discovery service is going to successfully complete its configuration and then will start on its own.
I faced the same problem and got a bit stuck and I was going to go the same way as repeating spring, which is not a bad pattern to implement it. but the main problem here is the docker startup order is misplaced. I'll share with my working batch file, it's very similar, but the key here is the "depends_on" parameter. I added quotes from my arguments and it seems to work.
version: "2"
services:
eureka:
image: eurekatest
ports:
- "8761:8761"
config:
image: config
ports:
- "8888:8888"
links:
- eureka:eureka
depends_on:
- "eureka"
The problem is that all docker containers will start together, but according to your architecture, you need to start the config service first and then the discovery service (eureka). So service-discovery gives an error.
depends_on
don't wait for the config-service to be "ready" before starting the discovery service - it just waits until it starts . If you need to wait for the service to be ready, you must use a control start order .
As suggested, you can set the API / services to retry at multiple intervals until the config server is out .
Although, I would also prefer to use depend_on or healthcheck and control the startup order as shown below:
version: "2"
services:
web:
build: .
ports:
- "80:8000"
depends_on:
- "db"
command: ["./wait-for-it.sh", "db:5432", "--", "python", "app.py"]
db:
image: postgres
wait-for-it.sh is a pure bash script that will wait for availability. I also suggest looking into container orchestration tools like docker-swarm or kubernetes .