본문으로 건너뛰기

"platform" 태그로 연결된 4개 게시물개의 게시물이 있습니다.

모든 태그 보기

기술블로그 배포 전에 자동으로 검증하는 것들

· 약 2분
dev-burnern
Developer

핵심 요약

개인 기술블로그라도 배포 전 검증 기준이 있어야 한다. 글 하나가 깨진 링크나 잘못된 frontmatter를 포함하면 검색 인덱스, RSS, sitemap, 빌드 결과까지 함께 흔들릴 수 있기 때문이다.

이 저장소의 기준 명령은 npm run check다. strict sync, 테스트, audit, build를 한 번에 실행해서 콘텐츠 파이프라인과 Docusaurus 빌드가 같이 통과하는지 확인한다.

문제 상황

블로그 배포 실패는 코드 변경에서만 생기지 않는다. Markdown 문서 하나에 잘못된 wiki link가 남아 있어도 공개 페이지의 연결성이 깨진다. 같은 slug를 가진 글이 두 개 생기면 canonical URL과 sitemap 신뢰도가 떨어진다.

반복 검증을 사람이 기억에 의존해서 실행하는 것도 위험하다. 글을 빠르게 수정한 뒤 바로 배포하면 draft 글이 검색 인덱스에 들어가거나, description이 비어 있는 글이 sitemap에 포함될 수 있다.

설계 방식

검증은 네 단계로 나눴다.

첫 번째는 npm run sync:strict다. 이 단계는 Obsidian Markdown을 Docusaurus 글로 정규화하면서 slug 충돌, broken wiki link, 처리 실패, description 부족, tags 누락, category 누락을 검사한다.

두 번째는 npm test다. sync 로직의 순수 함수와 파이프라인 흐름을 Vitest로 검증한다. 이 테스트는 실제 posts/를 망가뜨리지 않도록 임시 디렉터리를 사용한다.

세 번째는 npm run audit다. 전체 의존성 audit을 실행해 보안 취약점을 확인한다. 운영 상황에서 배포 산출물 기준만 보고 싶을 때는 npm run audit:prod를 별도로 사용할 수 있다.

네 번째는 npm run build다. Docusaurus가 RSS, Atom, sitemap, 검색 인덱스, 정적 HTML을 모두 생성할 수 있는지 확인한다.

검증 방법

로컬에서는 다음 순서로 확인한다.

npm ci
npm run sync:strict
npm test
npm run audit
npm run build
npm run check

GitHub Actions에서는 같은 기준을 더 단순하게 적용한다. 의존성 설치 후 npm run check만 실행하게 해서 로컬과 CI의 기준을 맞춘다.

빌드 결과는 build/sitemap.xml, build/robots.txt, build/llms.txt, 글 HTML의 canonical/OG/Twitter/JSON-LD를 함께 확인한다. 이 검증은 검색 엔진과 AI 검색이 사이트 구조를 올바르게 읽는지 확인하기 위한 최소 기준이다.

개선 방향

앞으로는 검증 결과를 더 읽기 좋은 리포트로 만들 수 있다. 예를 들어 broken wiki link, slug 충돌, description 품질 문제를 Markdown 리포트로 남기면 PR에서 바로 확인할 수 있다.

또한 Lighthouse나 HTML validator를 CI에 추가하면 성능과 접근성까지 같은 흐름에서 점검할 수 있다. 다만 개인 블로그에서는 우선 빌드 안정성과 콘텐츠 메타데이터 신뢰도를 먼저 고정하는 것이 효과가 크다.

sync-posts는 Obsidian Markdown을 어떻게 Docusaurus 글로 바꾸는가

· 약 2분
dev-burnern
Developer

핵심 요약

scripts/sync-posts.mjs는 Obsidian에서 작성한 Markdown을 Docusaurus가 안정적으로 빌드할 수 있는 블로그 글로 정규화한다. 핵심은 글쓴이가 매번 메타데이터와 링크 문법을 손으로 맞추지 않아도 되도록, 파일 경로와 본문을 기준으로 필요한 정보를 자동 보정하는 것이다.

이 스크립트는 글 작성 도구와 배포 도구 사이의 번역 계층이다. Obsidian의 빠른 기록 경험은 유지하고, 공개 블로그에는 Docusaurus가 이해할 수 있는 구조만 남긴다.

문제 상황

Obsidian은 개발 기록을 빠르게 남기기 좋지만, 그 문법이 정적 블로그에 그대로 맞지는 않는다. [[문서]] 형태의 wiki link는 Docusaurus 라우트가 아니고, > [!note] 같은 callout은 Docusaurus admonition과 다르다.

frontmatter도 반복 비용이 있다. 글이 늘어나면 category, tags, slug, authors, draft를 매번 같은 기준으로 채워야 한다. 이 작업을 사람이 직접 하면 누락과 불일치가 생기기 쉽다.

구현 방식

sync 단계는 먼저 posts/ 아래의 Markdown과 MDX 파일을 순회한다. Excalidraw, 내부 문서, 숨김 폴더처럼 공개 블로그에 올리지 않을 파일은 제외한다.

각 글은 gray-matter로 frontmatter와 본문을 분리한 뒤 정규화한다. title이 없으면 첫 번째 H1에서 가져오고, date가 없으면 안전한 기본값을 넣는다. categorytags는 파일 경로에서 생성하며, slug는 직접 지정하지 않았을 때 경로 기반으로 만든다.

본문 변환은 코드 블록을 먼저 보호한 뒤 수행한다. 코드 블록 안의 [[...]]나 callout 예제가 실제 링크로 바뀌면 안 되기 때문이다. 이후 Obsidian callout을 Docusaurus admonition으로 바꾸고, wiki link는 실제 대상 파일을 찾아 블로그 permalink로 변환한다.

마지막으로 공개 글만 모아 static/posts.json을 만든다. 이 파일은 검색 페이지와 시리즈 내비게이션에서 사용한다. draft: true 글은 작성 중인 상태로 보고 검색 인덱스와 AI 검색 문맥에서 제외한다.

검증 방법

핵심 변환 로직은 Vitest로 검증한다. 숫자 접두어 제거, tag 정규화, slug 정규화, 경로 기반 category/tag 추출, callout 변환, wiki link 변환, frontmatter 기본값 보정이 테스트 대상이다.

로컬에서는 npm run sync로 경고 모드 동기화를 실행한다. CI와 배포 전에는 npm run sync:strict를 사용한다. strict 모드는 slug 충돌, broken wiki link, 처리 실패, 메타데이터 품질 문제를 실패로 보고 빌드를 막는다.

개선 방향

다음 단계는 변환 결과를 더 관찰 가능하게 만드는 것이다. 예를 들어 broken wiki link 리포트를 별도 파일로 남기고, 글별 변환 전후 diff를 요약하면 배포 전에 문제를 더 빨리 찾을 수 있다.

또한 slug 충돌은 현재 strict 실패 조건이지만, 앞으로는 충돌 후보를 더 친절하게 제안할 수 있다. 파일 경로 기반 slug를 유지하되, 같은 이름의 글이 늘어날 때 어떤 경로에서 충돌했는지 명확히 보여주는 방향이 좋다.

Obsidian 기반 기술블로그 파이프라인을 만든 이유

· 약 3분
dev-burnern
Developer

개발 기록은 작성할 때보다 다시 찾아 쓰고 공유할 때 가치가 커진다. 문제는 개인 지식 관리 도구와 공개 블로그가 요구하는 형식이 다르다는 점이다. Obsidian은 빠르게 연결하고 메모하기 좋지만, 그 문법을 그대로 정적 블로그에 올리면 링크, 콜아웃, 메타데이터가 깨지기 쉽다.

이 블로그는 그 간극을 줄이기 위해 만들었다. Obsidian에서는 작성 경험을 유지하고, 배포 단계에서는 Docusaurus가 안정적으로 빌드할 수 있는 문서로 정규화한다.

문제 상황

처음에는 글마다 title, date, slug, tags를 직접 관리했다. 글 수가 적을 때는 큰 문제가 아니었지만, 카테고리가 늘어나면서 반복 작업이 많아졌다.

  • 파일 경로와 블로그 카테고리가 따로 관리되었다.
  • Obsidian의 [[위키링크]]가 공개 블로그에서 의미 없는 텍스트가 되었다.
  • > [!note] 같은 콜아웃을 Docusaurus admonition으로 매번 고쳐야 했다.
  • 작성 중인 글을 배포 전에 제외하는 기준이 흔들렸다.
  • 검색 페이지를 위해 공개 글 목록을 다시 가공해야 했다.

반복되는 작업을 사람이 기억하는 방식으로 해결하면 언젠가 실수한다. 그래서 글 작성 규칙을 코드로 옮겼다.

왜 Docusaurus를 선택했는가

Docusaurus는 기술 문서에 필요한 기능을 기본값에 가깝게 제공한다. Markdown/MDX 기반 작성 흐름, 사이드바와 라우팅, RSS/Atom, sitemap, prism 코드 하이라이트, 플러그인 생태계가 개인 기술블로그에 잘 맞았다.

특히 Mermaid와 KaTeX를 함께 사용할 수 있어 아키텍처 다이어그램과 수식을 글 안에서 자연스럽게 다룰 수 있다. 정적 사이트로 배포되므로 GitHub Pages와도 잘 맞는다.

sync-posts가 해결하는 문제

scripts/sync-posts.mjs는 Obsidian에서 작성한 Markdown을 Docusaurus 블로그 글로 정규화한다.

  1. 누락된 frontmatter를 보정한다.
  2. 파일 경로에서 category와 tag를 파생한다.
  3. slug가 없으면 경로 기반 slug를 생성한다.
  4. Obsidian callout을 Docusaurus admonition으로 변환한다.
  5. wiki link를 실제 블로그 링크로 변환한다.
  6. draft: true 글은 검색 인덱스에서 제외한다.
  7. 공개 글을 모아 static/posts.json을 생성한다.

이 방식 덕분에 작성자는 문서 내용에 집중하고, 배포 전 형식 정리는 스크립트가 담당한다.

운영 방식

파일 경로는 정보 구조의 기준이다. 예를 들어 posts/platform/obsidian-blog-pipeline.mdplatform 카테고리와 태그를 자동으로 얻는다. 글이 많아져도 폴더 구조만 보면 어떤 주제를 다루는지 알 수 있다.

slug는 직접 지정할 수 있지만, 지정하지 않아도 경로 기반으로 생성된다. 공개 URL을 직접 제어해야 하는 글만 slug를 명시하고, 일반 글은 파일 경로를 따른다.

draft는 공개 여부를 나누는 운영 스위치다. draft: true인 글은 Docusaurus 빌드 대상에는 남아 있을 수 있지만, 블로그 검색 인덱스와 공개 목록에서 제외하는 기준으로 사용한다.

앞으로의 개선 방향

다음 단계는 파이프라인을 더 신뢰할 수 있게 만드는 것이다. slug 충돌을 더 강하게 감지하고, 깨진 wiki link를 리포트로 남기며, 글 품질 체크를 CI에 붙일 수 있다. 최종 목표는 글을 작성하는 순간부터 배포 가능한 기술 문서가 되는 흐름이다.

개인 기술블로그에서 SEO와 GEO를 함께 설계하는 방법

· 약 3분
dev-burnern
Developer

핵심 요약

SEO는 검색 엔진이 페이지를 정확히 수집하고 평가하게 만드는 작업이고, GEO는 생성형 AI 검색이 사이트의 목적과 신뢰 신호를 해석하기 쉽게 만드는 작업이다. 개인 기술블로그도 두 기준을 함께 설계해야 한다.

이 저장소에서는 dev-burnern.dev를 canonical 도메인으로 통일하고, sitemap과 robots, structured data, llms.txt를 같은 기준으로 맞춘다. 목표는 “개발 지식 관리와 배포 자동화 시스템”이라는 사이트의 성격을 사람과 검색 시스템 모두가 이해하게 만드는 것이다.

문제 상황

도메인과 사이트명이 섞이면 검색 신호가 분산된다. GitHub Pages 기본 주소, 저장소명, 서비스명이 모두 노출되면 어떤 URL이 대표 주소인지 불명확해진다.

또한 검색 페이지나 404 페이지가 sitemap에 포함되면 품질 신호가 약해질 수 있다. 이런 페이지는 탐색에는 필요하지만 검색 결과에 노출될 대표 콘텐츠는 아니다.

AI 검색 관점에서도 문제가 있다. 글이 여러 개 있어도 사이트 목적, 작성자 신뢰 신호, 핵심 글 묶음이 명확하지 않으면 “무엇을 하는 프로젝트인가”를 요약하기 어렵다.

설계 방식

대표 도메인은 https://dev-burnern.dev로 고정한다. docusaurus.config.tsurl, robots.txt의 sitemap URL, GitHub Pages custom domain인 static/CNAME을 같은 값으로 맞춘다. GitHub Pages 기본 주소는 README에서 호스팅 주소로만 설명한다.

sitemap에서는 /404, /search, /search-page를 제외한다. 검색 페이지와 404 페이지에는 noindex,follow를 넣어 링크 흐름은 유지하되 검색 결과 대표 문서로는 노출하지 않게 한다.

홈에는 WebSite, Person, Organization JSON-LD를 추가한다. 글 상세 페이지에는 BlogPostingBreadcrumbList를 제공하고, 글의 tags를 keywords로 연결한다. 작성자에는 GitHub, Instagram, LinkedIn sameAs를 넣어 신뢰 신호를 정리한다.

GEO를 위해 llms.txt도 생성한다. 이 파일은 사이트 목적, 주요 URL, 콘텐츠 파이프라인 설명, 핵심 글 목록, 작성자 신뢰 신호를 짧고 구조적으로 제공한다. 검색 엔진용 sitemap과 AI 검색용 요약 문맥을 별도로 제공하는 셈이다.

검증 방법

빌드 후에는 build/sitemap.xml/404, /search, /search-page가 없는지 확인한다. build/robots.txthttps://dev-burnern.dev/sitemap.xml을 가리키는지도 확인한다.

홈 HTML에서는 title과 description, OG, Twitter metadata, WebSite/Person/Organization JSON-LD를 확인한다. 글 HTML에서는 canonical, OG, Twitter metadata, BlogPosting JSON-LD, BreadcrumbList가 함께 존재하는지 본다.

build/llms.txt는 생성되어야 하며, 핵심 시리즈 글과 작성자 링크를 포함해야 한다. 이 파일은 sync 결과물이므로 npm run sync:strictnpm run build를 통과하면 같이 검증된다.

개선 방향

앞으로는 글별 JSON-LD를 더 풍부하게 만들 수 있다. 예를 들어 시리즈 글에는 isPartOfposition 정보를 추가해 글 묶음을 더 명확히 표현할 수 있다.

또한 OG 이미지를 글별로 자동 생성하면 공유 품질이 좋아진다. 다만 현재 단계에서는 canonical 도메인, sitemap, robots, JSON-LD, llms.txt가 일관된 것이 먼저다. 이 기반이 있어야 검색 엔진과 AI 검색이 같은 신호를 읽는다.