핵심 요약

  • johnjin.blog(Ghost)는 육아 콘텐츠 전용으로 유지하고, 개발 기록은 dev.johnjin.blog(Astro)로 분리했습니다.
  • Next.js 대비 Astro는 빌드 결과물이 정적 HTML이라 Vercel 무료 플랜에서도 빠르게 돌아갑니다.
  • Claude Code + Git 워크플로우로 마크다운 파일을 작성하고 Vercel이 자동 배포합니다.

왜 개발 블로그가 따로 필요했나

저는 johnjin.blog를 Ghost로 운영하고 있습니다. 주요 독자는 육아에 관심 있는 분들이고, 글의 톤도 가볍고 일상적입니다. 그런데 기술적인 내용—예를 들어 Ghost 설정 방법, SEO 실험 결과, 뉴스레터 워커 코드—을 같은 공간에 올리면 독자층이 섞입니다.

개발자가 아닌 독자에게 TypeScript 코드 블록은 방해가 되고, 개발자 독자에게 육아 콘텐츠는 노이즈입니다. 분리가 답이었습니다.

두 번째 Ghost 인스턴스를 띄우는 방법도 있었지만, 서버 비용이 두 배가 됩니다. 정적 사이트 생성기(SSG)가 더 합리적인 선택이었습니다.


Next.js vs Astro: 선택의 이유

처음에는 Next.js App Router를 고려했습니다. 생태계가 크고 익숙한 React 문법을 쓸 수 있기 때문입니다. 하지만 블로그라는 유스케이스에 Next.js는 과도한 선택입니다.

항목GhostAstro (dev 블로그)
콘텐츠 타입뉴스레터, 멤버십기술 문서, TIL, 에세이
대상 독자일반 독자개발자
서버 필요 여부필요 (Node.js)불필요 (정적)
빌드 결과물서버 렌더링정적 HTML
Vercel 비용유료 플랜 권장무료 플랜으로 충분
마크다운 지원내장 에디터Content Collections

Astro의 결정적 장점은 Island Architecture입니다. 기본적으로 JavaScript를 클라이언트에 전송하지 않고, 필요한 컴포넌트에만 선택적으로 hydration을 적용합니다. 블로그는 대부분 읽기 전용 콘텐츠이므로 이 접근이 완벽하게 들어맞습니다.

또한 Astro v5부터 Content Collections에 glob 로더 API가 추가되어, Zod 스키마로 마크다운 프런트매터를 타입 안전하게 검증할 수 있게 됐습니다.


프로젝트 구조

dev-johnjin-blog/
├── src/
│   ├── content/
│   │   ├── blog/              # 마크다운 포스트
│   │   └── .gitignore
│   ├── content.config.ts      # Content Collections 스키마
│   ├── pages/
│   │   ├── index.astro        # 홈
│   │   ├── blog/
│   │   │   ├── index.astro    # 포스트 목록
│   │   │   └── [slug].astro   # 포스트 상세
│   │   └── rss.xml.js         # RSS 피드
│   ├── layouts/
│   │   └── BlogPost.astro
│   └── components/
│       └── Header.astro
├── public/
├── astro.config.mjs
└── package.json

Content Collections 스키마는 src/content.config.ts에 정의합니다:

import { defineCollection } from 'astro:content';
import { glob } from 'astro/loaders';
import { z } from 'astro/zod';

const blog = defineCollection({
  loader: glob({ base: './src/content/blog', pattern: '**/*.{md,mdx}' }),
  schema: z.object({
    title: z.string(),
    description: z.string(),
    pubDate: z.coerce.date(),
    category: z.enum(['프로젝트', '에세이', 'TIL']),
    tags: z.array(z.string()).default([]),
    schemaType: z.enum(['article', 'faq', 'howto']).default('article'),
  }),
});

export const collections = { blog };

Claude Code + Git 워크플로우

가장 흥미로운 부분입니다. 콘텐츠 작성과 배포를 모두 터미널에서 처리합니다.

  1. Claude Code를 열고 글의 주제와 구조를 프롬프트로 설명합니다.
  2. Claude Code가 마크다운 파일을 src/content/blog/에 생성합니다.
  3. git add && git commit && git push로 GitHub에 올립니다.
  4. Vercel이 push 이벤트를 감지해 자동으로 빌드하고 배포합니다.

에디터를 열 필요가 없습니다. CMS 로그인도 없습니다. 마크다운 파일이 곧 콘텐츠이고, Git이 버전 관리 시스템입니다.

이 워크플로우는 Ghost의 것과 완전히 다릅니다. Ghost는 웹 에디터에서 글을 쓰고 저장하면 끝입니다. Astro는 코드와 콘텐츠의 경계가 없습니다—둘 다 파일 시스템의 파일입니다.


앞으로의 계획

  • OG 이미지 자동 생성 (Satori 또는 Cloudflare Workers 활용)
  • Google Search Console + Vercel Analytics 연동
  • RSS 피드를 통한 johnjin.blog 뉴스레터와의 크로스포스팅

개발 블로그를 따로 운영한다는 게 처음에는 부담처럼 느껴졌지만, 실제로는 더 가볍습니다. Ghost의 멤버십, 구독, 이메일 발송 같은 복잡한 기능이 없으니까요. 파일을 쓰고 push하면 끝입니다.