Next.js 로 GitHub Pages 배포하기
간단한 프로토타이핑 공유를 위해, Next.js로 구현한 웹앱을 GitHub Pages에 배포하기로 했다.
nextJS 뭘로 배포할까? (Netlify, Vercel, Github page) 문서를 보면 GitHub Pages는 물론이고 Netlify, Vercel 을 사용해 배포하는 방법과, 플랫폼간의 장단점까지 비교해 놓았다. 세 플랫폼에 모두 관심이 있다면 해당 글을 읽기를 권한다.
이 글에서는 해당 글의 내용을 토대로 GitHub Pages에 배포하는 방법만 간략히 정리한다.
0. (2025. 2. 11.) 덧붙임
이 글에 작성된 방법을 사용하는 것보다 nextjs-github-pages 에 있는 방법을 사용하는 것이 훨씬 더 쉽고 간단하다.
1. 배포 방법
위 문서에서는 아래의 명령어를 package.json
에 등록해놓고 사용하라고 안내하고 있다.
"scripts": {
"deploy": "rm -rf node_modules/.cache && next build && next export && touch out/.nojekyll && git add out/ && git commit -m \"Deploy Next.js to gh-pages\" && git subtree push --prefix out origin gh-pages"
},
명령어를 하나하나 살펴보면 아래와 같다.
rm -rf node_modules/.cache
next build
next export
touch out/.nojekyll
git add out/
git commit -m "Deploy Next.js to gh-pages"
git subtree push --prefix out origin gh-pages
(각 명령어에 관한 설명은 원 문서에 잘 되어있으므로 여기서는 생략하겠다.)
대부분의 경우 위 명령어를 그대로 써도 문제가 없겠지만, 개인적으로는 이슈가 몇 개 있었다.
2. 이슈
2.1. 빌드 결과물을 git 스테이지에 추가
위에서는 git add out/
명령어를 통해 빌드한 결과물을 git의 스테이지에 추가 한다. 하지만 일반적인 Next.js 프로젝트에서 out/
디렉토리는 .gitignore
에 등록되어있기 때문에, 해당 명령어로는 스테이지에 추가되지 않는다.
해결 방법은 해당 디렉토리를 .gitignore
에서 제외시키거나 -f
옵션을 주어서 .gitignore
와 관계 없이 강제로 추가시키는 것이다.
여기서는 -f
옵션을 사용한다. 왜냐면 빌드할 때만 out/
디렉토리를 스테이지에 포함시키고, 빌드 후에는 삭제할 생각이기 때문이다.
2.2. 커밋 및 푸시
위 문서에서는 아래 명령어를 사용해 빌드 결과를 커밋하고 푸시한다.
git commit -m "Deploy Next.js to gh-pages"
git subtree push --prefix out origin gh-pages
이 경우 out/
디렉토리의 내용물을 main
(혹은 master
) 브랜치에 계속 유지해야 한다. out/
디렉토리 내용을 git 에서 계속 유지할 것이라면 문제 없다. 하지만 내 경우 out/
디렉토리의 내용을 main
브랜치에 유지하고 싶지 않았다. (유지하지 않는 편이 히스토리 관리에 더 좋다고 생각했다.) 내가 원하는 프로세스는 아래와 같다.
- git 스테이지에 임시로
out/
디렉토리를 추가하고 커밋한다. - 해당 커밋을 가지고
gh-pages
브랜치에 배포를 진행한다. (배포하면gh-pages
브랜치에 커밋이 새로 생성될 것이다.) - 배포가 끝난 후 1번에서 추가했던 커밋을 삭제한다.
그럼 원하는 방향이 적용되게끔 명령어를 변경해보자.
# temp-for-deploy-gh-pages 브랜치를 생성한다.
git checkout -b temp-for-deploy-gh-pages
# 생성한 브랜치에 `out/` 디렉토리가 포함된 내용을 커밋한다.
git commit -m "Deploy Next.js to gh-pages"
# 해당 커밋을 사용해 `out/` 디렉토리만으로 로컬의 gh-pages 브랜치에 새로운 커밋을 만든다.
git subtree split --prefix out -b gh-pages
# 로컬의 gh-pages를 강제로 gh-pages 에 푸시한다.
git push -f origin gh-pages:gh-pages
# 로컬의 gh-pages 브랜치를 삭제한다.
git branch -D gh-pages
# temp-for-deploy-gh-pages 브랜치를 삭제한다.
git checkout main
git branch -D temp-for-deploy-gh-pages
gh-pages
를 강제로 푸시하는 이유는 이미 원격에 gh-pages
브랜치가 있을 경우, 새로운 커밋이 원격에 있는 기존의 커밋과 이어지지 않는 커밋이기 때문이다. (gh-pages
에 추가되는 커밋의 부모 커밋이 main
브랜치 쪽에 유지되면, 이어지는 커밋으로 판단된다.)
3. 이슈 해결 결과
rm -rf node_modules/.cache
next build
next export
touch out/.nojekyll
git add -f out/
git checkout -b temp-for-deploy-gh-pages
git commit -m "Deploy Next.js to gh-pages"
git subtree split --prefix out -b gh-pages
git push -f origin gh-pages:gh-pages
git branch -D gh-pages
git checkout main
git branch -D temp-for-deploy-gh-pages
위 명령어들을 연달아 쓰면 Next.js 앱을 GitHub Pages에 배포할 수 있다. 매번 치기 귀찮을 것이므로 package.json
에 등록해두고 사용하자.
"scripts": {
"deploy-gh-pages": "rm -rf node_modules/.cache && next build && next export && touch out/.nojekyll && git add -f out/ && git checkout -b temp-for-deploy-gh-pages && git commit -m \"Deploy Next.js to gh-pages\" && git subtree split --prefix out -b gh-pages && git push -f origin gh-pages:gh-pages && git branch -D gh-pages && git checkout main && git branch -D temp-for-deploy-gh-pages"
},
4. 주의
- 위 내용은 어디까지나 "프로토타이핑 공유를 위한 GitHub Pages 배포"를 목적으로 하고 있다. 다른 목적으로 사용할 경우 적절하지 않을 수 있다.
- 환경변수와 관련된 내용은 이 문서에서 정리하지 않았다. 해당 내용은 원 문서에 잘 설명되어 있다.