You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker Compose部署全栈应用:React前端无法请求后端API

全栈Docker Compose部署:前端无法向后端API发起请求

我使用Docker Compose部署了一套全栈应用,各服务容器均运行正常,但前端React应用无法向后端API发起请求。通过netshoot、curl、ping、nmap验证了前端容器到后端容器(http://backend:8080)的网络连通性,确认网络可达,但运行在Nginx服务器中的前端应用发起请求时,请求无法送达。后端容器的8080端口使用tcpdump未捕获到来自React应用的流量,前端容器的80端口使用tcpdump也未捕获到React应用发出的请求。

我尝试了两种前端请求配置:

  • 直接请求http://backend:8080,未配置Nginx代理转发
  • 请求http://localhost/api,搭配Nginx代理配置

我认为这并非CORS问题,但已在Spring中配置了允许前端跨域的规则。


Spring Security配置

@Slf4j
@Configuration
@EnableWebSecurity
public class SecurityConfig {
    private final JwtFilter jwtFilter;
    private final UserProfileService userProfileService;

    @Autowired
    public SecurityConfig(JwtFilter jwtFilter, UserProfileService userProfileService) {
        this.jwtFilter = jwtFilter;
        this.userProfileService = userProfileService;
    }

    //Using JWT for auth
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .cors(cors -> cors.configurationSource(corsConfigurationSource())).csrf(CsrfConfigurer::disable)
                .authorizeHttpRequests(req -> req.requestMatchers("/user/login","/user/register").permitAll()
                        .anyRequest().authenticated())
                .sessionManagement(s -> s.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }

    @Bean
    public AuthenticationManager authenticationManager() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userProfileService);
        authProvider.setPasswordEncoder(passwordEncoder());

        return new ProviderManager(authProvider);
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(List.of("http://localhost:5173", "http://192.168.128.54:80"));
        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
        configuration.setAllowedHeaders(List.of("*"));
        configuration.setAllowCredentials(true);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

Docker Compose文件

services:
  backend:
    build:
      context: ./shewstringBE
      dockerfile: Dockerfile
    container_name: backend
    ports:
      - "8081:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=prod
      - SHEW_DB_URL=***removed for security***
      - SHEW_DB_USER=***removed for security***
      - SHEW_DB_PW=***removed for security***
      - SHEW_JWT_SECRET_KEY=***removed for security***
    networks:
      app-network:
        ipv4_address: 192.168.128.4
    depends_on:
      - mysql

  frontend:
    build:
      context: ./shewstringFE
      dockerfile: Dockerfile
    container_name: frontend
    ports:
      - "81:80"
    environment:
      - SHEW_FE_TEST_PW=***removed for security***
    networks:
      app-network:
        ipv4_address: 192.168.128.54

  mysql:
    image: mysql:latest
    container_name: mysql
    environment:
      MYSQL_ROOT_PASSWORD: ***removed for security***
      MYSQL_DATABASE: ***removed for security***
    ports:
      - "3307:3306"
    volumes:
      - mysql_data:/var/lib/mysql
    networks:
      - app-network

networks:
  app-network:
    driver: bridge
    ipam:
      config:
        - subnet: 192.168.128.0/24

volumes:
  mysql_data:
    driver: local

Nginx配置

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html;

    index index.html index.htm index.nginx-debian.html;

    server_name _;

    location / {
           try_files $uri $uri/ =404;
    }
  
    location /api/ {
           proxy_pass http://backend:8080/;
           proxy_set_header Host $host;
           proxy_set_header X-Real-IP $remote_addr;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header X-Fowrarded-Proto $scheme;
     }

前端Dockerfile

FROM node:16-alpine as build

WORKDIR /app

COPY package.json package-lock.json ./
RUN npm install

COPY . ./
RUN npm run build

RUN ls /app

FROM ubuntu/nginx:latest
RUN apt update && apt install vim -y && apt install curl -y

COPY --from=build /app/dist /var/www/html

EXPOSE 80FROM node:16-alpine as build

WORKDIR /app

COPY package.json package-lock.json ./
RUN npm install

COPY . ./
RUN npm run build

RUN ls /app

FROM ubuntu/nginx:latest
RUN apt update && apt install vim -y && apt install curl -y

COPY --from=build /app/dist /var/www/html

EXPOSE 80

后端Dockerfile

FROM openjdk:21-jdk-slim

WORKDIR /app

COPY target/shewstringBE-0.0.1-SNAPSHOT.jar app.jar

EXPOSE 8080

CMD ["java", "-jar", "app.jar"]

内容的提问来源于stack exchange,提问作者TorenRob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 04:02:12