← Home

04_GuWiki 웹 공개 — Osync 시도 → Quartz+Caddy 채택 기록

Raw Source — Ingested (2026-07-31)

Claude Code 세션에서 진행한 인프라 구축 작업 기록. ## Original Content(작업 로그)는 원문 그대로 보존됨. 컴파일된 Wiki: Obsidian 볼트를 Cloudflare Pages로 웹 발행하기 (Guide), 정적 사이트 호스팅 아키텍처 선택 (Self-Host vs CDN) · PowerShell CLI 파이프의 BOM 오염 문제 (Concepts).

Update (2026-07-31, 같은 날 오후)

Osync 셀프호스팅은 중단하고 삭제했습니다. 실제 목적이 “여러 기기 간 비공개 동기화”가 아니라 **“04_GuWiki를 웹사이트로 공개해서 보기”**였다는 게 명확해져서, 제로지식 암호화 동기화 도구인 Osync 대신 Quartz(정적 사이트 생성기) + Caddy(Basic Auth) 조합으로 전환했습니다. 아래 ## Original Content는 두 파트로 나뉩니다 — Part 1(Osync, 폐기됨)은 향후 재설치 시 참고용으로 보존, Part 2(Quartz+Caddy, 현재 운영 중)가 실제 살아있는 구성입니다.

Update (2026-07-31, 밤)

자동화 + 상시 접속을 마무리했습니다. (1) 볼트 변경사항이 30분마다 자동으로 사이트에 반영되는 재빌드 작업(TAB-Wiki-Rebuild)을 등록했고, (2) 재부팅해도 cloudflared 튜널이 자동으로 살아나도록 로그온 트리거 작업(Cloudflared-Tunnel-AtLogon)을 추가했습니다 — 지금까지는 재부팅마다 Claude Code에게 “다시 띄워줘”라고 요청해야 했는데 이제 필요 없습니다. 자세한 내용은 아래 Part 3 참고. 이전 “다음에 할 일”의 공개 범위·Safe Browsing 항목도 사용자 확인으로 해소됐습니다.

Update (2026-07-31, 밤 늦게) — 아키텍처 재전환: 노트북 호스팅 → Cloudflare Pages

Part 3의 “로그온 시 cloudflared 자동 기동”은 재부팅에는 대응했지만, 노트북 자체가 꺼지거나(또는 자동 생성된 cloudflared CLI 창을 닫으면) 여전히 사이트가 죽는 근본적 한계가 있었습니다 (Error 1033 재현). 사용자가 “노트북 상태에 상관없이 항상 접속 가능”을 요구하면서, 사이트를 노트북 밖(Cloudflare Pages, 글로벌 CDN)으로 완전히 이전했습니다. Caddy·Docker·cloudflared tunnel·Cloudflared-Tunnel-AtLogon 작업은 모두 폐기됐고, TAB-Wiki-Rebuild만 남아 6시간마다 “빌드 + Pages 배포”를 수행합니다. 자세한 내용은 아래 Part 4 참고. Part 2/Part 3의 Caddy/Tunnel 관련 서술은 이제 과거 구성 기록으로만 유효합니다.


Capture Summary

FieldValue
Topic04_GuWiki Obsidian 볼트를 웹사이트로 발행 (turboairbrain.uk)
Tab group / window해당 없음 — Claude Code 세션 작업
PlatformsClaude Code (claude-sonnet-5)
Capture method세션 내 실행한 명령/결정 사항 수동 요약
Capture modesession-log
Collection purpose(3) 데이터 파이프라인/기술 구현
Captured at2026-07-31

현재 상태 — 정상 운영 중 (Cloudflare Pages, 노트북 독립적)

https://turboairbrain.uk — Cloudflare Pages에서 직접 서빙되는 정적 사이트로, Basic Auth(아이디/비밀번호)로 보호되고 내부 링크(위키링크 포함) 정상 작동 확인됨. 노트북이 꺼져 있어도, 켜져 있어도 항상 접속 가능 — 노트북은 6시간마다 최신 볼트 내용을 빌드해 Pages로 “배포”만 할 뿐, 사이트 자체를 서빙하지 않음.


Source Manifest

#PlatformTitleURLRoleCapture status
1Claude Code인프라 구축 세션 (Osync → Quartz 전환)—작업 수행 에이전트완료
2Osync (Community Plugin)Osync (Self-Hosted) 플러그인 문서https://community.obsidian.md/plugins/osync참고 문서 (결국 미채택)완료
3QuartzQuartz 4/5 공식 문서https://quartz.jzhao.xyz채택한 도구완료

Original Content

Source 1 — Claude Code 세션 작업 로그

Platform: Claude Code (claude-sonnet-5) 환경: Windows 11, PC 로컬호스트 셀프호스팅, 도메인 turboairbrain.uk (Cloudflare) Capture limitation: 스크린샷/대화 로그 기반 수동 요약 — 원본 대화 전체가 아닌 핵심 단계·결정·미해결 이슈 위주 정리


Part 1 — Osync 셀프호스팅 (시도 후 폐기, 2026-07-31)

이 파트는 현재 삭제된 구성입니다

아래는 나중에 Osync를 다시 설치할 때 참고용으로만 남겨둡니다. 실제 서버(Docker 컨테이너·볼륨)는 모두 삭제됐고, Cloudflare Tunnel 라우팅에서도 제거됐습니다.

1-1. 로컬 서버 구축

  1. WSL2 설치(wsl --install, 관리자 권한, 재부팅) → 완료
  2. Docker Desktop for Windows 설치(winget install --id Docker.DockerDesktop, 4.84.0)
  3. Osync 서버 구성 — 작업 폴더 C:\Users\David\osync-server\
    • docker-compose.yml을 공식 저장소(github.com/KORThomasJeong/Osync-p)에서 받아 로컬 접근용으로 수정: minio에 ports: "9000:9000" 추가, MINIO_SERVER_URL: ${MINIO_PUBLIC_URL} 추가
    • .env 시크릿은 openssl rand로 생성. 관리자 계정 David@turboairinc.com.au
    • ⚠️ 트러블슈팅: .env에 ADMIN_EMAIL/ADMIN_PASSWORD를 최초 생성 후 안 지우면 재시작 시 “User already exists” crash loop 발생 — 지워야 함

1-2. Cloudflare Tunnel로 외부 접근

  • cloudflared tunnel create osync → 터널 ID 010d961e-d8b6-40bf-8818-216ca4ade7b3 (이 터널은 Part 2에서도 재사용 중 — 삭제 안 됨)
  • osync.turboairbrain.uk, osync-s3.turboairbrain.uk 서브도메인 라우팅 — 현재는 config.yml에서 제거된 상태

1-3. 알려진 이슈: Chrome “위험한 사이트” 경고

  • Google Safe Browsing이 (신규 도메인) + (Cloudflare Tunnel) + (로그인 폼) 조합을 피싱으로 오탐 분류
  • 미해결로 남음 — Part 2(현재 사이트)에도 동일 증상이 재현되는지 확인 필요 (아래 “다음에 할 일” 참고)

1-4. 두 번째 사용자(Hwangyu Byeon) 볼트 공유 시도 — 미완료 상태로 중단

  • 관리자 대시보드에 볼트-그룹 공유 GUI가 없어서 Postgres DB를 직접 조사·수정하는 방식으로 우회 시도 중이었음
  • 스키마 파악 완료: organization(개인/그룹 조직) → vault(조직에 귀속) → vault_membership(볼트 단위 멤버십), vault.password 컬럼으로 클라이언트가 로컬에서 키를 유도하는 구조로 추정
  • vault_membership에 Hwangyu 행 INSERT까지는 성공했으나, 볼트가 David 개인 조직 소속이라 여전히 안 보이는 문제 확인 → UPDATE vault SET organization_id = ...(TAB_Group으로 이전) 제안까지 하고 실행 결과 미확인 상태에서 Osync 자체를 폐기
  • DB 스키마 지식은 재사용 가치 있음 — 나중에 Osync 재설치 시 이 조사 내용부터 시작하면 시행착오를 줄일 수 있음

1-5. Osync 삭제 작업 (2026-07-31)

# Docker: 컨테이너 3개 + 볼륨 3개 + 네트워크 완전 삭제
cd C:\Users\David\osync-server
docker compose down -v
  • Cloudflare Tunnel config.yml에서 osync.*, osync-s3.* ingress 규칙 제거 (터널 자체는 유지, Part 2에서 재사용)
  • DNS 레코드는 미삭제 상태로 남음 — osync, osync-s3 CNAME이 Cloudflare 대시보드에 아직 존재 (기능적으로는 죽어있음, 청소는 선택사항)

Part 2 — Quartz + Caddy 정적 사이트 (현재 운영 중)

2-1. 목표 재정의

  • 실제 니즈는 “여러 기기 비공개 동기화”가 아니라 “04_GuWiki를 웹페이지로 발행해서 보기”
  • 도구 선택: Quartz(github.com/jackyzha0/quartz) — Obsidian 문법(위키링크·백링크·그래프뷰·태그)을 그대로 이해하는 정적 사이트 생성기, 무료·오픈소스
  • 보호 방식: 전체 공개하되 Caddy의 HTTP Basic Auth로 로그인 게이트 — Quartz 자체의 encrypted-pages 플러그인(페이지별 password frontmatter)은 파일 104개 전부 수정해야 해서 미채택

2-2. Quartz 설치·빌드

# 사전준비: Node.js LTS 설치
winget install --id OpenJS.NodeJS.LTS   # v24.18.1
 
# Quartz 클론 + 의존성 설치
git clone https://github.com/jackyzha0/quartz.git C:\Users\David\quartz-site
cd C:\Users\David\quartz-site
npm install
  • content/ 폴더에 04_GuWiki 전체를 복사(robocopy, /MIR 미러 모드로 최신 상태 유지):
    robocopy "C:\Users\David\Desktop\Vaults\04_GuWiki" "C:\Users\David\quartz-site\content" /E /MIR /XD ".git" ".obsidian" ".claude" ".codex" ".agents" "node_modules" /XF ".gitignore"
    • 제외한 것: .git, .obsidian, .claude, .codex, .agents(하네스/설정 폴더)
    • 포함한 것: 나머지 전부 — 00. Inbox~90. Settings, CLAUDE.md, AGENTS.md, log.md 등 최상위 문서까지 전부 (⚠️ 아래 “다음에 할 일” 참고 — 공개 범위 재검토 필요)
  • quartz.config.default.yaml 수정: pageTitle: TAB Project Wiki, baseUrl: turboairbrain.uk, locale: ko-KR
  • 빌드:
    npx quartz build   # content/ → public/ (104개 md → 735개 정적 파일)
    • LaTeX 플러그인이 가격 표기의 $ 기호를 수식 기호로 오인식해 경고 다수 발생 — 무해함, 무시

2-3. Caddy로 서빙 + Basic Auth

  • 비밀번호 생성 및 bcrypt 해시:
    docker run --rm caddy:latest caddy hash-password --plaintext "<비밀번호>"
  • C:\Users\David\quartz-site\Caddyfile:
    :8080 {
    	root * /srv
    	basic_auth {
    		david <bcrypt 해시>
    	}
    	try_files {path} {path}.html {path}/index.html /404.html
    	file_server
    }
    
    • ⚠️ 트러블슈팅: 처음엔 try_files 없이 file_server만 넣었더니, Quartz가 만드는 확장자 없는 “깔끔한 URL”(/폴더/파일명, 실제 파일은 파일명.html)을 Caddy가 못 찾아서 모든 내부 링크가 404가 남. try_files {path} {path}.html {path}/index.html 추가로 해결.
  • C:\Users\David\quartz-site\docker-compose.yml: Caddy 컨테이너(tab-wiki-web)가 ./public을 /srv로 마운트, 8080:8080 포트 노출

2-4. Cloudflare Tunnel 라우팅

  • 기존 osync 터널(ID 010d961e-...)을 재사용, 루트 도메인 추가:
    cloudflared tunnel route dns osync turboairbrain.uk
  • C:\Users\David\.cloudflared\config.yml — 최종본:
    tunnel: 010d961e-d8b6-40bf-8818-216ca4ade7b3
    credentials-file: C:\Users\David\.cloudflared\010d961e-d8b6-40bf-8818-216ca4ade7b3.json
    ingress:
      - hostname: turboairbrain.uk
        service: http://localhost:8080
      - service: http_status:404

2-5. ⚠️ 트러블슈팅: cloudflared Windows 서비스가 계속 멈춤

  • cloudflared service install로 등록한 Windows 서비스가 재부팅/재시작 시마다 “StopPending” 상태로 멈추는 문제가 3회 반복 — Restart-Service, Stop-Service -Force도 먹통이 되는 경우 있었음
  • 최종 결정: Windows 서비스 방식을 포기 (cloudflared service uninstall) 하고, Claude Code가 run_in_background로 직접 띄우는 방식으로 전환. 안정적으로 작동 확인됨.
  • 트레이드오프: PC 재부팅 시 자동으로 안 뜸 — 재부팅 후 매번 “이어서 해줘”라고 요청하면 다시 띄워줌. 완전 자동화하려면 Windows 작업 스케줄러(Task Scheduler)로 로그온 시 실행 트리거를 만드는 게 서비스보다 나을 수 있음(미시도).

Part 3 — 자동화: 주기적 재빌드 + 상시 접속 확보 (2026-07-31, 밤)

배경

Part 2까지는 “지금 접속 가능한 상태”만 만든 것이었고, 두 가지가 수동이었다: (1) 볼트 내용이 바뀌어도 사이트에 반영하려면 매번 robocopy+build를 직접 실행해야 했고, (2) cloudflared는 Claude Code가 run_in_background로 띄운 프로세스라 재부팅하면 사라졌다 — 실제로 재부팅 후 turboairbrain.uk 접속 불가 상태가 재현됨.

3-1. 주기적 자동 재빌드 (사용자가 “주기적 자동 재빌드” 방식을 명시적으로 선택 — 실시간 watcher 아님)

  • C:\Users\David\quartz-site\rebuild-site.ps1 작성: robocopy /MIR로 vault → content/ 동기화 후 npx quartz build
    • ⚠️ 트러블슈팅: -replace 이스케이핑 오류 → -split " r? n" 방식으로 교체
    • ⚠️ 트러블슈팅: Quartz가 LaTeX $ 기호 경고를 stderr로 뱉는데 $ErrorActionPreference = "Stop"이 이를 치명적 오류로 취급해 스크립트가 중단됨 → build 구간만 로컬로 "Continue"로 낮추고 $LASTEXITCODE로 직접 성공 여부 판단하도록 수정
  • Windows 작업 스케줄러에 “TAB-Wiki-Rebuild” 등록: New-ScheduledTaskTrigger -Once -RepetitionInterval (30분) -RepetitionDuration (10년)
    • ⚠️ 트러블슈팅: New-ScheduledTaskSettingsSet의 배터리 관련 파라미터 이름을 두 번 잘못 씀(AllowStartIfOnBattery, -DisallowStartIfOnBatteries) → (Get-Command New-ScheduledTaskSettingsSet).Parameters.Keys로 실제 이름 확인 후 AllowStartIfOnBatteries로 수정
    • ⚠️ 트러블슈팅: RepetitionDuration에 [TimeSpan]::MaxValue를 넣었더니 Register-ScheduledTask가 값이 너무 크다고 거부 → (New-TimeSpan -Days 3650)(약 10년)로 교체
    • 검증: Start-ScheduledTask로 수동 실행 → rebuild.log에서 Build exit code: 0 확인

3-2. cloudflared 상시 접속 확보 (재부팅 대응)

  • Part 2(2-5)에서 Windows 서비스 방식(cloudflared service install)이 StopPending에 반복적으로 멈춰서 포기하고 Claude Code가 직접 띄우는 방식으로 임시 전환했었는데, 이 방식은 재부팅 시 사라진다는 게 실제로 재현됨 (재부팅 후 접속 불가 → 이 세션에서 복구 작업 진행)
  • 해결 방향: Windows 서비스가 아니라 **작업 스케줄러(로그온 트리거)**로 우회 — TAB-Wiki-Rebuild가 이미 안정적으로 동작하는 걸 확인했으므로 같은 패턴을 재사용
  • C:\Users\David\quartz-site\start-tunnel.ps1 신규 작성:
    • 이미 cloudflared 프로세스가 떠 있으면 중복 실행하지 않고 종료 (로그에 Skipped 기록)
    • 없으면 무한 루프로 cloudflared tunnel run osync 실행 → 프로세스가 죽으면 5초 후 자동 재시작 (네트워크 순단 등에도 스스로 복구)
    • 로그: C:\Users\David\.cloudflared\tunnel-run.log
  • Windows 작업 스케줄러에 “Cloudflared-Tunnel-AtLogon” 등록: New-ScheduledTaskTrigger -AtLogOn, -RunLevel Limited
    • ⚠️ 트러블슈팅: Claude Code가 쓰는 PowerShell 세션(관리자 아님, 비대화형에 가까운 제한된 토큰)에서는 Register-ScheduledTask가 AtLogOn 트리거일 때만 Access is denied 발생 (같은 세션에서 Once+반복 트리거인 TAB-Wiki-Rebuild는 문제없이 성공했었음). schtasks.exe로 재시도해도 동일하게 거부됨 → 사용자가 직접 관리자 권한 PowerShell 창에서 등록 스크립트를 실행해서 해결
    • 검증: 수동으로 띄워둔 cloudflared 프로세스를 강제 종료한 뒤 Start-ScheduledTask로 작업만으로 재기동시킴 (새 PID로 정상 기동, “Registered tunnel connection” 로그 확인) → https://turboairbrain.uk/가 무인증 401 / Basic Auth 인증 200 모두 정상 응답
    • 참고: 작업 스케줄러 컨텍스트에서 실행되면 로그 파일에 한글이 mojibake(깨진 문자)로 기록됨 — rebuild.log에서도 동일 현상 재확인. 화면상 문제일 뿐 실제 빌드/튜널 동작에는 영향 없음

3-3. 남은 결정사항 확정 (사용자 확인, 2026-07-31 밤)

  • 공개 범위: 05_재무, 07_인사를 포함해 전체 공개 유지하기로 결정 — 애초 계획대로 사이트 비밀번호는 사장님과 Nathan 매니저에게만 공유할 예정이라 문제 없음. robocopy 제외 목록 변경 불필요.
  • Safe Browsing: 새 루트 도메인(turboairbrain.uk)은 Chrome 위험 사이트 경고가 뜨지 않음 확인 — Osync 시절 osync.* 서브도메인에서 겪었던 오탐(Part 1, 1-3)이 재현되지 않았음. Search Console 조치 불필요.

Part 4 — Cloudflare Pages로 완전 이전: 노트북 독립적 호스팅 (2026-07-31, 밤 늦게)

배경 — Part 3로는 부족했던 이유

Part 3(작업 스케줄러 기반 자동화)는 “재부팅”에는 대응했지만, 사용자가 실제로 경험한 문제는 그보다 근본적이었다: cloudflared가 로그온 시 자동 생성하는 CLI 창을 사용자가 닫으면, 그 프로세스가 죽으면서 사이트 전체가 다운됨 (Error 1033 “Cloudflare Tunnel error” 재현). 근본 원인은 아키텍처 자체 — turboairbrain.uk가 사용자의 노트북을 origin 서버로 쓰는 Tunnel 구조였기 때문에, 노트북이 꺼지거나 tunnel 프로세스가 죽으면 Cloudflare가 연결할 origin이 사라진다. “노트북 상태에 상관없이 항상 접속 가능”은 작업 스케줄러로는 원천적으로 불가능한 요구사항이었다.

4-1. 방향 결정

  • 옵션 비교: (a) Cloudflare Pages(정적 파일을 CDN에 직접 업로드, 노트북 불필요) — 채택, (b) 별도 VPS에 기존 Docker+Caddy 구성 이전 — 더 복잡·유료, (c) 현재 구조 유지 + 노트북 항상 켜두기 — 원 요구사항 미충족
  • Quartz가 이미 완전 정적 사이트(public/)를 만들고 있었으므로 Cloudflare Pages가 자연스러운 선택 — 같은 Cloudflare 계정/도메인 재사용, 무료, Caddy·Docker·cloudflared tunnel 전부 불필요해짐

4-2. Cloudflare Pages 프로젝트 생성 + 배포

# wrangler(Cloudflare CLI)는 npx로 즉시 사용 가능, 별도 설치 불필요
npx wrangler login          # 브라우저 OAuth 승인 필요 (사용자가 직접 Allow 클릭)
npx wrangler pages project create turboairbrain-wiki --production-branch=main
npx wrangler pages deploy public --project-name=turboairbrain-wiki --branch=main --commit-dirty=true
  • 첫 배포는 https://turboairbrain-wiki.pages.dev에서 즉시 확인 가능 (734개 정적 파일 업로드)
  • Quartz의 확장자 없는 “클린 URL”을 Pages가 자체적으로 처리 — Caddy의 try_files 트릭이 더 이상 필요 없음 (.html 요청 시 자동으로 308 리다이렉트까지 해줌, 오히려 이전보다 더 매끄러움)

4-3. Basic Auth 재구현 (Cloudflare Pages Functions)

  • Pages는 Caddy 같은 서버 설정 파일이 없으므로, C:\Users\David\quartz-site\functions\_middleware.js로 모든 요청을 가로채는 미들웨어를 작성해 Basic Auth를 직접 구현 (Authorization 헤더 검사, 불일치 시 401 + WWW-Authenticate 헤더)
  • 자격증명은 코드에 하드코딩하지 않고 Pages Secret으로 분리:
    "david" | npx wrangler pages secret put BASIC_AUTH_USER --project-name=turboairbrain-wiki
    "5Pq8tzYCrwRD7WdE" | npx wrangler pages secret put BASIC_AUTH_PASS --project-name=turboairbrain-wiki
    • 기존 Caddy Basic Auth와 동일한 아이디/비밀번호(david / 5Pq8tzYCrwRD7WdE)를 재사용해 사장님·Nathan 매니저 공유 계획에 변경이 없도록 함
  • ⚠️ 트러블슈팅 (재사용 가치 높은 패턴): PowerShell 파이프("david" | wrangler pages secret put ...)로 넘긴 값 앞에 UTF-8 BOM(U+FEFF)이 몰래 붙어서 정확한 비밀번호를 입력해도 계속 401이 나는 문제 발생. 미들웨어에 디버그 응답을 임시로 붙여서 expectedUser="\ufeffdavid"처럼 BOM이 섞인 걸 확인 후 진단. 해결: 재설정 대신 미들웨어 코드에서 env 값의 선행 BOM을 정규식으로 제거(.replace(/^\ufeff/, ""))하는 방어 코드 추가 — Windows PowerShell → CLI stdin 파이프 전반에 재발 가능한 함정이므로 기억해둘 것

4-4. 커스텀 도메인 연결 (turboairbrain.uk → Pages)

  • wrangler CLI에는 Pages 커스텀 도메인 관리 명령이 없음(wrangler pages domain add 같은 건 존재하지 않음, Unknown arguments 에러) → Cloudflare REST API를 wrangler의 저장된 OAuth 토큰(C:\Users\David\AppData\Roaming\xdg.config\.wrangler\config\default.toml)으로 직접 호출해서 처리:
    POST /accounts/{account_id}/pages/projects/turboairbrain-wiki/domains
    Body: {"name": "turboairbrain.uk"}
    
  • 이 토큰은 pages:write 스코프는 있지만 dns_records 스코프가 없어서 DNS 레코드 자체는 API로 못 건드림 → DNS 레코드 수정만 사용자가 대시보드에서 직접 진행: 기존 turboairbrain.uk CNAME(터널 주소)을 turboairbrain-wiki.pages.dev로 Edit, Proxied 유지
  • 처음엔 Pages 쪽이 “CNAME record not set”이라며 522 에러가 났으나, DNS 레코드 저장 후 곧바로 정상화 확인 (전파 지연 없이 즉시 반영됨)

4-5. 재빌드 스크립트에 배포 단계 추가

  • rebuild-site.ps1의 npx quartz build 뒤에 npx wrangler pages deploy public --project-name=turboairbrain-wiki --branch=main --commit-dirty=true 추가 — 이제 “동기화 → 빌드 → Pages 배포” 3단계가 한 번에 자동 실행됨 (6시간 간격, TAB-Wiki-Rebuild 작업 그대로 재사용)
  • 검증: Start-ScheduledTask로 수동 트리거 → 로그에서 Build exit code: 0 → Deploy exit code: 0 → === Rebuild + deploy completed successfully === 순서로 확인

4-6. 구인프라 폐기

  • Docker: docker compose down — tab-wiki-web 컨테이너 + 네트워크 제거 (Caddyfile/docker-compose.yml 파일 자체는 참고용으로 남겨둠, 삭제 안 함)
  • Windows 작업 스케줄러: Cloudflared-Tunnel-AtLogon 작업 삭제 (Unregister-ScheduledTask) — 이 역시 관리자 권한 필요해서 사용자가 직접 실행
  • cloudflared 프로세스: 이미 사용자가 CLI 창을 닫아서 종료된 상태 — 별도 조치 불필요
  • 남기는 것: Cloudflare Tunnel 객체(010d961e-..., 이름 osync) 자체와 .cloudflared/config.yml은 삭제하지 않음 — 당장 안 쓰지만 삭제할 이유도 없음(비용 없음)
  • 최종 구조: 04_GuWiki 볼트 (노트북, 6시간마다 빌드+배포만 담당) → Cloudflare Pages (상시 서빙, 노트북 무관) ← turboairbrain.uk (DNS, Cloudflare)

참고용 값 모음 (다음 세션에서 재사용)

아래 표는 최신 상태(Cloudflare Pages) 기준입니다

Caddy/Docker/cloudflared tunnel 관련 값(Part 2·3)은 이제 폐기된 구성입니다 — 재참고용으로만 남겨두고 “폐기” 표시.

항목값
사이트 주소https://turboairbrain.uk (실제 서빙: Cloudflare Pages)
Basic Auth 아이디david
Basic Auth 비밀번호5Pq8tzYCrwRD7WdE (Pages Secret BASIC_AUTH_USER/BASIC_AUTH_PASS로 저장, 코드엔 없음 — 이 평문은 이 노트가 유일한 기록이니 분실 주의)
공유 대상사장님, Nathan 매니저 (계획대로 — 그 외 비공개)
Cloudflare Pages 프로젝트turboairbrain-wiki (기본 도메인 turboairbrain-wiki.pages.dev, 커스텀 도메인 turboairbrain.uk)
Basic Auth 구현C:\Users\David\quartz-site\functions\_middleware.js (Pages Functions)
Quartz 프로젝트 경로C:\Users\David\quartz-site\
Quartz content 소스C:\Users\David\Desktop\Vaults\04_GuWiki (robocopy /MIR로 단방향 미러)
재빌드+배포 스크립트C:\Users\David\quartz-site\rebuild-site.ps1 (로그: quartz-site\rebuild.log) — 동기화→빌드→Pages 배포 3단계
재빌드 작업 스케줄러TAB-Wiki-Rebuild — 매일 06:00부터 6시간 간격(06/12/18/24시), 무기한 반복
wrangler 인증david@turboairinc.com.au OAuth 로그인 완료, 토큰 위치 AppData\Roaming\xdg.config\.wrangler\config\default.toml
(폐기) Caddy 컨테이너/composeC:\Users\David\quartz-site\docker-compose.yml (컨테이너명 tab-wiki-web, 중지·삭제됨)
(폐기) 튜널 기동 스크립트/작업start-tunnel.ps1 + Cloudflared-Tunnel-AtLogon 작업 스케줄러 (작업은 삭제됨, 스크립트 파일은 참고용으로 남음)
(유지, 미사용) Cloudflare Tunnel ID010d961e-d8b6-40bf-8818-216ca4ade7b3 (이름: osync) — 삭제는 안 했지만 더 이상 라우팅 안 됨
(폐기) Osync Vault/User/Org ID필요 시 이 문서의 이전 버전(git 이력 또는 백업) 참고 — 재설치 시에만 유효

Agent Capture Notes

Topic Summary

04_GuWiki를 다중 기기에서 보기 위해 처음엔 Osync(제로지식 암호화 동기화)를 셀프호스팅했으나, 실제 목적이 “웹사이트로 공개해서 보기”에 더 가깝다는 게 드러나 Quartz(정적 사이트 생성) + Caddy(Basic Auth) 조합으로 전환했다. Osync 인프라는 완전히 삭제했고, 같은 Cloudflare Tunnel을 재사용해 turboairbrain.uk 루트 도메인에 위키 전체를 발행했다. 링크 404 버그(Caddy try_files 누락)와 cloudflared Windows 서비스 불안정 문제를 해결한 뒤 작업 스케줄러 기반 자동화(30분→6시간 재빌드, 로그온 시 cloudflared 자동 기동)를 추가했지만, 노트북이 꺼지거나 cloudflared CLI 창이 닫히면 사이트 전체가 죽는 구조적 한계가 드러났다. 최종적으로 Cloudflare Pages로 완전히 이전해 사이트를 노트북과 무관하게 CDN에서 직접 서빙하도록 재구성했고(Basic Auth는 Pages Functions 미들웨어로 재구현), 로컬 Caddy·Docker·cloudflared tunnel 인프라는 전부 폐기했다. 이제 노트북은 6시간마다 “빌드 후 Pages에 배포”하는 역할만 한다.

Key Claims By Platform

  • Claude Code: Osync 폐기 후 Quartz+Caddy로 전체 재구축, try_files 누락으로 인한 링크 404 진단·수정, Windows 서비스 반복 장애를 백그라운드 프로세스 방식으로 우회.
  • Quartz 공식 문서: Obsidian 볼트를 그대로 웹사이트로 변환하는 정적 사이트 생성기 — wikilink/backlink/graph view/search 네이티브 지원, encrypted-pages 등 자체 인증 플러그인도 존재하나 이번엔 미채택.

Agreements And Disagreements

  • (Part 1에서 이미 기록) Osync 공식 문서의 “그룹 간 볼트 공유” 설명과 실제 admin UI 간 불일치 — 근본 원인 미확정 상태로 남음, Osync 재설치 시 재확인 필요.

Source URLs Mentioned

Evidence Gaps

  • cloudflared Windows 서비스가 왜 반복적으로 StopPending에 멈추는지, Claude Code의 PowerShell 세션이 왜 Register-ScheduledTask의 AtLogOn 트리거에서만 Access denied가 나는지는 끝내 미규명 — 다만 Part 4에서 cloudflared tunnel 자체를 폐기했으므로 더 이상 실질적 영향은 없음 (기록으로만 보존)
  • Cloudflare Pages custom domain 연결 시 왜 REST API로는 도메인 등록까지만 되고 DNS 레코드 자동 생성은 안 됐는지(같은 계정/zone인데도) 명확한 원인 불명 — wrangler OAuth 토큰의 스코프에 dns_records가 없다는 사실 자체는 확인했지만, Pages가 zone 소유 확인 후에도 자동으로 레코드를 안 만들어주는 게 의도된 동작인지는 미확인

Suggested Wiki Targets

  • 20. Wiki/23. Guides/ — “Obsidian 볼트를 Cloudflare Pages + Pages Functions(Basic Auth)로 웹 발행하기” 가이드로 컴파일 가치 있음 (Caddy+Tunnel 방식은 폐기됐으므로 최신 절차로 컴파일)
  • 20. Wiki/21. Concepts/ — “정적 사이트 생성 vs 제로지식 동기화” 개념 비교(왜 Osync 대신 Quartz를 택했는지) + “노트북 self-host vs CDN 이전” 의사결정 기록(왜 Tunnel 방식에서 Pages로 다시 전환했는지)

다음에 할 일 (Next Steps)

해소된 항목 (2026-07-31 밤 기준, Part 3까지)

  • 공개 범위 재검토 — 사용자 확인: 05_재무/07_인사 포함 전체 공개 유지 (비밀번호는 사장님·Nathan 매니저에게만 공유 예정이라 문제 없음)
  • Safe Browsing 경고 확인 — 새 루트 도메인은 경고 없음 확인
  • 재발행 자동화 — TAB-Wiki-Rebuild 작업 스케줄러로 자동화 (현재 6시간 간격)

해소된 항목 (2026-07-31 밤 늦게, Part 4)

  • 노트북 상태와 무관한 상시 접속 — Cloudflare Pages 이전으로 완전 해결 (Cloudflared-Tunnel-AtLogon 방식은 재부팅에만 대응했지, 노트북 꺼짐/창 닫힘엔 무력했음)
  • 재빌드 시 Pages 배포 자동화 — rebuild-site.ps1에 wrangler pages deploy 단계 추가로 해결
  • Basic Auth 유지 — Pages Functions 미들웨어로 동일 자격증명 재구현
  1. 안 쓰는 osync, osync-s3 DNS CNAME 레코드 Cloudflare 대시보드에서 삭제 (선택, 기능엔 무관 — cloudflared CLI로는 삭제 불가, 대시보드에서만 가능). 같은 김에 이제 안 쓰는 Cloudflare Tunnel 객체(osync)도 정리할지 판단
  2. (선택) Osync는 이번 조사로 얻은 DB 스키마 지식을 갖고 나중에 재설치 — 다중 기기 “비공개 동기화”가 실제로 필요해지면 이 문서의 Part 1을 출발점으로 사용
  3. (선택) 위 “Suggested Wiki Targets” 참고해 /ingest 진행 시 Guide/Concept 페이지로 컴파일 — 최신 아키텍처(Pages) 기준으로 작성할 것, Caddy/Tunnel 절차는 역사적 기록으로만 남기기
  4. (선택) functions/_middleware.js의 BOM 스트립 트러블슈팅은 Windows PowerShell → CLI 도구 전반에 재발 가능한 패턴이므로, 별도 Wiki Concept(“PowerShell 파이프 → stdin 값에 BOM이 섞이는 문제”)로 승격할 가치 있음

Ingest Notes