Docker微服务架构中Keycloak连接拒绝问题的解决
问题:Docker部署下Auth服务连接Keycloak报连接拒绝错误
基于Eureka的微服务架构,在auth-service中通过Keycloak Admin Client实现OAuth2相关配置(创建Realm和Client),所有服务通过Docker Compose部署。宿主机浏览器可正常访问localhost:8085的Keycloak控制台,但auth-service启动时抛出连接拒绝异常:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'keycloak' defined in class path resource [backend/authservice/config/KeycloakConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.keycloak.admin.client.Keycloak]: Factory method 'keycloak' threw exception; nested exception is javax.ws.rs.ProcessingException: RESTEASY004655: Unable to invoke request: org.apache.http.conn.HttpHostConnectException: Connect to localhost:8085 [localhost/127.0.0.1] failed: Connection refused
相关代码配置
1. Keycloak配置类
@Configuration public class KeycloakConfig { @Bean public Keycloak keycloak() { ResteasyClientBuilder resteasyClientBuilder = new ResteasyClientBuilderImpl(); Keycloak keycloak = KeycloakBuilder.builder() .serverUrl("http://localhost:8085") .grantType(OAuth2Constants.PASSWORD) .realm("master") .clientId("admin-cli") .username("admin") .password("keycloak") .resteasyClient(resteasyClientBuilder.connectionPoolSize(10).build()) .build(); RealmRepresentation realm = new RealmRepresentation(); realm.setId("new-relam"); realm.setRealm("new-relam"); realm.setEnabled(true); keycloak.realms().create(realm); ClientRepresentation clientRepresentation = new ClientRepresentation(); clientRepresentation.setClientId("my-backend"); clientRepresentation.setRedirectUris(List.of("http://localhost:8081/*")); clientRepresentation.setWebOrigins(List.of("http://localhost:8081")); keycloak.realm("new-relam").clients().create(clientRepresentation); return keycloak; } }
2. Docker Compose配置
services: eureka-server: image: 'eureka-server:1.0' container_name: eureka ports: - "8761:8761" auth-server: image: 'auth-service:1.0' container_name: auth-server ports: - "8081:8081" restart: on-failure environment: - SPRING_PROFILES_ACTIVE=prod - EUREKA_CLIENT_SERVICEURL_DEFAULTZONE=http://eureka-server:8761/eureka - SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/mydb - SPRING_DATASOURCE_USERNAME=usr - SPRING_DATASOURCE_PASSWORD=password - IP_ADDRESS=192.168.115.254 - TZ=Europe/Kiev depends_on: - eureka-server - db - keycloak-service db: image: 'postgres:latest' restart: always container_name: db environment: - POSTGRES_HOST_AUTH_METHOD=trust - POSTGRES_USER=usr - POSTGRES_PASSWORD=password - POSTGRES_DB=mydb keycloak-service: image: 'keycloak/keycloak:latest' container_name: keycloak-service ports: - "8085:8080" restart: always environment: - KEYCLOAK_ADMIN=admin - KEYCLOAK_ADMIN_PASSWORD=keycloak command: - start-dev
3. 核心依赖(pom.xml片段)
<!-- Keycloak --> <dependency> <groupId>org.keycloak</groupId> <artifactId>keycloak-admin-client</artifactId> <version>21.1.2</version> </dependency>
解决方案
将KeycloakConfig中的serverUrl从"http://localhost:8085"替换为"http://keycloak-service:8080":
Keycloak keycloak = KeycloakBuilder.builder() .serverUrl("http://keycloak-service:8080") // 修改此处 .grantType(OAuth2Constants.PASSWORD) // 其他配置保持不变 .build();
原因说明
- Docker容器内部的
localhost指向容器自身,而非宿主机,因此auth-service容器内访问localhost:8085会连接失败 - Docker Compose会自动为所有服务创建内部网络,服务名(
keycloak-service)可直接作为域名访问对应容器 - Keycloak容器内部的服务端口是
8080,8085是宿主机的映射端口,容器间通信需使用容器内部端口
内容的提问来源于stack exchange,提问作者Sonnka
相关产品推荐
相关产品推荐

