EC2 nginx 리액트 스프링 부트 배포 net::ERR_CONNECTION_REFUSED

미누·2023년 9월 17일

식구하자

목록 보기
5/5

식구하자 프로젝트에서 ec2를 활용하여 배포 역할까지 맡아, 배포를 하던 과정에서 생겼던 오류에 대해 포스팅 하려 한다.

👿 Problem


로컬 서버에서는 리액트와 스프링을 프록시 설정을 해두고, 연동하는 과정에서 문제가 없었다. 하지만 리액트 정적 파일을 NGINX로 호스팅하고 스프링 부트 빌드 파일을 EC2에 올려 연동하는 과정에서 :ERR_CONNECTION_REFUSED 에러가 생겼다.

먼저 nginx.conf 파일이다.

~nginx 설정 파일
~
"/etc/nginx/sites-available/PlantFrontend.conf" 19L, 677B                                                                                                                                 18,1          All
server {
listen 80;
        location /{
                root /etc/client/**/build;
                index index.html index.htm;
                try_files $uri $uri/ /index.html;
        }

       location  ^~ /api {
                proxy_pass http://localhost:8080;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
        }
}

location ^~ /api 블록:
이 블록은 /api 경로에 대한 설정을 정의함.

  • proxy_pass http://localhost:8080;: /api로 들어오는 요청은 http://localhost:8080으로 프록시 패스됩니다.

  • proxy_set_header: 프록시 헤더를 설정합니다.

  • X-Real-IP: 원격 주소를 설정합니다.

  • X-Forwarded-For: 프록시가 추가한 헤더를 설정합니다.

  • Host: 호스트 헤더를 설정합니다.
    이 설정은 클라이언트의 요청이 / 경로로 들어오면 해당 디렉토리의 파일을 찾고, 없으면 index.html로 리다이렉트합니다. 또한 /api로 들어오는 요청은 백엔드 서버(http://localhost:8080)로 프록시되어 처리됩니다.

이렇게 프록시 설정을 해뒀는데도, 왜 프론트에서 백엔드에 요청을 보내지 못하는 걸까?....? 고민을 계속하다 이유를 찾게 되었다.

xhr.js:251 GET http://localhost:8080/api/duplicate? net::ERR_CONNECTION_REFUSED

콘솔에 이러한 에러를 찾게 되었다.

👼 Solution


프론트에서 http://localhost:8080/api/duplicate로 요청하도록 하여 배포하면 이런 문제가 생긴것이다. /api/duplicate로 호출해야한다.

NGINX 프록시 설정 관련 자세한 설명

문제 A

│사용자│ ──(요청)──> │localhost:8080│──> { Error }

사용자 PC에는 8080 포트로 띄운 WAS가 없으므로 응답 불가
개발 서버를 보통 3000 포트로 실행 할텐데, 그럼 http://localhost:3000이 개발서버 접속 주소가 됨

그렇게 접속한 페이지에서 스키마(http://), 도메인(localhost:3000)을 생략하고 /api/duplicate로 요청하게 되면 하면, 접속한 페이지의 것으로 전송이 됩니다.
그러니까 http://localhost:3000 에다가 /api/duplicate에 대한 요청을 하게 된것이다.

예시

개발 서버: 3000 포트, http로 구동 중
WAS: 8080포트, http로 구동 중

[상황 1]

http://localhost:3000에서 접속하여 http://localhost:8080/api/duplicate로 요청 시

│사용자│ ──(요청)──> │WAS(localhost:8080)│

│사용자│ <──(응답)────┘

개발 시에는 문제 없겠지만* 그대로 배포 시 앞선 문제(문제 A)가 발생

  • 사실 문제가 있을 수 있긴 한데(SOP) 여기선 생략
    상황 1의 문제 해결을 위해서는 배포 시 http://localhost:8080 대신 https://도메인 과 같은 식으로 변경해서 빌드 해야 함

[상황 2]
http://localhost:3000에서 접속하여 /api/duplicate로 요청 시

│사용자│ ──(요청)──> │개발 서버(localhost:3000)│──> { Error }
개발 서버에는 /api/duplicate에 대한 요청을 처리하는 기능이 없음
개발 서버에 프록시 설정을 한 경우
프록시 설정을 해두면 개발 서버에서 WAS에게 다시 요청하는 식으로 처리를 맡겨버립니다.

http://localhost:3000에 접속하여 /api/duplicate로 요청 시

│사용자│ ──(요청)──> │개발 서버(:3000)│──(요청)──> │WAS(:8080)│

│사용자│ <──(응답)── │개발 서버(:3000)│<──(응답)────┘

하지만 리액트 빌드 결과는 html, css, js 파일이므로, 위와 같이 프록시 처리를 해 줄 서버가 없습니다.

그래서 nginx에서 아래와 같이 프록시 설정을 해두는 것이다.

location  ^~ /api {
  proxy_pass http://localhost:8080;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header Host $http_host;
}

│사용자│ ──(요청)──> │Nginx │──(요청)──> │WAS│

│사용자│ <──(응답)── │Nginx │──(응답)────┘

0개의 댓글