지난 글에서는 제게 맞는 Quartz 블로그 아키텍처를 찾기 위해 여러 방식을 비교해 봤습니다.
지난 글 요약
호스팅:
Cloudflare Pages(Private 리포지토리 무료 지원, 빠른 CDN)리포지토리:
1-Repo (Private)(관리가 단순하고 콘텐츠 비공개)배포 트리거:
Synology Cron(시놀로지 작업 스케줄러로 10분마다 git push)최종 아키텍처:
Synology (Cron)+Private 1-Repo (GitHub)+Cloudflare Pages
이번 글에서는 이 아키텍처를 실제로 구축하는 전체 과정을 단계별로 기록해 보려고 합니다.
1. 🐙 GitHub 리포지토리 준비
먼저 GitHub에서 2개의 리포지토리를 생성해야 합니다.
“분명 1-Repo(1개 리포지토리)로 관리한다고 했는데 왜 2개를 생성하나요?” 하실 수 있어요.
Quartz 자체에는 댓글 기능이 없습니다. 그래서 오픈소스 댓글 시스템인 Giscus를 추가하려고 하는데, 이 Giscus가 댓글 데이터를 저장할 별도의 (공개) 리포지토리를 필요로 하기 때문입니다.
-
my-quartz-blog(Private):-
핵심 리포지토리입니다. Quartz 소스코드와 제 Obsidian 콘텐츠(
.md파일)가 모두 이곳에 저장됩니다. -
Private(비공개) 으로 설정해서 제 글이 외부에 노출되지 않도록 합니다.
-
-
my-giscus-comments(Public):-
댓글 기능인
Giscus를 연동하기 위한 리포지토리입니다.Giscus가GitHub Discussions기능을 사용하기 때문에, 리포지토리는 반드시 Public(공개) 으로 설정해야 하고,Discussions기능을 활성화해야 합니다.
-
Giscus앱을 해당 리포지토리에 접근 권한을 부여 하기 위해Github에서 다음 경로로 접근하여 활성화해주세요.-
Repository > Settings > Integrations > GitHub Apps > giscus > Configure
-
Repository access 영역에서 Only select repository를 선택
-
방금 생성한 public repo my-giscus-comments를 선택해주세요.

-
-
-
2. 💻 PC에서 Quartz 프로젝트 초기화 및 Push
이제 제 PC에서 Quartz 공식 코드를 가져와서, 방금 만든 my-quartz-blog (Private) 리포지토리로 Push해줘야 합니다.
-
PC의 작업 폴더(예:
C:\Projects)로 이동합니다. -
Quartz 공식 리포지토리를
git clone받습니다.git clone https://github.com/jackyzha0/quartz.git -
다운로드한 폴더(
my-quartz-blog)로 이동한 뒤, 기존 Git 기록을 삭제합니다. (공식 리포지토리의 연결을 끊고 제 리포지토리에 새로 연결하기 위함입니다.)cd my-quartz-blog rmdir .git # Windows # rm -rf .git # macOS / Linux -
이 폴더를 새로운 Git 리포지토리로 초기화합니다.
git init -
Git 사용자 이름과 이메일을 설정합니다. (GitHub 계정과 동일하게)
git config user.name "Your-GitHub-Username" git config user.email "your-github-email@example.com" -
방금 만든 제 Private 리포지토리(
my-quartz-blog)를 원격(origin)으로 연결합니다.-
[Your_GitHub_ID]부분은 실제 GitHub ID로 변경해주세요.
git remote add origin git@github.com:[Your_GitHub_ID]/my-quartz-blog.git -
-
모든 파일을 스테이징하고 첫 커밋을이 data-repo, data-repo-id 등이 포함된 설정값을 알려줍니다.
<script src="[https://giscus.app/client.js] https://giscus.app/client.js)" data-repo="[ENTER REPO HERE]" data-repo-id="[ENTER REPO ID HERE]" data-category="[ENTER CATEGORY NAME HERE]" data-category-id="[ENTER CATEGORY ID HERE]" data-mapping="pathname" data-strict="0" data-reactions-enabled="1" data-emit-metadata="0" data-input-position="bottom" data-theme="preferred_color_scheme" data-lang="ko" crossorigin="anonymous" async> </script> -
PC에서 VS Code 같은 IDE(편집기)로
my-quartz-blog를 엽니다. -
quartz.layout.ts을 찾아 엽니다. -
Component.Footer()가 있는afterBody배열에, Giscus 컴포넌트 설정을 추가합니다. 7번에서 알려준 값들을 아래options에 맞게 넣어주세요.// quartz.layout.ts export const defaultContentPageLayout: PageLayout = { beforeBody: [ Component.Breadcrumbs(), Component.ArticleTitle(), Component.ContentMeta(), Component.TagList(), ], left: [ Component.PageTitle(), Component.MobileOnly(Component.Spacer()), Component.Search(), Component.Darkmode(), Component.DesktopOnly(Component.Explorer()), ], right: [ Component.Graph(), Component.DesktopOnly(Component.TableOfContents()), Component.Backlinks(), ], // afterBody에 Giscus 컴포넌트 추가 afterBody: [ Component.Spacer(), Component.Comments({ provider: 'giscus', options: { // 2단계에서 Giscus 사이트에서 받은 값들 repo: '[Your_GitHub_ID]/my-giscus-comments', // data-repo repoId: 'R_kgDOXXXXXX', // data-repo-id category: 'Announcements', // data-category categoryId: 'DIC_kwDOXXXXXX', // data-category-id } }), Component.Footer(), // Footer는 Giscus 뒤로 ], } -
수정이 완료되면 변경 사항을 다시 GitHub에 Push 합니다.
git add . git commit -m "Add Giscus comments feature" git push origin main
4. ☁️ Cloudflare Pages 배포
이제 Giscus까지 적용한 나만의 Quartz를 세상에 보여줄 차례입니다.
-
Cloudflare Pages대시보드로 이동하여Workers 및 Pages로 접근합니다.- 메뉴 > 컴퓨팅 및 AI > Workers 및 Pages
-
GitHub계정을 연결하고,my-quartz-blog(Private) 리포지토리를 선택합니다.- 이때 Cloudflare가 Private 리포지토리에 접근할 수 있도록 권한을 승인해 줘야 합니다.
-
빌드 설정을 구성합니다.
-
Project name: 원하는 주소 (예:
my-blog) -
Production branch:
main -
Framework preset:
None -
Build command:
npx quartz build -
Build output directory:
public -
(중요) Environment variables:
NODE_VERSION=22
-
-
‘저장 및 배포’ 버튼을 클릭합니다.
몇 분 정도 기다리면 Cloudflare가 GitHub에서 코드를 가져와 빌드하고, my-blog.pages.dev라는 주소로 블로그를 멋지게 배포해 줍니다. 1-Repo 방식이라 Submodule 설정 같은 복잡한 과정 없이 정말 간단하게 끝났습니다.
5. 🗄️ Synology NAS 자동 동기화 설정 (Cron)
가장 핵심적인 단계입니다. 제가 Obsidian에서 글을 쓰면, 시놀로지 NAS가 10분마다 이 변경 여부를 감지해 GitHub 리포지토리로 자동 git push 하도록 설정할 겁니다.
5-1. 필수 패키지 설치
-
시놀로지
패키지 센터에서Git Server를 설치합니다.- NAS에서 Git 명령어를 사용하기 위해 필요합니다.
5-2. NAS용 SSH 배포 키 생성
NAS가 GitHub Private 리포지토리에 암호 없이 git push를 하려면 SSH 키 인증이 필요합니다.
-
NAS에 SSH 접속
-
제어판 > 터미널 및 SNMP > SSH 서비스 활성화체크 -
터미널에서 NAS 관리자 계정으로 SSH 접속
ssh [NAS_Admin_ID]@[NAS_IP] -
-
user계정으로 접근 후 root로 전환 및 키 생성
# root로 전환하기 위한 관리자 암호 입력 sudo -i # SSH 키 생성 ssh-keygen -t rsa -b 4096 -C "quartz-deploy" # Enter 3번 눌러 암호 없이 기본 경로 `/root/.ssh/id_rsa`에 생성 -
공개 키 확인 및 복사
cat /root/.ssh/id_rsa.pubssh-rsa AAAA...로 시작하는 긴 키 문자열 전체를 복사합니다.
5-3. GitHub에 배포 키 등록
-
GitHub의
my-quartz-blog(Private) 리포지토리로 이동합니다. -
Settings > Deploy Keys > Add deploy key클릭-
Title:
Synology NAS(구분하기 쉬운 이름) -
Key: (5-2-3에서 복사한
ssh-rsa...공개 키 붙여넣기) -
✅ Allow write access (쓰기 권한 허용): 반드시 체크해야 합니다. (
git push에 필요)
-
5-4. NAS에 리포지토리 클론
이제 NAS의 SSH 터미널(root 상태)에서, Obsidian 볼트를 저장할 위치로 이동해 Private 리포지토리를 클론합니다.
-
(중요!)
git clone시 반드시 SSH 주소를 사용해야 배포 키가 작동합니다. -
경로는
home/{user_ID}와 동일한/volume1/homes/[Your_User_ID]입니다.
# [Your_User_ID]는 실제 사용자 ID로 변경
cd /volume1/homes/[Your_User_ID]
# [Your_GitHub_ID]는 GitHub ID로 변경
# "Obsidian_Quartz"라는 이름의 폴더로 클론됩니다.
git clone git@github.com:[Your_GitHub_ID]/my-quartz-blog.git Obsidian_Quartz5-5. Obsidian 볼트 연결
-
이제
/volume1/homes/[Your_User_ID]/Obsidian_Quartz폴더가 생겼습니다. -
PC나 모바일의 Obsidian 앱에서 리포지토리 폴더 안의
content폴더 (.../Obsidian_Quartz/content)를 볼트로 열어줍니다.- 이 폴더는 Synology Drive 등으로 동기화되어 있어야겠죠?
5-6. 자동 동기화 스크립트 생성
NAS의 root 홈 디렉터리에 자동 실행될 셸 스크립트를 생성합니다.
-
vi /root/quartz_sync.sh(vi 편집기 열기) -
i를 눌러 입력 모드로 변경 후, 아래 스크립트 내용을 붙여넣습니다.- (주의!)
[Your_User_ID]부분은 실제 사용자 ID로 꼭 변경해주세요.
- (주의!)
#!/bin/bash
set -ex # -e: 오류 시 즉시 중단, -x: 디버그 모드
cd /volume1/homes/[Your_User_ID]/Obsidian_Quartz || exit 1
echo "현재 위치: $(pwd)"
echo "Git 상태 확인 중..."
git status -s content
# 변경 사항이 없으면 종료
if [[ -z $(git status -s content) ]]; then
echo "변경 사항 없음 → 종료"
exit 0
fi
echo "변경 사항 발견 → 동기화 시작"
# pull을 하기 전에 로컬 변경 사항을 먼저 add/commit 합니다.
/usr/bin/git add content/
# 커밋 메시지: 일시
/usr/bin/git commit -m "Auto-sync: $(date +'%Y-%m-%d %H:%M:%S')" || true
# 로컬 커밋 이후에 pull --rebase를 실행합니다.
# 이렇게 하면 원격 변경 사항을 먼저 받고, 그 위에 방금 만든 로컬 커밋을 올립니다.
/usr/bin/git pull --rebase origin main
# 마지막으로 원격 저장소에 푸시합니다.
/usr/bin/git push origin main
echo "완료"-
ESC키 누르고:wq입력 후Enter(저장 및 종료) -
스크립트에 실행 권한 부여:
chmod +x /root/quartz_sync.sh
5-7. 시놀로지 작업 스케줄러 등록 (Cron 설정)
이것이 바로 Watcher를 대체하는 안정적인 Cron 설정입니다.
-
NAS
제어판 > 작업 스케줄러로 이동합니다. -
생성 > 예약된 작업 > 사용자 정의 스크립트클릭-
[일반] 탭:
-
작업:
Quartz 자동 배포(원하는 이름) -
사용자:
root(필수! root 권한으로 실행)
-
-
[스케줄] 탭:
-
다음 날짜에 실행:
매일 -
주기:
매 10분(또는 원하는 간격)
-
-
[작업 설정] 탭:
- 사용자 정의 스크립트:
bash /root/quartz_sync.sh
- 사용자 정의 스크립트:
-
확인을 눌러 저장합니다.
-
6. ✍️ 최종 워크플로우 확인
모든 설정이 완료되었습니다. 이제 저의 블로깅 워크플로우는 완벽하게 자동화되었습니다.
-
PC나 모바일의 Obsidian 앱에서 글을 작성하고 저장합니다.
- 이 볼트는 Synology Drive를 통해 NAS의
.../Obsidian_Quartz/content폴더와 실시간 동기화됩니다.
- 이 볼트는 Synology Drive를 통해 NAS의
-
NAS의
Obsidian_Quartz폴더에 파일 변경이 감지됩니다. -
최대 10분 이내에 ‘작업 스케줄러(Cron)‘가
quartz_sync.sh스크립트를 실행합니다. -
스크립트가
content폴더의 변경 사항을 감지하고, Private GitHub 리포지토리(my-quartz-blog)로git push를 실행합니다. -
Cloudflare Pages가 이
push이벤트를 즉시 감지합니다. -
Cloudflare가 자동으로
npx quartz build를 실행하여 사이트를 새로 빌드하고, 배포합니다.
graph RL subgraph "글 작성" A["Obsidian (PC/모바일)<br>글 작성 및 저장"] end subgraph "Synology NAS" B("Synology Drive<br>실시간 동기화") C["NAS 로컬 리포지토리<br>.../Obsidian_Quartz/content"] D("작업 스케줄러 (Cron)<br>10분마다 스크립트 실행") E{"변경 사항 감지<br>(quartz_sync.sh)"} end subgraph "Cloudflare" F["Private GitHub Repo<br>my-quartz-blog"] G("Cloudflare Pages<br>Push 감지 및 자동 빌드") H[("🌎<br>최종 블로그 배포")] end %% 워크플로우 연결 A --> B B --> C D --> E C -. "파일 변경" .-> E E -- "변경 사항 O" --> F(git push) E -- "변경 사항 X" --> I["종료"] F --> G("Push 트리거") G --> H
이제 Obsidian에서 글을 저장하는 것 외에는 아무것도 신경 쓸 필요가 없어졌습니다. 앞으로 성장 일기를 하나 하나 작성하려고 합니다. 많은 조언 부탁드립니다!
감사합니다