Apollo Server WebSocket连接Docker Compose仅用expose无法连通问题咨询
故障成因
你遇到的问题核心是混淆了请求的实际发起方:
- 绝大多数React项目采用客户端渲染(CSR)模式,所有前端发起的请求(包括GraphQL订阅请求)都是用户本地浏览器发起的,并非运行React静态资源的容器发起。
- Docker的
expose配置仅开放端口给同一Docker网络下的其他容器访问,不会将端口暴露到宿主机所在的本地/公网,外部的浏览器根本无法访问到Apollo Server的对应端口,自然会出现连接失败的问题。 - 配置
ports端口映射后,Apollo Server的端口会绑定到宿主机端口,浏览器可以通过宿主机IP+端口访问到服务,因此运行正常。 - 你之前遇到的同Docker网络容器可正常通信的场景,均为请求从容器内部发起,和当前浏览器发起请求的场景完全不同。
解决方法
根据你的项目架构选择对应方案即可:
方案1:客户端渲染React(绝大多数场景适用)
保留Apollo Server的ports端口映射配置即可,也可以引入Nginx反向代理统一转发请求,避免跨域问题,无需单独暴露Apollo和React的端口,参考配置如下:
server { listen 80; # 前端静态资源路由 location / { proxy_pass http://visualization:3000; # 替换为你的React容器服务名和端口 } # GraphQL请求+订阅路由 location /graphql { proxy_pass http://apollo-server:4000; # 替换为你的Apollo Server容器服务名和端口 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; } }
采用该方案只需暴露Nginx的80端口到宿主机即可,前端所有请求统一走Nginx地址即可。
方案2:服务端渲染(SSR)React,且订阅请求在服务端发起
修改Apollo Client的连接地址,将原来的localhost:4000或宿主机地址,替换为Apollo Server在Docker Compose中定义的服务名,例如你的Apollo服务名为apollo的话,连接地址改为http://apollo:4000/graphql即可,此时请求从SSR服务容器内部发起,可直接走Docker内部网络通信,无需配置端口映射。
内容的提问来源于stack exchange,提问作者mehmet emin çukur
相关产品推荐
相关产品推荐

