Docker and Eureka with Spring Boot failing to register clients

spring boot microservices eureka
building microservices using spring boot and docker - part 1
eureka client: serviceurl: defaultzone
how to register microservices in eureka server
eureka client not registering
eureka client in docker container
spring boot microservices with docker-compose example
disable eureka discovery client

I have a very simple demo of using Spring Boot + Docker Compose + Eureka.

My server runs on port 8671 with the following application properties:

server:
  port: 8761
eureka:
  instance:
    prefer-ip-address: true
  client:
    registerWithEureka: false
    fetchRegistry: false
  server:
    waitTimeInMsWhenSyncEmpty: 0

My Eureka client runs on port 9000 with the following application properties:

server:
  port: 9000
spring:
  application:
    name: user-registration
eureka:
  client:
    registerWithEureka: true
    fetchRegistry: true
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true

When I start up my docker.compose file in the parent maven project, this is the contents of my docker-compose file:

eureka-server:
  image: rosenthal/eureka-server
ports:
   - "8761:8761"
user-registration:
  image: rosenthal/user-registration
  ports:
   - "9000:9000"
  links:
   - eureka-server

When I run my application by first starting the eureka server, following by the client via

mvn spring-boot:run 

The server successfully registers my client (I call it user-registration).

When I run my application through docker-compose, the client fails to register with the following output:

 DiscoveryClient_USER-REGISTRATION/0fd640cbc3ba:user-registration:9000: 
 registering service...
 user-registration_1  | 2017-06-21 04:36:05.120 ERROR 1 --- [nfoReplicator-0]        
 c.n.d.s.t.d.RedirectingEurekaHttpClient  : Request execution error
 user-registration_1  | 
 user-registration_1  | com.sun.jersey.api.client.ClientHandlerException: 
 java.net.ConnectException: Connection refused (Connection refused)

My first assumption was that running docker-compose ran into a race condition on waiting for the server to start, but my eureka client seems to have a heartbeat trying to call home to the server it's configured with. This means it's just not able to find the Eureka server I have registered (and is running, I can navigate to it on localhost:8671).

What am I missing here? Everything runs fine running locally with spring-boot starting up with it's own embedded tomcat containers. As soon as I start to do it with docker-compose, it doesn't want to work.

EDIT

I realized my problem, I believe. So docker doesn't run on localhost, it runs on the public IP it is assigned when I start up docker. Navigating to this ip + port shows my service running for Eureka Server. The client still doesn't register.

SO, I made changes to the application.yml file for my eureka client to:

serviceUrl:
  defaultZone: http://192.168.59.103:8761/eureka/

That IP is the one my docker daemon is running under. Now, it misses the first registration when I do docker-compose, but the second heartbeat picks up my client.

How can I ensure the client waits until the server is FULLY up? I used the proper docker "links" field in my docket compose file, but it didn't work as I hoped. Additionally, how can I see the defaultZone file to be my DOCKER_HOST IP?

Final result

The resulting docker-compose file that got everything working for me was:

eureka-server:
  image: thorrism/eureka-server
  ports:
   - "8761:8761"
user-registration:
  image: thorrism/user-registration
  ports:
   - "9000:9000"
  links:
   - eureka-server
  environment:
    EUREKA_CLIENT_SERVICEURL_DEFAULTZONE: http://eureka-server:8761/eureka

If useful for you, that's in some way how I configure it for my production environment (docker-compose file version 2):

version: '2'
services:
  eureka-server:
    image: rosenthal/eureka-server
    expose:
    - "8761"
  user-registration:
    image: rosenthal/user-registration
    container_name: user-registration
    ports:
    - "9000:8080"
    environment:
      server.port: 8080
      eureka.client.enabled: 'true'
      eureka.host: eureka-server
      eureka.instance.preferIpAddress: 'true'

From the docs that's what expose does:

Expose ports without publishing them to the host machine - they’ll only be accessible to linked services. Only the internal port can be specified.

As you've got everything in the same network, containers can see each other with no links between them.

SIDE NOTE

Keep in mind that with this configuration port 9000 will be publicly accessible at the host machine, and mapped to the 8080 port of the user-registration container.

Netflix built and then open-sourced their own service registry, Eureka. Spring Cloud will startup a Eureka instance with its Spring Boot auto-configuration. In this configuration, the Spring Cloud Eureka client knows to connect to the in your manifest.yml or, on Cloud Foundry Lattice, your Docker file. Teams. Q&A for Work. Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information.

Set an environment property to override the eureka.client.serviceUrl.defaultZone to match the service name in your docker compose file.

eureka-server:
  image: rosenthal/eureka-server
  ports:
   - "8761:8761"
user-registration:
  image: rosenthal/user-registration
  ports:
   - "9000:9000"
  environment:
   - EUREKA_CLIENT_SERVICEURL_DEFAULTZONE: http://eureka-server:8761/eureka

This will override the property from the packaged application.properties.

NOTE: As mentioned in the comments you don't need the links section in the compose file. I removed is as such. See https://docs.docker.com/compose/networking/ for info on that.

Build Microservices in Spring with Docker The school-service directory contains a Spring Boot project that acts as 8761 is the default port for Eureka server. eureka.client.register-with-eureka - Tells Spring not to register itself into This set Docker Compose to restart the application as soon as it fails. Spring Cloud and Spring Boot, Part 5: Deploying the Eureka Server and Spring Boot Application in Docker The title pretty much tells you all you need to know. Let's get started with part 5!

i had the same issue and i tried everything but it did not work. after 2 weeks of trial and error then i tried to remove all the dependency from the repository and then i made sure that i have the same netflix client, server and Zuul dependency in all of them.

and then i used the above solutions after which it worked for me.

also be aware that u need to start the Services with docker compose only then it will work or else if u start them independently then they will all start in their on containers and will not register with the service registry. hope this helps

When docker is running on the client, the client serves the docker bridge RELEASE</spring-boot-dependencies.version> All communications with this service will fail because of the wrong IP advertised by the container. in a docker container to register with Eureka(running on a remote server) using a  We have many Spring Boot applications & are starting to 'containerize' using Docker. Right now, we have Eureka running (Spring Boot) and client applications (all other Spring Boot applications), in their application.yml files have:

I'm using docker and spring cloud Netflix Eureka server Below are my details Inter micro-service communication between docker eureka clients is failing #​3401. Closed. havannavar SpringApplication; import org.springframework.boot​.autoconfigure. Sign up for free to join this conversation on GitHub. Dismiss Join GitHub today. GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.

Eureka Server is service discovery for your microservices, where all client applications can register by themselves and other microservices look  I have a spring boot MS as euureka client, register to eureka service and a zuul gateway and all works fine except one single point. As docker container the eureka client is registered with the original port. But for real there is a port mapping and this one should be used for register to eureka service.

Docker build -f Dockerfile -t eureka-client . (-f is Docker filename, -t is tagname)  when running as direct spring boot apps, it works fine and registers client using IP address to eureka server. But when i run client as docker container, it always uses docker container id to register in eureka server. I am using docker for mac version 1.13.1. and spring boot version 1.4.1.

Comments
  • great solved the problem i have been working for hours!
  • Do you have the port mapped to 8080 in the container for each microservice? I'm still trying to understand all the networking behind using containers, and knowing how to map the ports. The public facing port for the docker container is 9000 (host machine port), but internally the service is running under 8080 within the container, correct?
  • @rosenthal youre right. The port for spring boot aplication is 8080 by default and youre running it within a container
  • I like this but how does docker environment variable mapped to java
  • @SabareeshKkanan it is done by Spring Boot: docs.spring.io/spring-boot/docs/current/reference/html/… (taking environment variables)
  • As the docker-compose instruction creates a default network for the whole stuff, using links should not be required. They are deprecated too.
  • Good point, but that wasn't the question :). Will add a note to the answer for that. (I just used the configuration from the question and added the environment stuff).
  • Yeah, answer is fine, just a side note ;-)
  • Couple of feedback notes from your response: The syntax is a bit off in the environment as you stated. No '-' or quotation marks are required for the new default zone. Additionally, I tried this by removing the "links" property as you suggest (and note as legacy?) but it didn't work until I added the links tag back.