Hyeond Deok's Blog

Astro로 GitHub Pages 블로그 구축 및 자동 배포하기 (서브모듈 연동)

Astro 프레임워크로 개인 블로그를 개설하고, GitHub Actions와 서브모듈 시스템을 유기적으로 결합하여 GitHub Pages에 안전하게 자동 배포하는 프로세스를 기록합니다.

HyeonD · · 7 min read · Deep Dive
img of Astro로 GitHub Pages 블로그 구축 및 자동 배포하기 (서브모듈 연동)

Astro는 최신 웹 트렌드에 걸맞은 빠른 렌더링 성능(아일랜드 아키텍처)과 훌륭한 개발 경험(DX)을 선사하는 프레임워크입니다. 개인 기술 블로그를 가볍고 빠르게 유지하면서도, 비용 없이 안정적으로 호스팅할 수 있는 방법으로 GitHub Pages는 언제나 최적의 선택지입니다.

특히, 블로그의 코드 베이스와 작성하는 글 콘텐츠(Markdown/MDX 등)를 분리하여 효율적으로 관리하기 위해 Git 서브모듈(Submodule) 구조를 적용한 블로그 구축 및 배포 자동화(CI/CD) 여정을 공유하고자 합니다.


1. Astro 설정 조정하기

GitHub Pages 배포 시 가장 먼저 신경 써야 하는 부분은 바로 경로 설정입니다. Astro 프로젝트의 루트 디렉토리에 있는 astro.config.ts 파일에서 site 속성을 설정해야 빌드 시 올바른 절대 경로의 사이트맵과 파일 링크가 생성됩니다.

// astro.config.ts
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import sitemap from '@astrojs/sitemap';
import tailwind from "@astrojs/tailwind";
import react from "@astrojs/react";

export default defineConfig({
    // 배포될 GitHub Pages의 실제 URL을 지정합니다.
    site: 'https://historiabdevil.github.io/',
    markdown: {
        shikiConfig: {
            themes: {
                light: 'light-plus',
                dark: 'material-theme-palenight'
            },
            wrap: true
        }
    },
    integrations: [
        mdx(),
        sitemap(),
        tailwind(),
        react()
    ]
});
  • 만약 계정 하위의 서브 경로(예: username.github.io/blog/)에 배포한다면 base: '/blog' 옵션을 추가로 설정해 주어야 합니다. 여기서는 개인 도메인처럼 사용할 루트 주소이므로 별도의 base 없이 설정했습니다.

2. GitHub Actions를 이용한 자동 배포 구성

블로그에 글을 작성하고 GitHub main 브랜치에 푸시할 때마다 자동으로 빌드와 배포가 수행되도록 GitHub Actions 워크플로를 작성했습니다.

프로젝트 루트에 .github/workflows/deploy.yaml 파일을 생성하고 아래와 같이 정의합니다.

name: Deploy to GitHub Pages

on:
  push:
    branches: [ main ]
  workflow_dispatch:

# 배포에 필요한 권한 정의
permissions:
  contents: read
  pages: write
  id-token: write

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      # 1. 깃 레포지토리 체크아웃 (서브모듈 포함)
      - name: Checkout your repository using git
        uses: actions/checkout@v4
        with:
          submodules: 'recursive'
          token: ${{ secrets.BLOG_SECRET }}

      # 2. 서브모듈 동기화 및 최신화
      - name: Git Submodule Update
        run: |
          git pull --recurse-submodules
          git submodule update --remote --recursive

      # 3. 블로그 이미지 등 내부 리소스 복사
      - name: Copy Resources
        run: |
          if [ -d "src/content/blog/assets" ]; then
            ls -al src/content/blog/assets
            cp -r src/content/blog/assets/* public/
          fi

      # 4. 서브모듈의 포인터 최신화 변경분 자동 커밋 (무한 루프 방지)
      - name: Commit Update
        run: |
          git config --global user.email "bot@noreply.github.com"
          git config --global user.name "git-bot"
          git remote set-url origin "https://x-access-token:${{ secrets.BLOG_SECRET }}@github.com/${{ github.repository }}"
          git commit -am "[no ci]: automated commit submodules" && git push || echo "No changes to commit"

      # 5. Astro 빌드 및 아티팩트 업로드
      - name: Install, build, and upload your site
        uses: withastro/action@v2
        with:
          path: .
          node-version: 20
          package-manager: pnpm@latest

  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4

3. 핵심 자동화 포인트 분석

이 워크플로는 단순히 코드를 빌드하고 배포하는 것을 넘어, 콘텐츠 서브모듈과의 긴밀한 연동을 위한 특별한 장치들이 마련되어 있습니다.

① Git 서브모듈(Submodule)의 재귀적 체크아웃

Astro 블로그 코드와 실제 글 콘텐츠가 다른 레포지토리로 분리된 구조를 띨 때, 빌드 시점에 두 소스가 완벽하게 머지되어야 합니다. actions/checkout@v4에서 submodules: 'recursive' 옵션과 BLOG_SECRET 개인 접근 토큰(PAT)을 지정해 서브모듈까지 온전히 클론을 받아옵니다.

② 리소스 자원(Assets) 동적 매핑

글에 포함될 각종 이미지 등의 애셋(src/content/blog/assets)을 빌드 단계에서 Astro의 public/ 디렉토리로 동적으로 이식합니다. 덕분에 컨텐츠 작성자는 본인 레포지토리에서 상대 경로 이미지 관리가 편리해집니다.

[no ci]를 활용한 무한 빌드 루프 예방

서브모듈의 포인터 변동사항을 반영하여 부모 레포지토리에 다시 푸시하는 Commit Update 단계가 포함되어 있습니다. 이때 푸시 행위 자체가 깃허브 액션을 다시 트리거할 수 있으므로, 커밋 메시지에 [no ci] 태그를 삽입하여 무한 배포 빌드 순환에 빠지지 않도록 우아하게 방지했습니다.


4. 마치며

이번 설정을 통하여 pnpm 기반으로 빠르고 경제적인 Astro 블로그의 CI/CD 파이프라인이 매끄럽게 완성되었습니다. 이제 개발자는 로컬에서 코드를 번거롭게 빌드하여 수동으로 깃허브에 밀어 넣을 필요 없이, 본문에 포스트를 커밋하고 푸시하는 단 한 번의 액션으로 실시간 배포 서비스를 누릴 수 있습니다.

앞으로는 여기에 덧붙여 블로그의 풍성한 경험을 위한 RSS Feed 생성 기능이나 수익화를 위한 Google AdSense 연동 등을 유기적으로 붙여나갈 계획입니다. 나만의 정교한 기록 저장소를 원하신다면 Astro와 GitHub Pages의 결합을 강력하게 추천해 드립니다!