식구하자 프로젝트에서 ec2를 활용하여 배포 역할까지 맡아, 배포를 하던 과정에서 생겼던 오류에 대해 포스팅 하려 한다.
로컬 서버에서는 리액트와 스프링을 프록시 설정을 해두고, 연동하는 과정에서 문제가 없었다. 하지만 리액트 정적 파일을 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
콘솔에 이러한 에러를 찾게 되었다.
프론트에서 http://localhost:8080/api/duplicate로 요청하도록 하여 배포하면 이런 문제가 생긴것이다. /api/duplicate로 호출해야한다.
문제 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)가 발생
[상황 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 │──(응답)────┘