0

I have a full stack application that I'm trying to setup with docker compose. Each application is running fine in their containers but I cannot make any requests to my backend API from the front end application. I used netshoot/curl/ping/nmap to verify that requests from the frontend container to backend container (http://backend:8080) are connecting. They are connecting, but when I make the request from my frontend application, which is running in a nginx server, the requests do not go through. I used tcpdump in the backend container (port 8080) to see if the request were coming through and there was no traffic when requests made from react app. I used tcpdump in the frontend container (port 80) to see if the request were being sent and there was no traffic when requests made from react app.

I've tried two different request configurations for my frontend request:

  1. Request made to http://backend:8080 - with no proxy pass in nginx
  2. Request made to http://localhost/api - with proxy pass shown in nginx config below

I'm pretty sure it is not a cors issue, but I configured cors in Spring to allow from frontend.

Docker, Nginx, and Spring Security config files below.

Spring Security Config:

@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 File

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 Config

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;
     }

Frontend 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

Backend 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"]
3
  • Your frontend application is running in the end user's browser; it's not actually in a container or necessarily even on the same machine. Does the setup in "Unknown host" error calling containerized backend from frontend help you? What URL are you trying to connect to from the React app, and what is the actual error message you're getting? Commented Nov 18, 2024 at 19:15
  • When your Nginx location is /api/ with a trailing slash, I think you need the slash in http://localhost/api/ as well. You've shown the URL without the trailing slash. Commented Nov 18, 2024 at 20:31
  • @HansKilian With the configuration OP showed, a 301 redirect to /api/ will be returned by nginx in response to /api request. Commented Dec 6, 2024 at 2:05

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.