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