-
[오답노트] Docker 환경에서 Vue + Vite Proxy 설정 (웹서버 프록시 설정)오답 노트 2024. 4. 29. 11:22
최근 프로젝트를 진행하며 백엔드 개발자인 저에게 조금의 시련이 찾아왔습니다.
Vite 기반의 Vue를 프론트 서버(Ubuntu + Apache2)에 띄우는 것이었죠.
그간엔 그냥 부트 임베디드 톰캣에 전부 다 띄우거나, 외부 프론트 개발을 따로하더라도 톰캣을 활용해썼는데
이번엔 SSL과 Proxy 설정 및 내부 프로젝트 환경 때문에 부득이하게 웹서버에서 프론트를 서빙해야 하는 이슈가 있었습니다.
실제 개발서버 배포 전 개인 PC에서 Docker 환경으로 Ubuntu 컨테이너를 하나 띄우고 그곳에 Apache와 Tomcat을 모두 설치하여
프론트 서빙은 Apache를 통해 하도록 구현하고, Backend API는 Tomcat으로 처리하도록 구현하였습니다.
허나 여기서 기존에 제 로컬에선 잘 되던 Vite의 Proxy설정이 적용이 되질 않았습니다.
계속 헛바퀴가 돌듯 Proxy설정을 찾지 못하고 target URL로의 변경을 진행하지 못하는 이슈가 있었습니다.
왜이럴까..왜이럴까..고민을 하다가 얼핏 이런 내용을 보았습니다.
'Docker 기반의 Container 환경에서 Vite의 Proxy 설정은 동작하지 않는다' 라는 것을요.
.env.production 파일을 만들어 FE를 서빙하려 했으나 결국 내부 API 호출은 불가하다는 것을 확인하고 좌절에 빠져있었습니다.
근데 다시 생각을 해보니 서빙은 Apache가 하는데 왜 설정을 vite.config.js에 해놓으려고 한걸까요?
이상하다 싶어서 찾아보니 역시 Apahce 웹서버 자체에 설정하는 Proxy가 있었습니다.
(유레카!!!!)
Ubuntu 환경에서 Apache(우분투에선 httpd가 아니라 apache2로 설치되며 내부 구조는 httpd의 그것과는 다릅니다)의 접속을 관리하는 000-default.conf파일을 열었습니다.
(apache2 내 sites-available 디렉토리 내부에 있습니다.)
기본 FE 포트인 9080을 설정해주고, DocumentRoot를 html이 아닌 dist까지로 설정해주었습니다.
<VirtualHost *:9080> # ...(중략)... #ServerName www.example.com ServerAdmin webmaster@localhost DocumentRoot /var/www/html/dist
주요한 부분은 그 다음입니다.
해당 부분 바로 아래쪽에 Proxy설정을 추가해줍니다.
참고로 프록시에는 포워드 프록시와 리버스 프록시가 있습니다.
간략하게 개념만 정리하자면 포워드 프록시는 클라이언트의 요청을 받아 인터넷 서버로 전달 및 그 응답을 클라이언트로 전달하는 중개 서버로 클라이언트의 신원이나 외부 인터넷의 접근 제어, 캐싱 기능 등을 제공합니다. 즉, 내부에서 외부로 나가는 통신을 제어한다고 생각하시면 됩니다.
리버스 프록시의 경우 클라이언트의 요청을 받아 적절한 서버로 부하분산 및 고가용성 그리고 보안성을 제공하는 기능으로 외부에서 내부로 접근할 경우의 제어를 위한 프록시라고 생각하시면 됩니다.
저희가 여기서 설정해야 하는 Proxy 설정은 리버스 프록시입니다. 왜냐하면 외부로부터의 Call을 처리하기 위해 FE에서 BE를 호출하는 구조로 되어있기 때문이죠.
ProxyRequests Off ProxyPreserveHost On <Proxy *> Order deny,allow Allow from all </Proxy> ProxyPass /portal http://localhost:8080/portal ProxyPassReverse /portal http://localhost:8080/portal
각각의 옵션 설명은 다음과 같습니다.
- ProxyRequests는 요청을 전달 받아 웹서버로 전달하는 역할인지 클라이언트로 전달하는 역할인지를 설정하는 옵션입니다. On일 경우 포워드 프록시, Off일 경우 리버스 프록시이며 기본 설정값은 Off입니다.
- ProxyPreserveHost는 클라이언트의 호스트헤더를 프록시 요청에서 유지하도록 설정합니다. 이 설정은 웹서버가 원래 요청을 받은 호스트 대신 실제 요청이 전달된 호스트를 인식할 수 있도록 해줍니다.
- <Proxy *> ~ </Proxy> 블록은 특정 프록시의 설정을 정의하는 역할을 합니다. * 는 와일드카드로 모든 요청을 대상으로 한다는 의미이며, 이 블록 내부에선 프록시 대상 서버의 주소나 포트, 프록시 전달 요청의 특정 조건 등을 설정할 수 있습니다. 위 내용은 모든 요청에 대해 프록시가 허용된다는 것을 말합니다.
- ProxyPass의 경우 리버스 프록시를 설정할 때 사용하며 클라이언트의 요청을 받아 특정서버로 전달하는 역할을 합니다. 이를 통해 아파치 웹서버는 클라이언트와 서버 간 중개 역할을 수행할 수 있습니다.
Path는 클라이언트가 요청한 URL의 경로를 지정하며 URL은 요청이 전달될 프록시의 URL을 지정합니다. 이를 톹해 특정 경로에 대한 요청을 다른 서버로 전달하고 로드밸런싱이나 캐싱, SSL 암호화 등의 다양한 프록시 관련 기능을 웹서버에 구현할 수 있습니다.
설정 방식은 다음과 같습니다.
ProxyPass [path] [url]
- ProxyPassReverse는 리버스 프록시 설정과 함께 사용되며 백엔드 서버 응답을 클라이언트에 반환하기 전에 수정하는데 사용됩니다. 일반적으로 클라이언트가 리버스 프록시 서버에 요청을 보내면 이 요청은 프록시로 설정된 특정 백엔드 서버로 전달되고, 그 백엔드 서버에서 처리를 완료한 후 응답을 반환하게 됩니다. 하지만 백엔드 서버는 클라이언트의 호스트 헤더를 알지 못하므로 Location Header나 컨텐츠 내부 링크 등에 대한 정보가 올바르지 않을 수 있습니다.
이러한 문제를 방지하기 위해 ProxyPassReverse가 사용됩니다. 이는 받은 응답의 헤더를 변경해 클라이언트에게 올바른 정보를 전달하기 위함입니다.
설정 방식은 다음과 같습니다.
ProxyPassReverse [path] [url]
그 다음으로 proxy 설정을 마무리해줍니다.
a2enmod proxy a2enmod proxy_http systemctl restart apache2
앞으로 추가적으로 사용되는 Database나 Redis, RabbitMQ 등등을 연동하고 Cluster 구성을 해야 합니다.
최근들어선 개발보단 서버 환경 설정이 주를 이루는 것 같네요..
프로젝트 init은 언제나 할 일이 많은 것 같습니다.
'오답 노트' 카테고리의 다른 글