Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Cloud Config Server not working with Docker compose

I have a spring cloud config server and packaged it as a docker image then I have spring cloud eureka server which is also packaged as docker image.

When I run the two using docker compose 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)

Although the config service is up and running successfully, discover service still does not find it for some reason.

Docker compose file being used here is this 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 is the 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 the 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 assuming something is wrong with my docker-compose.yml but I am not sure.

Any help will I am stick in this for hours ... heading close to days :(

like image 543
Shahbaz Avatar asked Jun 24 '17 16:06

Shahbaz


People also ask

How does Spring cloud Config server work?

Spring Cloud Config Server provides an HTTP resource-based API for external configuration (name-value pairs or equivalent YAML content). The server is embeddable in a Spring Boot application, by using the @EnableConfigServer annotation. Consequently, the following application is a config server: ConfigServer.

How do I use RefreshScope in spring boot?

Now, you need to add the @RefreshScope annotation to your main Spring Boot application. The @RefreshScope annotation is used to load the configuration properties value from the Config server. Now, add the config server URL in your application. properties file and provide your application name.

Can we configure spring cloud with spring boot?

Creating Spring Cloud Configuration Server Gradle users can add the below dependency in your build. gradle file. Now, add the @EnableConfigServer annotation in your main Spring Boot application class file. The @EnableConfigServer annotation makes your Spring Boot application act as a Configuration Server.

What is spring cloud config server in Microservices?

Spring Cloud Config is Spring's client/server approach for storing and serving distributed configurations across multiple applications and environments. This configuration store is ideally versioned under Git version control and can be modified at application runtime.


3 Answers

I solved it by adding this configuration to the discovery service's bootstrap.yml.

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 the discovery service's maven dependencies.

<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're both starting at the same time. But the discovery service depends on the config service.

When you start the discovery service, it's going to say "Fetching config from server" again and again until config service is up.

After the config service starts, discovery service is going to get its configuration successfully and then it's going to start itself.

like image 89
Enes Korukcu Avatar answered Sep 27 '22 20:09

Enes Korukcu


The problem is all the docker container will start together, but as per your architecture, the config-service needs to start first, then the discovery-service(eureka). So discovery-service is giving the error.

depends_on does not wait for config-service to be “ready” before starting discovery-service - it only waits until it is started. If you need to wait for a service to be ready, you have to use controlling startup order.

As suggested about you can set the APIs/Services to keep retrying in some intervals until the config server is up.

Although, I would also prefer to use depends_on or healthcheck and controlling 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 on the availability. I would also suggest looking into, container orchestration tools like docker-swarm or kubernetes.

like image 33
madhu pathy Avatar answered Sep 28 '22 20:09

madhu pathy


I've faced the same issue and was stuck for a bit and I was about to go the same route as you did with the spring retry, which isn't a bad pattern to follow it does embed resiliency into your application but the main issue here is docker's launch order is out of place. I'll share my working docker-compose file, it's quite similar but the key here is the "depends_on" parameter. I've added quotes on my arguments and it seemed to work.

version: "2"
services:
  eureka:
    image: eurekatest
    ports:
    - "8761:8761"

  config: 
    image: config
    ports:
    - "8888:8888"
    links:
    - eureka:eureka
    depends_on:
    - "eureka"
like image 21
Twesh Chowdhury Avatar answered Sep 28 '22 20:09

Twesh Chowdhury