Docker Compose网络配置问题:两个React应用页面无法正常互访
我正在学习Docker Compose网络配置,现有两个React应用,分别在路径/one和/two展示页面。此前单独使用docker-compose运行时均正常,配置如下:
ports: - 3001:3000
现在需要将二者部署在同一Docker网络中,于是创建了名为common-network的外部网络并在各自的docker-compose文件中引用。为避免主机端口3001冲突,第二个应用仅保留EXPOSE 3000配置(移除了端口映射)。
执行docker-compose up -d --build启动两个应用后,通过docker exec -it <container> ping <service>确认容器间可正常ping通,但在浏览器中访问/one后,跳转至/two时显示空白页面。
请问我的配置方式是否有误?需要如何调整才能实现页面间的正常跳转?
现有docker-compose配置
第一个应用(page-one-dev)
version: '3.7' services: page-one-dev: container_name: page-one-dev build: context: . dockerfile: Dockerfile volumes: - '.:/app' - '/app/node_modules' ports: - 3001:3000 environment: - CHOKIDAR_USEPOLLING=true - DOCKER_CLIENT_TIMEOUT=120 - COMPOSE_HTTP_TIMEOUT=120 networks: default: external: name: common-network
第二个应用(page-two-dev)
version: '3.7' services: page-two-dev: container_name: page-two-dev build: context: . dockerfile: Dockerfile volumes: - '.:/app' - '/app/node_modules' # ports: # - 3001:3000 expose: - 3000 environment: - CHOKIDAR_USEPOLLING=true - DOCKER_CLIENT_TIMEOUT=120 - COMPOSE_HTTP_TIMEOUT=120 networks: default: external: name: common-network
核心问题
浏览器是在主机环境发起请求,而非Docker容器内部。第二个应用仅设置EXPOSE 3000但未映射主机端口,浏览器根本无法直接访问到它的服务——容器间能ping通只是Docker内部网络的连通性,和外部浏览器访问完全是两回事。另外,如果React应用里的跳转路径硬编码了localhost:3001/two这类内容,也会因端口冲突或服务不可达导致页面空白。
具体调整方案
方案一:给第二个应用映射独立主机端口
修改第二个应用的docker-compose配置,取消ports的注释,换成不冲突的端口,比如3002:3000:
ports: - 3002:3000
(EXPOSE只是文档性指令,不影响实际端口映射,留着或删除均可)
同时,要确保第一个应用中跳转到第二个应用的链接是http://localhost:3002/two——容器内部的服务名(比如page-two-dev)只有Docker网络内部能识别,浏览器无法解析。
方案二:用Nginx反向代理统一入口(更优雅)
如果不想暴露多个端口,可以添加一个Nginx容器作为反向代理,统一用主机的3001端口,通过路径区分两个应用:
- 访问
localhost:3001/one时,Nginx转发到page-one-dev容器的3000端口 - 访问
localhost:3001/two时,Nginx转发到page-two-dev容器的3000端口
这样浏览器只需访问一个端口,内部由Nginx做路由转发,还能避免跨端口跳转的问题。
内容的提问来源于stack exchange,提问作者chocalaca

