问题
I have a Eureka Server, Config Server and Spring-Boot Service. I have created a docker compose file like this:
version: '3'
services:
user-service:
container_name: user-service-container
image: user-service:latest
build:
context: ./user-service
dockerfile: DockerFile
hostname: user-service
ports:
- "8082:8082"
depends_on:
- postgresdb
- eureka-service
- config-server
environment:
management.context-path : /userservice
hostName : user-service
EUREKA_HOST: eureka-service
EUREKA_PORT: 8761
config-server:
container_name: config-server-container
image: config-server:latest
build:
context: ./config-server
dockerfile: DockerFile
hostname: config-server
ports:
- "8081:8081"
depends_on:
- eureka-service
environment:
management.context-path : /config
hostName : config-server
SPRING_PROFILES_ACTIVE : registration-first
EUREKA_HOST: eureka-service
EUREKA_PORT: 8761
eureka-service:
container_name: eureka-service-container
image: eureka-service:latest
build:
context: ./eureka-service
dockerfile: DockerFile
hostname: eureka-service
ports:
- "8761:8761"
postgresdb:
container_name: postgres-db-container
image: postgres:10.5
hostname: postgres
ports:
- "5432:5432"
With this configuration Config Server can register itself to Eureka Server, however configuration part of the User Service throws below exception:
2018-09-07T18:53:17.869040200Z 2018-09-07 18:53:17.868 INFO 6 --- [ main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at : http://localhost:8888
2018-09-07T18:53:18.331651100Z 2018-09-07 18:53:18.331 INFO 6 --- [ main] c.c.c.ConfigServicePropertySourceLocator : Connect Timeout Exception on Url - http://localhost:8888. Will be trying the next url if available
2018-09-07T18:53:18.332055700Z 2018-09-07 18:53:18.331 WARN 6 --- [ main] c.c.c.ConfigServicePropertySourceLocator : Could not locate PropertySource: I/O error on GET request for "http://localhost:8888/user-service/registered-config-server,dev": Connection refused (Connection refused); nested exception is java.net.ConnectException: Connection refused (Connection refused)
2018-09-07T18:53:18.334406300Z 2018-09-07 18:53:18.334 INFO 6 --- [ main] c.k.d.u.UserServiceApplication : The following profiles are active: registered-config-server,dev
2018-09-07T18:53:18.371334800Z 2018-09-07 18:53:18.370 INFO 6 --- [ main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@4d1c00d0: startup date [Fri Sep 07 18:53:18 UTC 2018]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@13969fbe
From this exception, I understand that User Service connects to Euroka Server but it tries to connect to Config Server via a wrong URL (i.e. http://localhost:8888 )
Euroka Server App Properties:
spring.application.name=eureka-server
server.port=8761
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
Config Server App Properties:
spring:
cloud:
config:
server:
git :
uri: https://bitbucket.org/blabla
username: blabla
password: ***
discovery:
enabled: true
service-id: config-server
server:
port: 8081
---
spring:
application:
name: config-server
profiles: registration-first
eureka:
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: http://${eureka.host:localhost}:${eureka.port:8761}/eureka/
instance:
appname: config-server
hostname: ${hostName}
statusPageUrlPath: ${management.context-path}/info
healthCheckUrlPath: ${management.context-path}/health
preferIpAddress: true
metadataMap:
instanceId: ${spring.application.name}:${server.port}
User Service Application Properties:
endpoints:
enabled: false
info:
enabled: true
health:
enabled: true
metrics:
enabled: true
refresh:
enabled: true
eureka:
client:
fetchRegistry: true
registerWithEureka: true
serviceUrl:
defaultZone: http://${eureka.host:localhost}:${eureka.port:8761}/eureka/
instance:
hostname: ${hostName}
statusPageUrlPath: ${management.context-path}/info
healthCheckUrlPath: ${management.context-path}/health
preferIpAddress: true
metadataMap:
instanceId: ${spring.application.name}:${server.port}
spring.jpa.database: POSTGRESQL
spring.datasource.platform: postgres
spring.jpa.show-sql: true
spring.jpa.hibernate.ddl-auto: update
spring.database.driverClassName: org.postgresql.Driver
spring.datasource.url: jdbc:postgresql://postgresdb:5432/postgres
spring.datasource.username: postgres
spring.datasource.password: postgres
User Service Bootstrap.yml:
spring:
profiles:
active: registered-config-server,dev
application:
name: user-service
server.port: 8082
---
spring:
profiles: known-config-server
cloud:
config:
uri: http://localhost:8080
---
spring:
profiles: registered-config-server
cloud:
config:
discovery:
enabled: true
serviceId: config-server
But when I run these applications on my local PC without docker they work properly.
Does anyone have any suggestions?
EDIT: UserService Docker File:
FROM java:8
EXPOSE 8082
ADD /target/user-service-0.0.1-SNAPSHOT.jar user-service.jar
CMD java -jar user-service.jar
config-server docker file
FROM java:8
EXPOSE 8081
ADD /target/config-server-0.0.1-SNAPSHOT.jar config-server.jar
CMD java -jar config-server.jar
eureka-server docker file
FROM java:8
EXPOSE 8761
ADD /target/eureka-service-0.0.1-SNAPSHOT.jar eureka-service.jar
CMD java -jar eureka-service.jar
回答1:
I am too facing the same issue when trying to fetch configurations from Spring Cloud Config Server running in a Docker container. My Spring Boot app tries to access it on http://localhost:8888 even though I have specified the docker container name in the app's application.proprties.
Below is my app's application.properties:
spring.application.name=stock-app
spring.profiles.active=default
spring.cloud.config.uri=http://configserver:8888
server.port=8301
As a workaround, I am passing config server URL as a parameter in my docker compose.
This is my docker-compose.yml:
version: '2'
services:
configserver:
image: himarg/config-server:0.0.1-SNAPSHOT
ports:
- "8888:8888"
environment:
ENCRYPT_KEY: "IMSYMMETRIC"
database:
image: himarg/stock-db:latest
ports:
- "3307:3306"
environment:
MYSQL_ROOT_PASSWORD: "Welcome1"
MYSQL_DATABASE: "inventory"
stockapp:
image: himarg/stock-app:0.0.1-SNAPSHOT
ports:
- "8301:8301"
environment:
PROFILE: "default"
CONFIGSERVER_URI: "http://configserver:8888"
CONFIGSERVER_PORT: "8888"
DATABASESERVER_PORT: "3306"
ENCRYPT_KEY: "IMSYMMETRIC"
Then I use this parameter in my shell script that I use to start my app.
Below are the Dockerfile and the script:
Dockerfile
FROM openjdk:8-jdk-alpine
RUN apk update && apk upgrade && apk add netcat-openbsd
RUN mkdir -p /usr/local/stock-app
ADD @project.build.finalName@.jar /usr/local/stock-app/
ADD run.sh run.sh
RUN chmod +x run.sh
CMD ./run.sh
run.sh
#!/bin/sh
echo "********************************************************"
echo "Waiting for the database server to start on port $DATABASESERVER_PORT"
echo "********************************************************"
while ! `nc -z database $DATABASESERVER_PORT`; do sleep 3; done
echo "******** Database Server has started "
echo "********************************************************"
echo "Waiting for the configuration server to start on port $CONFIGSERVER_PORT"
echo "********************************************************"
while ! `nc -z configserver $CONFIGSERVER_PORT`; do sleep 3; done
echo "******* Configuration Server has started"
echo "********************************************************"
echo "Starting stock-app "
echo "********************************************************"
java -Dspring.cloud.config.uri=$CONFIGSERVER_URI -jar /usr/local/stock-app/@project.build.finalName@.jar
After making this change, I am able to successfully run my app, though I am not sure if this kind of workaround suits your requirement.
回答2:
Change this
eureka:
client:
fetchRegistry: true
registerWithEureka: true
serviceUrl:
defaultZone: http://${eureka.host:localhost}:${eureka.port:8761}/eureka/
To this
eureka:
client:
fetchRegistry: true
registerWithEureka: true
serviceUrl:
defaultZone: http://${EUREKA_HOST:localhost}:${EUREKA_PORT:8761}/eureka/
You also have to create a bridge network so that your apps can talk to each other. Think of dockerizing your apps as running each of the services on different computers. That means using "localhost" won't really help you.
Like this one below (source: https://developer.okta.com/blog/2017/10/11/developers-guide-to-docker-part-3)
services:
app:
image: sample:1.0
container_name: sample_app
build: .
ports:
- 80:3000
environment:
- MONGO_URI=mongodb://sampledb/sample
depends_on:
- db
networks:
- samplenet
db:
image: mongo:3.0.15
container_name: sample_db
volumes:
- ./db:/data/db
networks:
samplenet:
aliases:
- "sampledb"
networks:
samplenet:
driver: bridge
回答3:
Try moving eureka.client properties to bootstrap.yml instead of application.properties for config server
来源:https://stackoverflow.com/questions/52228734/microservice-can-not-reach-to-config-server-on-docker-compose