GitHub Actions로 블로그 자동 배포하기 — push만 하면 끝

@JavaPark · April 04, 2026 · 12 min read

안녕하세요, 자바파커입니다.

"글 수정할 때마다 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@v4

GitHub 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 ci

npm install 대신 npm ci를 사용합니다. npm cipackage-lock.json을 기반으로 정확히 동일한 의존성을 설치하므로, 빌드 환경의 일관성을 보장합니다.

Step 4: Gatsby 빌드

- name: Build Gatsby site
  run: npm run build
  env:
    PREFIX_PATHS: true

gatsby 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-pages

public/ 폴더의 내용을 gh-pages 브랜치에 자동으로 push합니다. GITHUB_TOKEN은 별도 설정 없이 GitHub Actions가 자동으로 제공합니다.


캐시 설정으로 빌드 속도 향상

Gatsby 빌드는 처음에는 시간이 꽤 걸립니다. 캐시를 설정하면 빌드 시간을 크게 줄일 수 있습니다.

npm 캐시 (이미 적용됨)

actions/setup-nodecache: "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/CNAME

Gatsby 빌드 시 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 레포지토리 설정을 확인해야 합니다.

  1. GitHub 레포지토리 > Settings 탭 클릭
  2. 왼쪽 메뉴에서 Pages 클릭
  3. Source 항목을 Deploy from a branch로 설정
  4. Branchgh-pages / / (root)로 설정
  5. 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:
      - develop

Q. 배포 후 사이트에 반영되기까지 얼마나 걸리나요?

보통 GitHub Actions 빌드에 13분, GitHub Pages 반영에 12분 정도 걸립니다. 전체적으로 push 후 3~5분이면 사이트에 반영됩니다. 캐시가 따뜻한(warm) 상태라면 더 빨라집니다.


여러분은 블로그 배포를 어떻게 하고 계신가요? 댓글로 알려주세요.

다음 포스팅에서는 블로그에 광고와 댓글 시스템을 다는 방법을 다룹니다. AdSense, 쿠팡 파트너스로 수익화하고, Utterances로 댓글 기능을 구축하는 방법까지 알아보겠습니다.

@JavaPark
AI 시대의 개발자 도구, 실전 경험을 공유합니다