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

