Search code examples
spring-bootdockercontainersmicroservices

How to configure and run Eureka Server, Microservices (Eureka Client), Zuul inside separate docker containers?


I am a newbie in Spring Boot and Docker. Written the below microservices.

  1. User Registration Service: Create users in the MySql database and also interacts with "Search and Delete Service" using Rest Template and its Eureka Client. GitHub link
  2. User Search and Delete Service: Search and Delete from MySql database and its Eureka Client. GitHub Link
  3. Eureka Server: Used for service discovery. GitHub Link
  4. Zuul Server: Used as an API Gateway and its Eureka Client. GitHub Link

I have used "Spring Boot STS" to develop the services. Also used "Spotify" dependency to build the docker images.

I am able to run all the services from STS on localhost (windows) and everything is working fine. All the three services mentioned before are getting registered in Eureka server.

But everything stopped working when I choose to dockerize the services. I have created four docker images of the four services.

Problem: Ran the Eureka server and "User Registration Service" in two sperate containers but the service is not getting registered with Eureka. In fact none of the services is getting registered with Eureka.

What I did:

Try 1:

Ran the Eureka server and client using below commands:

docker run --rm -it --name eurekaserver-container -p 8761:8761 eurekaserver-alpine-linux

docker run --rm -it -d --name user-registration-container -p 8081:8081 user-registration

enter image description here

It seems Eureka Client (User Registration Service) is not able to find Eureka server. What I found, Eureka server is running within a container with different IP (172.0...) and Eureka client is not able to connect the server.

Try 2:

Ran the Eureka server and client using below commands. Tried to link the two containers (Eureka Server and Client):

docker run --rm -it --name eurekaserver-container -p 8761:8761 eurekaserver-alpine-linux

docker run --rm -it -d --name user-registration-container -p 8081:8081 --link eurekaserver-container:eureka-server user-registration

This also didn't work.

Try 2 Error

Try 3:

Ran the Eureka server and client using below commands. Tried to pass the host name to Eureka image, so that Client can find the Eureka server using host name. Also linked the two containers.

docker run --rm -it -d --name eurekaserver-container -h discovery-eurekaserver.com -p 8761:8761 eurekaserver-alpine-linux /bin/bash

docker run --rm -it -d --name user-registration-container -p 8081:8081 --link eurekaserver-container:eureka-server user-registration

Try 3 Error

This also didn't work.

Can anyone please help me to understand what am I doing wrong? Whatever I have tried, Eureka clients are not able to register with Eureka server when running in different containers.

My objective is to run the services (Eureka Server, Application Services etc.) in different containers and all the services will register with Eureka server, so that I can call APIs from Postman or SOAP UI.


Solution

  • I suggest, you have a separate Dockerfile for each Spring boot project.

    FROM maven:3.6.0-jdk-8
    MAINTAINER [email protected]
    COPY . /usr/src/project-name
    WORKDIR /usr/src/project-name
    CMD ["mvn","spring-boot:run"]
    

    And a docker-compose.yml for controlling services and networks and links between containers.

    For example:

    version: '3.5'
    services:
    
      discovery-server:
        build:
          context: ./discovery-server
        hostname: discovery-server
        environment:
          - SPRING_APPLICATION_NAME=discovery-server
          - SPRING_PROFILES_ACTIVE=dev
        command: ["mvn", "spring-boot:run"]
        expose:
          - "8761"
        volumes:
          - maven-home:/root/.m2
        networks:
          services-network-01:
            aliases:
              - discovery-server
    
      user-service:
        build:
          context: ./user-service
        hostname: user-service
        environment:
          - SPRING_APPLICATION_NAME=user-service
          - SPRING_PROFILES_ACTIVE=dev
        command: ["mvn", "spring-boot:run"]
        ports:
          - "8080:8080"
        volumes:
          - maven-home:/root/.m2
        networks:
          services-network-01:
            aliases:
              - user-service
        depends_on:
          - discovery-server
    
    volumes:
      maven-home:
    
    networks:
      services-network-01:
        name: services-network-01
        driver: bridge
    

    Docker Compose File Refrence

    And ultimately depends on the configuration for Eureka discovery server and Microservices.

    Eureka Discovery Server config in application.yml:

    server:
      port: 8761
    eureka:
      client:
        register-with-eureka: false
        fetch-registry: false
        region: region1
        serviceUrl:
          zone1: http://discovery-server:8761/eureka/
        availability-zones:
          region1: zone1
      instance:
        hostname: discovery-server
        metadata-map:
          zone: zone1
    

    Eureka client config in application.yml in Microservices:

    # Eureka client
    eureka:
      instance:
        prefer-ip-address: true
        metadata-map:
          zone: zone1
      client:
        prefer-same-zone-eureka: true
        register-with-eureka: true
        region: region1
        service-url:
          zone1: http://discovery-server:8761/eureka/
        availability-zones:
          region1: zone1
    

    Run docker compose:

    docker-compose up -d --build --force-recreate
    

    Docker Compose Commands Refrence