안녕하세요, 자바파커입니다.
"글 수정할 때마다 npm run build 하고 gh-pages 브랜치에 push하고... 이걸 매번 해야 하나요?"
솔직히 말하면, 수동 배포를 계속하다 보면 글 쓰는 것보다 배포가 더 귀찮아지는 순간이 옵니다. 결론부터 말씀드리면 — GitHub Actions를 설정하면 git push 한 번으로 빌드부터 배포까지 전부 자동화할 수 있습니다.
이번 포스팅에서는 Gatsby 블로그를 GitHub Actions로 자동 배포하는 CI/CD 파이프라인을 처음부터 끝까지 구축해보겠습니다.
수동 배포의 문제점
수동으로 GitHub Pages에 배포하려면 보통 이런 과정을 거칩니다.
# 1. 빌드
npm run build
# 2. gh-pages 브랜치에 배포
npx gh-pages -d public
# 3. 또는 직접 public 폴더를 gh-pages 브랜치에 push이 방식의 문제점은 명확합니다.
- 글을 수정할 때마다 수동으로 빌드해야 합니다
- 빌드 명령어를 잊거나 실수하면 배포가 안 됩니다
- 로컬 환경에 따라 빌드 결과가 달라질 수 있습니다
- 시간이 오래 걸립니다 (특히 Gatsby 빌드는 느린 편)
자동화의 핵심은 단순합니다. 코드를 push하면 나머지는 서버가 알아서 하도록 만드는 것입니다.
GitHub Actions 기본 개념
GitHub Actions는 GitHub에서 제공하는 CI/CD(지속적 통합/지속적 배포) 서비스입니다. 레포지토리에 특정 이벤트(push, PR 등)가 발생하면 정의된 작업을 자동으로 실행합니다.
핵심 용어 정리
| 용어 | 설명 | 비유 |
|---|---|---|
| Workflow | 자동화 작업의 전체 흐름 | 레시피 전체 |
| Event | 워크플로우를 실행하는 트리거 | "주문이 들어오면" |
| Job | 워크플로우 안의 작업 단위 | 레시피의 각 단계 (재료 준비, 조리, 플레이팅) |
| Step | Job 안의 개별 명령어 | "양파를 잘게 썬다" |
| Runner | 워크플로우가 실행되는 서버 | 주방 |
| Action | 재사용 가능한 Step 묶음 | 밀키트 (미리 만들어진 것) |
워크플로우 파일은 .github/workflows/ 디렉토리에 YAML 형식으로 작성합니다.
블로그 배포용 workflow 파일 작성
프로젝트 루트에 .github/workflows/deploy.yml 파일을 만들겠습니다.
전체 workflow 파일
# .github/workflows/deploy.yml
name: Deploy Blog to GitHub Pages
on:
push:
branches:
- main # main 브랜치에 push하면 실행
permissions:
contents: write
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
# 1. 레포지토리 코드 체크아웃
- name: Checkout repository
uses: actions/checkout@v4
# 2. Node.js 설정
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
# 3. 의존성 설치
- name: Install dependencies
run: npm ci
# 4. Gatsby 빌드
- name: Build Gatsby site
run: npm run build
env:
PREFIX_PATHS: true
# 5. GitHub Pages 배포
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./public
publish_branch: gh-pages이 파일 하나면 main 브랜치에 push할 때마다 자동으로 빌드 후 gh-pages 브랜치에 배포됩니다.
파일 생성 방법
# 디렉토리 생성
mkdir -p .github/workflows
# 파일 생성 (위 내용을 붙여넣기)
nano .github/workflows/deploy.yml각 Step 상세 설명
Step 1: actions/checkout
- name: Checkout repository
uses: actions/checkout@v4GitHub Actions Runner(서버)에 레포지토리 코드를 가져옵니다. 모든 워크플로우의 첫 번째 단계입니다.
Step 2: actions/setup-node
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"Node.js를 설치합니다. node-version은 로컬에서 사용하는 버전과 맞추는 것이 좋습니다.
로컬 Node.js 버전 확인 방법:
node -v
# v20.11.0 이런 식으로 출력됩니다Step 3: npm ci
- name: Install dependencies
run: npm cinpm install 대신 npm ci를 사용합니다. npm ci는 package-lock.json을 기반으로 정확히 동일한 의존성을 설치하므로, 빌드 환경의 일관성을 보장합니다.
Step 4: Gatsby 빌드
- name: Build Gatsby site
run: npm run build
env:
PREFIX_PATHS: truegatsby build 명령어를 실행해 정적 파일을 생성합니다. 결과물은 public/ 폴더에 저장됩니다.
Step 5: peaceiris/actions-gh-pages
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./public
publish_branch: gh-pagespublic/ 폴더의 내용을 gh-pages 브랜치에 자동으로 push합니다. GITHUB_TOKEN은 별도 설정 없이 GitHub Actions가 자동으로 제공합니다.
캐시 설정으로 빌드 속도 향상
Gatsby 빌드는 처음에는 시간이 꽤 걸립니다. 캐시를 설정하면 빌드 시간을 크게 줄일 수 있습니다.
npm 캐시 (이미 적용됨)
actions/setup-node의 cache: "npm" 옵션으로 npm 패키지 캐시는 이미 적용되어 있습니다.
Gatsby 캐시 추가
Gatsby는 .cache 폴더에 빌드 캐시를 저장합니다. 이것도 캐시하면 빌드 속도가 더 빨라집니다.
# Step 2와 Step 3 사이에 추가
- name: Cache Gatsby build
uses: actions/cache@v4
with:
path: |
.cache
public
key: gatsby-build-${{ hashFiles('package-lock.json') }}-${{ hashFiles('contents/**') }}
restore-keys: |
gatsby-build-${{ hashFiles('package-lock.json') }}-
gatsby-build-캐시 적용 전후 빌드 시간 비교
| 단계 | 캐시 없음 | 캐시 있음 |
|---|---|---|
| npm install | ~60초 | ~10초 |
| gatsby build | ~120초 | ~30초 |
| 전체 | ~3분 | ~1분 |
실제 시간은 블로그 규모에 따라 다르지만, 캐시만으로 2~3배 빨라지는 것을 체감할 수 있습니다.
캐시 포함 완성 workflow
캐시까지 포함한 최종 workflow 파일입니다.
# .github/workflows/deploy.yml
name: Deploy Blog to GitHub Pages
on:
push:
branches:
- main
permissions:
contents: write
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- name: Cache Gatsby build
uses: actions/cache@v4
with:
path: |
.cache
public
key: gatsby-build-${{ hashFiles('package-lock.json') }}-${{ hashFiles('contents/**') }}
restore-keys: |
gatsby-build-${{ hashFiles('package-lock.json') }}-
gatsby-build-
- name: Install dependencies
run: npm ci
- name: Build Gatsby site
run: npm run build
env:
PREFIX_PATHS: true
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./public
publish_branch: gh-pages커스텀 도메인 설정 (CNAME)
blog.javapark.kr처럼 커스텀 도메인을 사용하고 있다면, 배포할 때마다 CNAME 파일이 유지되어야 합니다.
방법 1: static 폴더에 CNAME 파일 추가
echo "blog.javapark.kr" > static/CNAMEGatsby 빌드 시 static/ 폴더의 파일이 그대로 public/에 복사되므로, 배포 시 자동으로 포함됩니다.
방법 2: workflow에서 CNAME 옵션 사용
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./public
publish_branch: gh-pages
cname: blog.javapark.kr두 가지 방법 모두 동일한 결과를 만들지만, 저는 방법 1을 추천합니다. CNAME 파일이 프로젝트에 명시적으로 포함되어 있으면 관리가 더 편합니다.
GitHub Pages 설정 확인
workflow를 배포하기 전에 GitHub 레포지토리 설정을 확인해야 합니다.
- GitHub 레포지토리 > Settings 탭 클릭
- 왼쪽 메뉴에서 Pages 클릭
- Source 항목을 Deploy from a branch로 설정
- Branch를
gh-pages// (root)로 설정 - Save 클릭
이 설정이 되어 있어야 gh-pages 브랜치에 push된 파일이 실제로 웹에 배포됩니다.
배포 상태 확인 및 디버깅
Actions 탭에서 확인
push 후 GitHub 레포지토리의 Actions 탭에 들어가면 워크플로우 실행 상태를 확인할 수 있습니다.
- 초록색 체크: 성공
- 빨간색 X: 실패
- 노란색 원: 진행 중
빌드 실패 시 확인할 것
실패한 워크플로우를 클릭하면 각 Step의 로그를 볼 수 있습니다. 자주 발생하는 오류와 해결법을 정리했습니다.
| 오류 | 원인 | 해결법 |
|---|---|---|
npm ci 실패 |
package-lock.json 불일치 |
로컬에서 npm install 후 lock 파일 커밋 |
gatsby build 실패 |
플러그인 설정 오류 | 로컬에서 gatsby build 먼저 테스트 |
| 권한 오류 | permissions 미설정 |
workflow에 permissions: contents: write 추가 |
gh-pages 배포 안 됨 |
Pages 설정 미완료 | Settings > Pages에서 브랜치 설정 확인 |
로컬에서 빌드 테스트
GitHub Actions에 push하기 전에 로컬에서 빌드가 정상인지 확인하는 습관을 들이면 좋습니다.
# 캐시 정리 후 빌드 테스트
gatsby clean && gatsby build배포 프로세스 전체 흐름 정리
로컬에서 글 작성/수정
|
v
git add . && git commit -m "새 글 추가"
|
v
git push origin main
|
v
GitHub Actions 자동 실행
1. 코드 체크아웃
2. Node.js 설정
3. 캐시 복원
4. npm ci
5. gatsby build
6. gh-pages 브랜치에 배포
|
v
GitHub Pages가 gh-pages 브랜치 감지
|
v
https://blog.javapark.kr 에 반영 완료이제 글을 쓰고 push만 하면 됩니다. 나머지는 전부 자동입니다.
자주 묻는 질문 (FAQ)
Q. GitHub Actions는 무료인가요?
네, 공개(public) 레포지토리에서는 완전 무료입니다. 비공개(private) 레포지토리에서는 월 2,000분의 무료 빌드 시간이 제공됩니다. 블로그 하나를 운영하기에는 충분한 양입니다.
Q. main 브랜치가 아닌 다른 브랜치에서 배포하고 싶어요
workflow 파일의 on.push.branches 값을 변경하면 됩니다. 예를 들어 develop 브랜치에서 배포하려면 다음과 같이 수정합니다.
on:
push:
branches:
- developQ. 배포 후 사이트에 반영되기까지 얼마나 걸리나요?
보통 GitHub Actions 빌드에 13분, GitHub Pages 반영에 12분 정도 걸립니다. 전체적으로 push 후 3~5분이면 사이트에 반영됩니다. 캐시가 따뜻한(warm) 상태라면 더 빨라집니다.
여러분은 블로그 배포를 어떻게 하고 계신가요? 댓글로 알려주세요.
다음 포스팅에서는 블로그에 광고와 댓글 시스템을 다는 방법을 다룹니다. AdSense, 쿠팡 파트너스로 수익화하고, Utterances로 댓글 기능을 구축하는 방법까지 알아보겠습니다.