1. 준비

Cloudflare 계정이 필요하다. 계정이 없다면 여기에서 생성할 수 있음.

2. GitHub에서 Quartz 저장소 생성

Quartz 템플릿으로 새로운 저장소 생성
Use this templateCreate a new repository 클릭

3. Cloudflare와 GitHub 연동

Cloudflare 대시보드 접속 → Workers 및 Pages 클릭 → Pages 탭에서 GitHub 저장소 연결

  • 프로젝트 이름 = 도메인 이름
  • 프로덕션 브랜치 = v4
  • 프레임워크 미리 설정 = 없음
  • 빌드 명령 = npx quartz build
  • 출력 디렉토리 = public

4. 옵시디언 노트 퍼블리싱

Flowershow 플러그인을 통해 .md 파일을 GitHub에 업로드 가능

📌 단, 이미지 파일은 업로드되지 않음 → 따로 처리 필요


📦 이미지 동기화 및 Flowershow 한계

Flowershow 플러그인을 통해 Markdown 파일은 GitHub에 업로드할 수 있지만, 다음과 같은 한계가 있음

문제설명
❌ 이미지 자동 업로드 불가![[Images/파일명.png]] 형식의 이미지가 GitHub에 푸시되지 않음
❌ 이미지 파일도 함께 삭제됨Obsidian에서 .md 파일 삭제 시 연동된 이미지도 함께 제거되는 문제 발생
❌ 업로드 경로 제어 불가이미지 저장 위치 및 구조를 사용자 정의하기 어려움

🔁 선택한 대안: 파일 동기화 기반 Quartz 퍼블리싱

이러한 한계를 해결하기 위해 다음과 같은 전략을 사용했음

  1. ~/Coding/Obsidian/Blog 폴더를 Obsidian 작성용 폴더로 지정
  2. ~/Coding/Obsidian/SecondBrain/content를 Quartz 퍼블리싱용 content 폴더로 설정
  3. rsync 명령어를 사용하여 Blog 폴더 전체를 content 폴더로 복사
  4. 이미지 포함 모든 파일이 동기화되므로, 퍼블리싱 누락 없이 반영 가능
rsync -av --delete ~/Coding/Obsidian/Blog/ ~/Coding/Obsidian/SecondBrain/content/

🚀 자동화 스크립트

sync-secondbrain.sh 파일을 만들어 아래처럼 자동화 가능:

#!/bin/bash
 
echo "🔄 동기화 시작..."
rsync -av --delete ~/Coding/Obsidian/Blog/ ~/Coding/Obsidian/SecondBrain/content/
 
echo "🔧 Quartz 빌드 중..."
cd ~/Coding/Obsidian/SecondBrain
npx quartz build
 
echo "📦 Git 푸시 중..."
git add .
git commit -m "📝 자동 동기화 및 빌드"
git push origin v4

💡 결과

  • ✅ 이미지 포함 완전 자동 퍼블리싱
  • ✅ Cloudflare Pages 자동 배포
  • ✅ Flowershow의 제약 극복
  • ✅ 터미널에서 syncNote 명령어 하나면 모든게 자동화

5. 퍼블리싱 세부 구성

5.1 Quartz 기본 구조

  1. Cloudflare는 GitHub push 감지 후 npx quartz build 자동 실행
  2. 로컬에서 확인하려면 직접 npx quartz build 실행
  3. content/ 폴더에 Markdown 파일 정리
  4. content/index.md → 홈 화면
  5. public/ 폴더는 자동 생성

5.2 이미지 처리 방식

  1. 이미지 파일은 content/Images/ 하위에 저장
  2. npx quartz buildpublic/Images/로 자동 반영됨
  3. Markdown에서는 ![[Images/파일명.png]] 형태로 삽입
  4. Flowershow는 이미지 push 불가 → 수동 복사 또는 자동화 필요 (추후 정리)

5.3 Cloudflare Pages 자동 배포


6. 💬 Giscus 댓글 시스템 적용

6.1 적용 절차

  1. quartz/components/Giscus.tsx 생성
  2. preactFunctionalComponent로 작성
  3. quartz.config.ts에서 afterBody에 Giscus 컴포넌트 추가

6.2 Giscus 컴포넌트 예시

// quartz/components/Giscus.tsx
import { FunctionalComponent, h } from "preact"
 
const Giscus: FunctionalComponent = () => (
  <div style={{ marginTop: "3rem" }}>
    <script
      src="https://giscus.app/client.js"
      data-repo="ParkJaeHan0623/SecondBrain"
      ...
      async
    ></script>
  </div>
)
 
export default Giscus

6.3 quartz.config.ts 수정

import Giscus from "./quartz/components/Giscus"
 
Plugin.ContentPage({
  afterBody: [Giscus], // ✅ 댓글 삽입 위치
}),

7. 🛠 트러블슈팅

문제해결 방법
react 타입 충돌react 제거 후 preact 사용
QuartzComponentConstructor 에러types.ts 삭제 후 FunctionalComponent로 대체
댓글 삽입 위치 조정afterBody에 연결
public/Images 삭제content/Images/에 유지하면 자동 생성됨

8. 🎉 퍼블리싱 결과 요약


9. 🛠 기타 트러블슈팅 & 배운 것

문제해결 방법
react 관련 타입 충돌react 제거, preactFunctionalComponent로 대체
QuartzComponentConstructor 에러types.ts 삭제 후 Preact 방식 전환
댓글 위치 조정afterBody 위치로 컴포넌트 등록
빌드 시 public/Images 삭제됨content/Images/로 유지하면 문제 없음