개인 프로젝트를 진행하면서 Next.js 를 gh-pages 로 배포를 했던 적이 있다.
당시 특정 주기로 데이터를 최신화 해주는 기능이 필요하여 Next.js에서 지원하는 getStaticProps에 revalidate 옵션을 넣어 3일에 한 번씩 데이터 패칭 및 업데이트를 시도하기 위한 코드를 짜고 배포를 하였었다.
어찌 된 영문인지 배포만하면 작동을 안 해서 결국 getStaticProps를 걷어내고 Github Actions에 cron으로 스케쥴링하여 지정한 간격마다 새로운 데이터로 배포하는 방식으로 해결을 했었는데 왜 해당 방법을 쓸 수밖에 없었는지에 대해 정리한다.
GitHub Pages 훑어보기
GitHub Pages란
GitHub Pages는 GitHub에서 제공하는 정적 웹사이트 호스팅 서비스로서, 사용자의 GitHub 리포지토리에 저장된 정적 파일을 호스팅하여 간단하게 웹사이트를 배포하고 공개할 수 있다.
GitHub Pages의 특징
- 정적 웹사이트 호스팅: GitHub Pages는 주로 정적 파일 (HTML, CSS, JavaScript 등)을 호스팅 합니다. 정적 파일은 클라이언트 측에서 실행되므로 서버 측의 동적 기능은 지원되지 않습니다.
- 무료: GitHub Pages는 GitHub 계정을 가진 사용자에게 무료로 제공되는 서비스입니다.
- 프로젝트 페이지와 사용자 페이지: GitHub Pages는 프로젝트 페이지와 사용자 페이지 두 가지 유형으로 웹사이트를 호스팅할 수 있습니다. 프로젝트 페이지는 특정 GitHub 리포지토리와 연결되어 해당 프로젝트와 관련된 웹사이트를 호스팅 하는 데 사용됩니다. 사용자 페이지는 사용자의 GitHub 계정과 연결되어 개인 또는 포트폴리오 웹사이트를 호스팅 하는 데 사용됩니다.
- 자동 배포: GitHub Pages는 Git 저장소에 푸시되는 변경 사항을 자동으로 감지하여 배포합니다. 이를 통해 웹사이트를 업데이트하는 프로세스가 간단해집니다.
- 사용자 정의 도메인: GitHub Pages는 기본적으로 username.github.io와 같은 도메인을 제공합니다. 그러나 사용자는 사용자 정의 도메인을 설정하여 웹사이트를 호스팅할 수도 있습니다.
Next.js와 정적 사이트 생성
Next.js 개요
Next.js는 React 기반의 프레임워크로, 서버 사이드 렌더링(SSR)과 정적 사이트 생성(SSG)을 지원한다. SSR은 각 요청마다 서버에서 페이지를 렌더링하여 클라이언트에 전달하는 방식으로 작동한다.
getStaticProps와 revalidate
getStaticProps는 Next.js에서 사용되는 함수로, 정적 페이지를 생성하기 전에 데이터를 미리 가져오는 역할을 한다. revalidate 옵션은 getStaticProps에서 사용되며, 정적 페이지를 재생성하는 주기를 설정할 수 있다.
정적 사이트 생성과 데이터 갱신
getStaticProps를 사용하여 데이터를 미리 가져와서 정적 페이지를 생성하면, 서버 사이드의 데이터 의존성이 없는 정적 파일이 생성된다. 이러한 정적 파일은 데이터가 갱신되어도 재생성되지 않는 한 내용이 변경되지 않는다.
GitHub Pages의 제약 사항
정적 호스팅 환경
GitHub Pages는 주로 정적 파일을 호스팅하는 환경이다. HTML, CSS, JavaScript 등의 정적 파일은 제공되지만, 서버 측의 동적 기능은 제한적이거나 지원되지 않는다. 이는 GitHub Pages가 주로 프론트엔드 리소스를 제공하기 위한 목적으로 사용된다는 의미이기도 하다.
서버 사이드 렌더링(SSR)의 부재
GitHub Pages는 클라이언트 측에서 정적 파일을 제공하는 호스팅 서비스이므로 서버 사이드 렌더링(SSR)을 지원하지 않는다. SSR은 요청 시에 서버에서 페이지를 렌더링하여 동적인 콘텐츠를 생성하는 방식으로 작동한다. 따라서 Next.js의 getStaticProps와 같은 서버 사이드 렌더링 기능은 GitHub Pages에서 사용할 수 없다.
getStaticProps와 revalidate 간단 요약
getStaticProps
getStaticProps는 Next.js에서 사용되는 함수로, 정적 페이지를 생성하기 전에 빌드단계에서 데이터를 미리 가져올 수 있도록 해준다. getStaticProps 함수 내에서 API 호출이나 데이터베이스 쿼리 등을 사용하여 필요한 데이터를 가져올 수 있으며, 이를 통해 페이지의 데이터 의존성을 설정할 수 있다.
revalidate 옵션
getStaticProps 함수 내에 revalidate 옵션을 사용하여 정적 페이지를 재생성하는 주기를 설정할 수 있다. revalidate 값은 초 단위로 지정하며(1분 : 60), 해당 시간 간격마다 Next.js는 페이지를 다시 렌더링하여 새로운 데이터를 가져온다. 이를 통해 캐시된 정적 페이지를 업데이트하고 새로운 데이터를 반영할 수 있다.(주기가 도래하지 않는 한 화면 새로고침마다 일어나는 불필요한데이터패칭을 줄일 수 있음)
getStaticProps의 revalidate 미작동 이유
GitHub Pages의 서버 사이드 렌더링 미지원
GitHub Pages는 주로 정적 파일을 호스팅 하는 환경이며 서버 측의 동적 기능을 제공하지 않는다. 따라서 Next.js의 getStaticProps와 같은 서버 사이드 렌더링 기능은 GitHub Pages에서 직접 작동하지 않으며, getStaticProps를 사용하더라도 빌드 시에 데이터를 가져와 정적 페이지를 생성하고 이를 GitHub Pages에 업로드할 뿐이다. (처음 1번만 작동한다는 뜻)
정적 파일 호스팅의 한계
GitHub Pages는 정적 파일을 호스팅 하기 위해 설계되었기 때문에 동적 데이터의 갱신 주기를 자동으로 관리하지 않는다. revalidate 옵션이 정적 페이지를 재생성하는 주기를 설정할 수는 있지만, GitHub Pages 환경에서는 이 주기에 따라 정적 페이지를 재생성하는 기능이 내장되어 있지 않기 때문에 revalidate를 사용하더라도 GitHub Pages에서는 새로운 데이터를 가져와 페이지를 업데이트하는 동적 기능이 작동하지 않는다.
대안 및 해결 방법
Vercel 등의 서버 사이드 렌더링(SSR) 호스팅 서비스이용 :*BEST
GitHub Pages가 서버 사이드 렌더링을 지원하지 않기 때문에 getStaticProps의 revalidate와 같은 동적 기능을 사용하려면 다른 서버 사이드 렌더링(SSR) 호스팅 서비스를 검토할 수 있다. 대표적으로 Vercel은 Next.js 애플리케이션을 호스팅하고 서버 사이드 렌더링을 지원하는 플랫폼이다. Vercel을 사용하면 getStaticProps의 revalidate 옵션이 작동하고, 동적 데이터의 갱신과 페이지의 업데이트가 자동으로 처리된다.
정적 파일 생성과 수동 배포 :*WORST
데이터 갱신이 필요한 경우마다 정적 파일을 수동으로 재생성하고 배포하는 방법으로 가장 최악의 방법이다. 개발자답게 수동을 배제하고 자동화를 추구하자.
Github Actions을 활용한 데이터 갱신작업 및 배포 스케쥴링(schedule) : *케바케
GitHub Actions에서 특정 작업을 주기적으로 실행하거나 예약할 수 있는 schedule 이벤트 기능을 제공한다. 이를 통해 일정한 주기로 작업을 자동화하거나 특정 시간에 작업을 실행할 수 있다. 이 점을 활용하여 원하는 주기로 데이터 갱신작업을 실시하고 Git 저장소에 push 만 해준다면 github pages가 push된 내용을 자동으로 인식하고 배포까지 이루지게 된다.
(자세한 내용은 다른 포스팅에서 따로 정리해 둘 예정이다.)
결론
GitHub Pages는 주로 정적 파일 호스팅에 사용되며, getStaticProps의 revalidate와 같은 동적 기능을 지원하지 않는다. 따라서 Next.js 애플리케이션을 GitHub Pages에 배포할 때는 배포할 프로젝트의 성격을 미리 고민하고 배포 방법을 선택하는 것이 좋다.
곧죽어도 Github pages에 배포하고 싶다면 Github Actions의 schedule 이벤트를 잘 활용해보는 방법도 있다.