지난 번 github-page 배포는 react 앱이이었고 이번에는 Next js 앱을 배포해봤다 with github action
이 과정을 간단히 서술한다. #다사다난
continuous integration 와 continuous delivery/deployment의 줄임말이다.
보통 분업하여 작업할 때 계속 끝까지 따로 작업하다가 마지막에 한 번에 합칠 수는 없다. 지속적으로 서로의 코드를 통합하고 테스트하는 과정이 필요 → CI
이렇게 합치면서 개발 단계에서만 끝나는 것이 아니라 지속적으로 이 개발된 것들을 실제로 production으로 만들어주는 과정 → CD
둘다 직접 할 수 있겠지만 굉장히 번거롭다. 불필요한 시간을 줄여서 개발 시간을 단축해야함. 그래서 많은 관련 툴을 많이 제공해주고 있음. 그중 하나가 github action
https://docs.github.com/en/actions/quickstart
양이 많은데 typescript 공부하듯이 하기엔 좀 불필요 한 것 같아서 기본적인 틀만 이해했다.
레포지토리 루트에 .github/workflows
에 .yml
을 정의하여 액션을 추가한다.
workflow는 트리거 이벤트를 기반으로 작동한다. 특정한 이벤트(push, merge 등)가 발생했을 때 지정해둔 job을 하며 workflow를 따라가도록 지정해주는 것
job은 말그대로 workflow에서의 작업들을 의미한다. push발생시 eslint를 돌린다, merge발생시 build를 한다.
다른 job에 의존성을 가질 수도 있다. 1번 job이 실행되어야 2번 job이 실행될 수 있는 것.
이런 job들은 은 실제로 runs-on
항목에 정의된 가상환경에서 실행한다.
아래는 workflow 파일(확장자 .yml)의 예시 코드
name: learn-github-actions
on: [push]
jobs:
check-bats-version: # 작업의 이름
runs-on: ubuntu-latest # 어느 가상환경에서 이를 작동시킬 것인지
steps: # 이 작업의 단계들을 차례로 정의. 단계는 - 으로 구분한다.
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '14'
- run: npm install -g bats
- run: bats -v
learn-github-actions
push
check-bats-version:
으로 여러 작업을 정의한다.[소유자]/[액션 이름]
의 형태로 작성https://github.com/vercel/next.js/tree/canary/examples/github-pages
를 참고해서 package.json의 값 아래처럼 수정
...
"build": "next build",
...
"deploy": "touch out/.nojekyll && git add out/ && git commit -m \"Deploy\" && git subtree push --prefix out origin gh-pages",
...
하지만 이렇게 하고 yarn run deploy를 실행하면 했는데 out/.nojekyll
을 찾을 수 없다는 에러와 함께 배포가 안된다..
당연하다 out폴더 자체를 만들지 않았음. next export를 실행하면 out/ 폴더가 생기고 그 아래에 배포될 파일들이 들어가게 그냥 빌드만 해서 /.next
안에 빌드된 파일들이 생기기만 한 것.. 이걸 빼먹니
그래서 next export도 추가해서 만들어줍니다. 아래가 최종적으로 완성된….이 아니라
이렇게만 쓰면 이미 gh-pages가 존재한다고 뜨기 때문에 강제로 업데이트를 해줘야해서
아예 새롭게 가상환경의 로컬에 브랜치를 만들어주고 origin으로 force push 한다.
"deploy": "next export && touch out/.nojekyll && git add -f out/ && git commit -m \"Deploy\" && git subtree split --prefix out -b gh-pages && git push -f origin gh-pages:gh-pages && git branch -D gh-pages",
이렇게 쓰면 배포는 성공하는데 next js가 구성해서 보내는 html로만 만들어진 페이지가 존재한다. css-in-js, js, image같은 파일들의 path가 제대로 설정되지 않아서 파일을 찾을 수가 없는 것이다.
next.config.js
의 assetPrefix
을 설정하여 asset들을 요청할 때 prefix로 붙일 path를 설정해준다.
또한 이미지 최적화를 위해서 next js에서 제공하는 <Image>
태그를 이용했는데 여기서도 문제 생김 → 해결을 반복한다.
https://{닉네임}.github.io/
이기 때문에 (레포지토리 이름을 포함하지 않음) assetPrefix
를 /레포지토리명
으로 지정해줘야한다. 하지만 한 번만 입력했음에도 중복으로 입력되는 것zmin9.githhub.io/premium-page/premium-page)
을 발견.‘’
으로 입력했더니 Image 컴포넌트의 원래 요청 prefix 주소 zmin9.githhub.io/premium-page
으로 설정되서 아예 images.path
를 아래와 같이 사이트 주소로 설정해주었다.그렇게 완성된 next.config.js
/**
* @type {import('next').NextConfig}
*/
const isProduction = process.env.NODE_ENV === 'production';
export default {
compiler: {
styledComponents: true
},
eslint: {
ignoreDuringBuilds: true,
},
images: {
loader: 'akamai',
path: isProduction ? 'https://zmin9.github.io' : 'http://localhost:3000',
},
assetPrefix: isProduction ? '/premium-page' : '',
};
완성된 workflow
on:
push:
branches:
- main
jobs:
build-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: yarn set version 3.2.2
- run: yarn install
- name: Build
run: yarn build
- run: yarn run export # scripts : { export: 'next export' }
- run: touch ./out/.nojekyll #위에서 말한 것처럼 이파일을 추가하지 않으면 _app 인식 못함
- name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@v4
with:
branch: gh-pages
folder: out
위를 보면 알 수 있지만 결국 만들어둔 yarn run deploy
는 쓰지 않았다... 왜냐면 github config 인증하는 과정도 따로 추가해줘야하고 이미 잘 만들어진 액션이 있으면 그걸 써서 불필요한 작업을 줄이는게 좋다고 생각했기 때문이다.
물론 이미 yarn run deploy
를 만들었기 때문에 시간을 절약했다고 볼 수는 없었지만 그 과정을 깨닫는 것도 + 한 번 정도는 경험해보는 것도 좋았다고 생각...^_^ 아무튼... 이제 main branch에 push가 일어나면 잘 배포된다.
은 훨씬 쉽다.
이유: vercel 홈페이지에 그냥 있음
https://vercel.com/guides/how-can-i-use-github-actions-with-vercel
그리고 vercel의 좋은 점이라하면 preview 배포와 production 배포를 구분할 수 있다는 건데 위 링크에서 .github/workflows/production.yaml
만 만들면 모든 브랜치에서 preview deploy가 이루어지는 약간은 비효율적인 상황이 생긴다.
.github/workflows/preview.yaml
의 branches 부분을 수정한다. on:
push:
branches-ignore:
- main
를
on:
push:
branches:
- 특정 브랜치 이름
[ "$VERCEL_ENV" != production ]
아주 잘 작동한다.