Docker中OpenResty对接Keycloak的OIDC发现地址解析问题求助
你遇到的核心矛盾是Docker容器内置DNS的解析逻辑,和你手动修改/etc/hosts的操作不兼容——因为你已经把Nginx的resolver设为Docker内置的127.0.0.11,它只会优先使用Docker Compose的内部DNS服务,完全忽略你手动添加的/etc/hosts条目。下面给你几个靠谱的解决方案,按推荐优先级排序:
1. 直接使用Docker Compose服务名访问Keycloak(最推荐)
既然两个服务在同一个Docker Compose栈里,Docker会自动为每个服务注册内部DNS记录,你可以直接用Keycloak的服务名keycloak-container作为主机名,完全不用依赖外部服务器域名。
修改你的Docker Compose环境变量:
version: '3.5' services: my_nginx: environment: OIDC_DISCOVERY: 'http://keycloak-container:8081/auth/realms/example/.well-known/openid-configuration' ... keycloak-container: ...
这样Nginx通过127.0.0.11就能直接解析到Keycloak容器的IP,无需任何额外配置,这也是Docker跨服务通信的标准方式,稳定性最高。
2. 通过Nginx反向代理转发OIDC请求(如果必须保留外部域名)
如果业务上一定要用外部服务器域名(比如前端也需要访问这个地址),可以在Nginx配置里加一个反向代理规则,把对该域名的OIDC发现请求转发到内部的Keycloak服务:
在你的Nginx配置文件中添加:
location ~* /auth/realms/example/.well-known/openid-configuration { # 保留Docker内置DNS解析,同时设置缓存有效期 resolver 127.0.0.11 valid=30s; # 转发请求到Keycloak服务的内部地址 proxy_pass http://keycloak-container:8081$request_uri; # 可选:添加必要的代理头,避免Keycloak报错 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }
然后把OIDC_DISCOVERY的值改成Nginx对外暴露的地址,比如http://[my-test-server-url]/auth/realms/example/.well-known/openid-configuration,这样Nginx收到请求后会自动转发到内部的Keycloak实例。
3. 让Nginx优先读取/etc/hosts(不推荐)
如果你坚持要使用手动修改的/etc/hosts条目,可以调整Nginx的resolver配置,让它优先读取本地hosts文件:
resolver 127.0.0.11 hosts;
不过这个方法不推荐,因为Docker容器重启后/etc/hosts会被重置,而且Keycloak容器的IP可能随重启变化,维护成本很高。
内容的提问来源于stack exchange,提问作者enrm

