Image 1

웹 서버는 여러 의미가 있을 수 있지만 이번 글에서 사용하는 웹 서버라는 용어는 Web Application Server (WAS) 와 대조되는 의미로 NginxApache HTTP Server 등의 프로그램을 의미합니다. 편의상 WAS와 비교하기 위해 영어로 Web Server라고 표기하겠습니다.

점유율 1위는 오랫동안 Apache HTTP Server가 차지하고 있지만 훨씬 좋은 성능적 이점을 가진 Nginx가 빠르게 따라잡고 있습니다. 저 또한 Nginx를 더 선호하는 편입니다. Web Server는 보통 웹 서비스의 앞단에 위치되고, 정적 파일 서비스, Reverse Proxy, Load Balancer 등의 기능을 가지고 있습니다. 이 중에서도 정적 파일 서비스는 프론트엔드 배포에 많이 사용됩니다.

저는 한때 백엔드 개발로 취업을 준비했으나 당시 수요가 더 높았던 프론트엔드로 일을 시작했기에 프론트 개발이 주 업무임에도 아키텍처적인 시각을 항상 가지고 있습니다. 그렇기에 평소에도 프론트엔드 작업물이 어떻게 배포되어야 하는지에 대해서 여러 구상을 해봅니다. 반면에 제 주위의 다른 프론트엔드 개발자들은 이러한 구상은 백엔드 (또는 데브옵스) 개발자들만의 책임으로 생각하는듯 합니다. 이에 대한 저의 생각을 한번 정리해볼까 합니다.

프론트엔드와 백엔드의 분리

현재 웹 개발 분야는 프론트엔드와 백엔드 개발로 나뉘는 추세가 확실하게 자리를 잡았다고 봐도 무방합니다. 그러나 사실 이 둘이 완벽하게 분리될 수는 없습니다. 프론트엔드 개발의 결과물을 어떻게 배포하느냐의 질문에서 결국은 서버에서 지속적인 서비스가 되어야 한다는 결론에 이르기 때문입니다. 이는 모바일 앱과 같이 사용자의 기기에서 다운받아 사용하는 클라이언트 소프트웨어와는 사정이 다르죠.

또한 프론트엔드에서 서버사이드 로직이 완전히 빠졌을 때 발생하는 단점 또한 무시할 수 없습니다. 렌더링 속도와 검색엔진 최적화에 있어서 치명적인 단점을 가지게 되죠. 이에 서버사이드 렌더링 (SSR) 및 정적페이지 생성기 (SSG) 가 많은 각광을 받고 있습니다. 서버사이드 렌더링은 오늘의 주제랑은 좀 달라서 나중에 관련 내용을 다뤄보도록 하겠습니다.

프론트엔드 배포

프론트엔드 개발의 결과물은 서버사이드 렌더링을 하는게 아니라면 html, css, js 로 정적인 파일이 됩니다. 요즘 많이 사용하는 React JS로 예를 들어봅시다. build 명령어를 실행하면 build 폴더가 생성되고 그 안에 index.html과 여러 css, js 파일로 빌드됩니다. 이렇게 빌드된 결과물은 사용자 요청에 따라 내어줄 수 있는 형태로 배포되어야 합니다.

Template Engine

MVC 모델이 익숙하다면 View에 해당되는 Template Engine을 통해 프론트엔드를 서비스하는 방식을 생각할 수 있습니다. 이 경우 프론트엔드는 백엔드의 한 부분으로 들어가게 됩니다.

Web Server

또 다른 방법으로는 Web Server와 WAS의 역할을 분리하는 겁니다. Web Server는 요청이 들어왔을 때 정적파일을 내어주거나 다른 서버로 Reverse Proxy를 하는 등 안내데스크와 같은 역할만 합니다. 흔히 알고있는 백엔드의 경우 WAS에 해당되며, 요청에 따라 실행되어야할 서버사이드 로직이 실행됩니다. Web Server를 가장 앞단에 두어 프론트엔드는 정적으로 서비스하고 백엔드는 Reverse Proxy로 서비스하는 형태가 되는겁니다.

React JS로 프론트엔드 개발을 하고 Nginx로 배포하는 상황을 가정해보면 아래와 같이 Nginx 설정파일을 작성할 수 있습니다.

location / {
  root        [정적 파일 루트 경로];
  index	      index.html index.htm;
  try_files   $uri $uri/ /index.html;
}

React JS 빌드 결과물에 대한 Nginx 설정 예시

try_files 속성에서 정의된 패턴을 통해 정적 파일을 서비스하게 됩니다. 이러한 패턴은 사용하는 프레임워크 또는 개발 방식에 따라 달라질 수 있습니다. React JS의 경우 SPA 구조답게 html이 루트 디렉토리의 index.html 하나밖에 없습니다. 따라서 어떤 경로로 들어가든 루트 경로의 index.html을 내어주도록 되어야 합니다.

아래는 좀 다른 예시로 Next.js를 정적으로 배포하는 경우에 적합한 설정 예시입니다.

location / {
  root        [정적 파일 루트 경로];
  index	      index.html index.htm;
  try_files   $uri $uri/index.html =404;
  error_page  404 /404/index.html;
}

Next.js 정적 빌드 결과물에 대한 Nginx 설정 예시

Next.jsReact JS와 다르게 각 경로마다 html이 존재한다는 차이가 있습니다. 이와 같이 프론트엔드의 파일 구조를 고려하여 설정파일을 작성하게 됩니다.

백엔드로 Reverse Proxy 하는 경우는 아래와 같이 작성할 수 있습니다.

location ^~ /api/ {
  proxy_pass  [백엔드 서버 URL];
}

/api/ 경로에 대해서 백엔드로 Reverse Proxy

배포 환경 구축 과정에서 프론트엔드 개발자의 역할

어떤 배포 방법을 사용하든 프론트엔드의 파일 구조를 고려해야 합니다. 프론트엔드 개발자가 직접 서버를 개발하지 않더라도 파일 구조에 대한 가이드를 줄 수 있으면 훨씬 원활해질 것입니다. 프론트엔드 개발자 모두가 그럴 필요는 없다 할지라도 이러한 역량까지 가추고 있다면 스스로의 가치를 더욱 높일 수 있지 않을까 싶습니다.

업데이트:

댓글남기기