AWS EC2实例中React容器与SpringBoot容器内部URL通信配置
我在Ubuntu系统的AWS EC2实例上运行两个Docker容器:
- React/Vite客户端通过
docker build和docker run启动,端口映射为14173:4173 - SpringBoot/PostgreSQL通过Docker Compose部署,端口映射为
18080:8080
实例所属VPC的两个安全组(default和launch-wizard-1)均开放了8080、18080端口,同时存在允许全部流量的规则,当前仅使用HTTP协议。
目前可以通过公网URL在本地访问React客户端(14173端口),也能通过公网URL访问SpringBoot服务(18080端口,后续希望关闭公网访问)。
React客户端容器的.env文件中配置了VITE_SERVER_API_URL:
- 设置为内部URL(
http://spring-boot-app:8080)或localhost:18080时,客户端无法连接SpringBoot(无数据加载,SpringBoot日志无交互记录) - 设置为公网URL:18080时可正常通信
请问如何配置才能让React客户端通过内部URL访问SpringBoot服务?
核心问题是React代码在本地浏览器中执行,而非Docker容器内,浏览器无法解析Docker内部的spring-boot-app主机名,也无法直接访问EC2实例内部的8080端口。以下是可行的配置方案:
1. 将React客户端纳入Docker Compose网络
当前React客户端单独用docker run启动,不在Docker Compose默认网络中,导致无法和SpringBoot容器互通。将React加入Compose配置,让所有服务处于同一Docker网络:
修改后的Docker Compose配置:
services: react-app: image: setlist-frontend build: context: ./setlist-frontend dockerfile: Dockerfile ports: - 14173:4173 container_name: react-client networks: - app-network environment: - VITE_SERVER_API_URL=http://spring-boot-app:8080 # 直接使用Docker内部服务名 spring-boot-app: image: setlist-backend ports: - 18080:8080 # 后续关闭公网访问时,删除此端口映射 build: context: ./setlist-backend container_name: spring-boot-app depends_on: - setlistdb environment: - SPRING_DATASOURCE_URL=jdbc:postgresql://setlistdb:5432/postgres - SPRING_DATASOURCE_USERNAME=postgres - SPRING_DATASOURCE_PASSWORD=postgres - SPRING_JPA_HIBERNATE_DDL_AUTO=update networks: - app-network setlistdb: image: postgres:14.12-alpine ports: - 15432:5432 container_name: setlistdb environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres - POSTGRES_DB=postgres volumes: - setlistdata:/var/lib/postgresql/data - ./scripts/postgres:/docker-entrypoint-initdb.d/ networks: - app-network volumes: setlistdata: external: true networks: app-network: driver: bridge
2. 配置Nginx反向代理(生产环境推荐)
若希望React直接在浏览器访问,同时SpringBoot不暴露公网端口,可在EC2实例上配置Nginx反向代理,将React的API请求转发到SpringBoot内部端口:
Nginx配置示例(/etc/nginx/sites-available/react-app.conf):
server { listen 14173; server_name 你的EC2公网IP; # 处理React静态文件(若直接部署构建产物) location / { root /path/to/react/build; try_files $uri $uri/ /index.html; } # 转发API请求到SpringBoot内部端口 location /api { proxy_pass http://localhost:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }
修改React的.env文件:
VITE_SERVER_API_URL=/api
此方案下,浏览器发起的/api请求会被Nginx转发到SpringBoot内部8080端口,无需暴露SpringBoot公网端口。
3. 临时调试方案(不推荐生产使用)
仅用于临时调试时,可在EC2安全组开放8080端口,修改React的.env为EC2私有IP:
VITE_SERVER_API_URL=http://EC2私有IP:8080
该方案安全性较低,不适合生产环境。
内容的提问来源于stack exchange,提问作者Jim Walmsley

