You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker环境中Spring Boot网关无法连接Keycloak配置URI问题

问题描述

在本地Docker中部署Spring Boot网关服务与Keycloak后,网关无法解析Keycloak的领域配置URI。浏览器可正常访问http://localhost:8080/realms/Events/.well-known/openid-configuration,但网关日志报错:

Caused by: org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://keycloak:8080/realms/Events/.well-known/openid-configuration": Connection refused

相关配置文件

docker-compose.yml

services:
  postgres:
    image: postgres:16
    container_name: postgres
    restart: unless-stopped
    environment:
      POSTGRES_USER: eventsadmin
      POSTGRES_PASSWORD: my_pass
      POSTGRES_DB: eventsdb
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - eventslistingapp_default

  eureka-server:
    image: eureka-server
    build: ./configuration/eureka-server
    container_name: eureka-server
    restart: always
    ports:
      - "8761:8761"
    networks:
      - eventslistingapp_default

  config-server:
    image: config-server
    build: ./configuration/config-server
    container_name: config-server
    restart: unless-stopped
    environment:
      - SPRING_PROFILES_ACTIVE=default
    ports:
      - "8888:8888"
    depends_on:
      - eureka-server
    networks:
      - eventslistingapp_default

  gateway:
    image: gateway
    build: ./configuration/gateway
    container_name: gateway
    restart: unless-stopped
    ports:
      - "80:80"
    depends_on:
      - eureka-server
      - config-server
    networks:
      - eventslistingapp_default

  keycloak:
    image: quay.io/keycloak/keycloak:latest
    container_name: keycloak
    environment:
      - KEYCLOAK_ADMIN=admin
      - KEYCLOAK_ADMIN_PASSWORD=admin
      - KC_DB=postgres
      - KC_DB_URL=jdbc:postgresql://postgres/eventsdb
      - KC_DB_USERNAME=keycloak_user
      - KC_DB_PASSWORD=keycloak_user
      - KC_DB_SCHEMA=keycloak
    ports:
      - "8080:8080"
    depends_on:
      - postgres
    command:
      - start-dev
    networks:
      - eventslistingapp_default

  portainer:
    image: portainer/portainer-ce:latest
    container_name: portainer
    restart: unless-stopped
    ports:
      - "9000:9000"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer_data:/data
    networks:
      - eventslistingapp_default

volumes:
  postgres_data:
  portainer_data:

networks:
  eventslistingapp_default:
    driver: bridge
    external: true

gateway/application.yml

spring:
  application:
    name: gateway
  main:
    allow-bean-definition-overriding: true
    web-application-type: reactive
  config:
    import: optional:configserver:http://config-server:8888
  security:
    oauth2:
      resourceserver:
        jwt:
          jwk-set-uri: http://keycloak:8080/realms/Events/protocol/openid-connect/certs
      client:
        provider:
          keycloak:
            issuer-uri: http://keycloak:8080/realms/Events
        registration:
          gateway:
            provider: keycloak
            client-id: gateway
            client-secret: SPQByrPTSpwEfDaZVYwIQym5BGm7GUpB
            scope: openid
            authorization-grant-type: authorization_code
eureka:
  client:
    serviceUrl:
      defaultZone: http://eureka-server:8761/eureka/

server:
  port: 80

网关Security配置类

@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        http.authorizeExchange(auth -> auth.anyExchange().authenticated())
                .oauth2Login(Customizer.withDefaults())
                .oauth2ResourceServer((oauth2) -> oauth2.jwt(Customizer.withDefaults()));
        http.csrf(ServerHttpSecurity.CsrfSpec::disable);
        return http.build();
    }
}

已完成Keycloak基础配置:创建"Events"领域,SSL-Required设为none,创建"gateway"客户端。使用MacBook Pro M3,尝试过host.docker.internal、localhost、127.0.0.1及Keycloak容器IP,均出现连接拒绝问题,需解决网关与Keycloak的连通性问题。


解决方案

1. 验证Docker网络连通性

  • 执行docker network inspect eventslistingapp_default,确认输出中同时包含gateway和keycloak容器的名称/ID,确保两者在同一网络内。
  • 若不在同一网络,需将两个容器加入目标网络:docker network connect eventslistingapp_default [容器名/ID]。

2. 修正Keycloak监听地址

Keycloak默认可能仅绑定localhost,导致容器内服务无法访问。修改docker-compose.yml中Keycloak的环境变量,强制监听所有网卡:

keycloak:
  environment:
    # 保留原有环境变量,新增以下配置
    - KC_BIND_ADDRESS=0.0.0.0
    - KC_HTTP_ENABLED=true

重启Keycloak容器,确保服务对外暴露可访问端口。

3. 调整网关的Keycloak地址配置

容器内部通信(优先方案)

保持网关配置中的服务名地址http://keycloak:8080/realms/Events,但需确保Keycloak已正确绑定0.0.0.0,且网络连通正常。

Mac环境特殊处理

若使用host.docker.internal,需修改网关配置:

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          jwk-set-uri: http://host.docker.internal:8080/realms/Events/protocol/openid-connect/certs
      client:
        provider:
          keycloak:
            issuer-uri: http://host.docker.internal:8080/realms/Events

4. 修复容器启动依赖问题

depends_on仅保证容器启动顺序,不保证服务就绪。网关启动时Keycloak可能未完全初始化:

  • 手动重启网关容器,确保Keycloak服务完全启动后再启动网关。
  • 可在网关容器中添加健康检查脚本(如wait-for-it),等待Keycloak的/.well-known/openid-configuration接口返回正常后再启动服务。

5. 检查Keycloak数据库权限

从配置看,Postgres初始化用户为eventsadmin,但Keycloak使用keycloak_user连接数据库,需确认该用户已创建并授权:

  • 进入Postgres容器:docker exec -it postgres psql -U eventsadmin
  • 执行以下SQL创建用户并授权:
CREATE USER keycloak_user WITH PASSWORD 'keycloak_user';
GRANT ALL PRIVILEGES ON DATABASE eventsdb TO keycloak_user;

确保Keycloak能正常连接数据库,否则服务无法完全启动。


内容的提问来源于stack exchange,提问作者markoss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 07:44:57