블로그 구축기 #3 - 데이터베이스 없이 블로그 운영하기

5 min readJeongwoo Ahn

블로그 구축기 #3 - 데이터베이스 없이 블로그 운영하기

thumbnail

들어가며

블로그 구축기 #1에서 Module Federation 아키텍처를, #2에서 CSR 프로젝트의 사이트맵 제출을 다뤘습니다.

시간이 흐르고, 저는 아키텍처를 바꿨습니다.

Module Federation은 좋은 실험이었지만, 개인 블로그에는 과한 복잡도였습니다. 여러 앱을 동시에 실행하고, 라우터를 동기화하고, 환경변수를 관리하는 것이 점점 번거로워졌습니다.

무엇보다 SEO 문제가 해결되지 않았습니다. CSR 기반이라 검색엔진이 콘텐츠를 제대로 인식하지 못했고, 사이트맵만으로는 한계가 있었습니다.

그래서 다시 원점으로 돌아갔습니다.

“데이터베이스 없이, 마크다운 파일만으로 블로그를 운영할 수 없을까?”

왜 데이터베이스가 필요 없는가

블로그 글은 본질적으로 정적 콘텐츠입니다.

한 번 작성하면 자주 바뀌지 않고, 실시간 동기화가 필요하지 않습니다. 댓글이나 좋아요 같은 동적 기능을 제외하면, 블로그 글 자체는 파일로 충분합니다.

데이터베이스를 사용하면:

  • DB 서버 비용이 발생합니다
  • 연결 관리, 마이그레이션, 백업을 신경 써야 합니다
  • 글을 작성할 때마다 관리자 페이지가 필요합니다

반면 마크다운 파일을 사용하면:

  • Git으로 버전 관리가 됩니다
  • 어떤 에디터에서든 작성할 수 있습니다
  • 빌드만 하면 배포가 끝납니다

아키텍처 전환: Module Federation → Vite SSG

기존 아키텍처는 이랬습니다:

┌─────────────────┐
│   Shell App     │ ← 런타임에 Remote 앱 로드
├─────────────────┤
│  Blog App       │ ← 별도 빌드, 별도 배포
├─────────────────┤
│  Guestbook App  │ ← 별도 빌드, 별도 배포
└─────────────────┘

새로운 아키텍처는 훨씬 단순합니다:

┌─────────────────┐
│   Home App      │ ← SSG로 빌드
│   (통합)         │
│  - 홈페이지      │ ← 정적 HTML
│  - 블로그        │ ← 정적 HTML
│  - 방명록        │ ← CSR (예외)
└─────────────────┘

하나의 앱에서 모든 것을 처리합니다. 빌드 시 정적 HTML이 생성되고, Cloudflare Pages에 배포됩니다.

빌드 파이프라인

핵심은 빌드 시점에 모든 것을 처리하는 것입니다.

1단계: 마크다운 파일 작성

posts/
├── 2025-11-10-javascript-set.md
├── 2025-12-06-module-federation.md
└── 2026-03-13-blog-build-markdown-ssg.md  ← 이 글

각 파일에는 frontmatter로 메타데이터를 정의합니다:

---
title: "글 제목"
date: 2026-03-13
tags: [blog, ssg]
description: "한 줄 설명"
---

# 본문 내용

마크다운으로 작성...

2단계: 메타데이터 수집 (build-posts.ts)

빌드 스크립트가 모든 마크다운 파일을 읽어 JSON으로 변환합니다:

async function processMarkdownFile(filePath: string): Promise<BlogPost | null> {
  const fileContent = await fs.readFile(filePath, 'utf-8');
  const { data, content } = matter(fileContent);

  // 마크다운 → HTML 렌더링
  const html = await renderMarkdown(content);

  // 목차 생성
  const toc = generateTOC(html);

  // 읽기 시간 계산
  const readingTime = calculateReadingTime(content);

  return { slug, frontmatter, content, html, readingTime, toc };
}

결과물은 src/generated/posts.json에 저장됩니다:

{
  "posts": [
    {
      "slug": "blog-build-markdown-ssg",
      "frontmatter": { "title": "...", "date": "...", "tags": [...] },
      "html": "<h1>본문...</h1>",
      "readingTime": 5,
      "toc": [{ "id": "heading-1", "text": "제목", "level": 2 }]
    }
  ],
  "tags": ["blog", "ssg", "seo"],
  "totalPosts": 15,
  "lastUpdated": "2026-03-13T..."
}

3단계: SSG 빌드 (Vite SSG)

Vite SSG가 JSON을 기반으로 정적 HTML을 생성합니다:

// vite.config.ts
ssgOptions: {
  includedRoutes: async () => {
    const metadata = await import('./src/generated/posts.json');

    const routes = [
      '/',
      '/blog',
      ...metadata.posts.map(p => `/blog/${p.slug}`),
      ...metadata.tags.map(t => `/blog/tags/${t}`),
    ];

    return routes;
  },
}

빌드 결과:

dist/
├── index.html
├── blog/
│   ├── index.html
│   ├── blog-build-markdown-ssg/
│   │   └── index.html  ← 이 글의 정적 HTML
│   └── tags/
│       ├── blog/index.html
│       └── ssg/index.html
└── assets/
    └── ...

각 블로그 글이 완전한 HTML 파일로 생성됩니다. JavaScript가 로드되기 전에도 콘텐츠가 보입니다.

SEO 최적화

SSG의 가장 큰 장점은 SEO입니다.

메타 태그

각 페이지에 적절한 메타 태그가 삽입됩니다:

<head>
  <title>블로그 구축기 #3 - 데이터베이스 없이 블로그 운영하기</title>
  <meta name="description" content="마크다운 파일과 서버리스 도구만으로...">
  <meta property="og:title" content="블로그 구축기 #3">
  <meta property="og:image" content="https://images.jeongwoo.in/...">
</head>

사이트맵 자동 생성

블로그 구축기 #2에서 다뤘듯이, 사이트맵을 R2에 업로드하고 Worker로 서빙합니다.

// generate-sitemap.ts
const links = [
  { url: '/', priority: 1.0 },
  { url: '/blog', priority: 1.0 },
  ...metadata.posts.map(post => ({
    url: `/blog/${post.slug}`,
    lastmod: post.frontmatter.date,
    priority: 0.8,
  })),
];

이제 검색엔진이 모든 페이지를 제대로 크롤링할 수 있습니다.

서버리스 인프라

전체 인프라가 서버리스입니다:

역할서비스비용
호스팅Cloudflare Pages무료
사이트맵 저장Cloudflare R2무료 (10GB)
사이트맵 서빙Cloudflare Workers무료 (10만 요청/일)
이미지 호스팅Cloudflare R2무료 (10GB)
도메인Cloudflare DNS도메인 비용만

월 비용: 도메인 비용만 (연간 약 1만원)

서버 관리가 필요 없습니다. 배포는 Git push만 하면 끝입니다:

git add .
git commit -m "새 글 추가"
git push origin main
# Cloudflare Pages가 자동으로 빌드 & 배포

워크플로우

글을 발행하는 전체 워크플로우입니다:

1. 마크다운 파일 작성
   └─ posts/20260313-new-post.md

2. 로컬에서 확인
   └─ pnpm dev

3. 빌드 테스트
   └─ pnpm build

4. Git 커밋 & 푸시
   └─ git push origin main

5. Cloudflare Pages 자동 배포
   └─ 빌드 → 사이트맵 업로드 → 배포

6. 완료!
   └─ https://jeongwoo.in/blog/new-post

장단점 정리

장점

  • 비용 없음: 서버리스 무료 티어로 충분
  • 빠른 로딩: 정적 HTML이라 초기 로딩이 빠름
  • SEO 친화적: 검색엔진이 콘텐츠를 제대로 인식
  • 심플한 배포: Git push만 하면 끝
  • 버전 관리: 모든 글이 Git으로 관리됨
  • 어디서든 작성: 에디터만 있으면 글 작성 가능

단점

  • 동적 기능 제한: 댓글, 좋아요 등은 별도 서비스 필요
  • 빌드 시간: 글이 많아지면 빌드가 느려질 수 있음
  • 실시간 수정 불가: 수정하려면 다시 빌드 & 배포 필요

마치며

“데이터베이스 없이도 블로그를 운영할 수 있을까?”

답은 충분히 가능하다입니다.

마크다운 파일을 Git으로 관리하고, SSG로 정적 페이지를 생성하고, 서버리스 인프라에 배포하면 됩니다. 복잡한 백엔드도, 비싼 서버 비용도 필요 없습니다.

물론 이 방식이 모든 상황에 맞는 것은 아닙니다. 실시간 상호작용이 중요하거나, 비개발자가 글을 작성해야 한다면 CMS가 더 나을 수 있습니다.

하지만 개발자가 개인 블로그를 운영한다면, 이 방식을 고려해볼 만합니다.

코드가 곧 콘텐츠이고, Git이 곧 CMS입니다.


관련 글

참고 자료