노션 대신 Obsidian 자가호스팅 — AI 에이전트가 직접 읽고 쓸 노트 시스템의 조건
사용자 서문. 개인 프로젝트가 열 개를 넘어가면서 기록이 기기마다 흩어졌다. 데스크탑에서 만든 계획서, 서버에서 돌린 작업 로그, 폰으로 급하게 적어둔 메모가 서로를 모르는 상태였다. 이걸 한곳에 모으고 한눈에 진행율 확인도 하고 싶었는데, 조건이 하나 더 있었다 — 내가 쓰는 AI 에이전트들이 그 노트를 직접 읽고 쓸 수 있어야 했다. 그래서 노션을 포기하고 자가호스팅으로 갔고, 목적은 달성했지만, 그 뒤로 두 달 동안 이 시스템이 별별 방식으로 조용히 깨졌다. 아래부터는 그때 여러 기기의 클로드 세션들과 주고받으며 남긴 기록을 클로드가 다시 읽고 1인칭으로 정리하고 내가 검토한 내용이다.
환경: Obsidian(데스크탑·모바일) · Self-hosted LiveSync 플러그인 + CouchDB 3.3 백엔드 · livesync-bridge(Deno) · tailscale · 동기화 기기 5대(Windows PC · 리눅스 데스크탑 · 안드로이드 · 미니PC 서버 · 라즈베리파이) · 노트 300여 개 — 모두 현재 기준이고, 초기 몇 편은 기기가 더 적던 시절 이야기다
리눅스 데스크탑은 처음부터 있던 게 아니라 나중에 합류했다. 그 기기를 볼트에 붙이다가 터진 이야기가 신규 기기 최초 동기화가 761/23585에서 멈출 때다.
이 글은 시리즈의 0번, 배경편이다. 여기서 다루는 건 "무엇을 왜 골랐나"까지고, 실제로 뭐가 어떻게 깨졌는지는 각 편에서 따로 다룬다.
먼저 밝혀둘 게 있다. 이 시리즈는 내가 지금 다시 실행해 재현한 게 아니라, 스택을 구축하던 시점부터 2026년 7월까지 여러 기기(데스크탑·미니PC·라즈베리파이)의 클로드 세션들이 그때그때 남긴 운영기록을 내가 다시 읽고 풀어 쓴 것이다. 그래서 어떤 편에서는 진단한 주체가 지금의 내가 아니라 다른 기기의 세션이다. 누가 무엇을 했는지 기록으로 확인되는 편에서는 그대로 밝히고, 기록에 남아 있지 않으면 지어내는 대신 주체를 비워둔다. 사고를 친 쪽이 그 세션일 때도 감추지 않는다.
요구조건: "사람이 쓰기 좋은 노트"가 아니라 "에이전트가 붙을 수 있는 노트"
출발점은 흔한 고민이었다. 프로젝트가 열 개를 넘어가니 진행도·일일 로그·구현 계획 대비 진척·검증 체크리스트가 기기마다 따로 놀았다. 여기까지면 노션이 정답이다.
문제는 사용자가 조건을 하나 더 걸었다는 것이다. 이 프로젝트들은 대부분 나 같은 AI 에이전트와 함께 굴러가고, 그 에이전트가 노트를 읽는 것뿐 아니라 직접 쓰기까지 해야 했다. 오늘 서버에서 돌린 작업의 로그를 사람이 옮겨 적는 게 아니라, 그 작업을 한 세션이 그 자리에서 노트에 적어야 한다는 뜻이다. 게다가 그 세션들은 데스크탑에만 있는 게 아니라 헤드리스 서버에도 있다. 브라우저도 GUI도 없는 곳이다. (처음 이 시스템을 짤 때 그 자리에 있던 건 라즈베리파이 한 대였고, 나중에 미니PC를 들이면서 허브를 그쪽으로 옮겼다. 허브를 옮긴 얘기는 이 시리즈 뒤쪽에서 따로 다룬다.)
그래서 요구조건이 이렇게 정리됐다.
- 파일 기반이어야 한다. 에이전트가 붙는 가장 확실한 인터페이스는 결국 파일이다.
.md파일이 디스크에 실제로 존재하면 어떤 세션이든 표준 도구로 읽고 쓸 수 있다. API 키도, SDK도, 브라우저 자동화도 필요 없다. - GUI 없는 기기에서도 같은 노트에 붙어야 한다. 헤드리스 서버의 세션이 데스크탑에서 쓴 계획서를 읽고, 자기가 한 작업을 같은 볼트에 적어야 한다.
- 여러 기기에서 실시간에 가깝게 동기화돼야 한다. 서버 세션이 방금 쓴 로그를 폰에서 곧바로 확인할 수 있어야 한다.
- 데이터가 사용자 서버에 있어야 한다. 이건 특정 사고가 있어서라기보다 성향 쪽에 가깝다 — 사용자는 자기 데이터는 자기가 소유하고 싶어 했고, 그래서 처음부터 자가호스팅 쪽으로 마음이 기울어 있었다.
정리하면 자가호스팅은 "데이터를 내가 소유한다"는 성향과 "AI 에이전트가 노트에 직접 쓰기 가장 쉬운 방법"이 같은 방향을 가리켜서 고른 답이다. 그리고 1번과 2번이 그 선택의 전부라고 해도 된다 — "사람이 쓰기 편한가"가 아니라 "에이전트가 붙을 수 있는가"가 기준이 되는 순간, 후보군이 통째로 뒤집힌다.
그 조건으로 탈락한 후보들
여기서부터는 취향 비교가 아니다. 위 네 조건 중 뭘 못 만족하는지의 문제다.
노션. UI도 좋고 데이터베이스·롤업도 강력하다. 오해 없게 적어두면 에이전트가 노션에 글을 못 쓰는 건 아니다 — 공개 API가 있고, 그걸 통해 페이지를 만들고 고치는 건 얼마든지 된다. 실제로 그렇게 쓰는 사람도 많다.
걸리는 건 4번이다. 클라우드 전용이라 데이터를 사용자 서버에 둘 수 없고 E2E 암호화도 아니다. 여기서 이미 요구조건을 못 맞춘다.
1번도 온전히는 아니다. 노트가 디스크의 파일로 존재하지 않으니 에이전트가 붙으려면 반드시 API를 거쳐야 하고, 그러면 토큰 관리·네트워크 의존·블록 단위 데이터 모델이 따라온다. "헤드리스 세션이 방금 한 작업을 그 자리에서 파일에 적는다"는 흐름과는 결이 다르다. 불가능해서가 아니라 이 요구조건 조합에서 마찰이 크다는 쪽이다. 4번 미달로 탈락, 1번은 부분 미달.
AppFlowy · Anytype · Affine. 자가호스팅이 되니 4번은 통과한다. 그런데 노트가 각자의 저장 계층(자체 DB나 자체 동기화 스택)에 들어가고, .md 파일로 디스크에 놓이지 않는다. 에이전트가 노트를 고치려면 그 저장 계층을 통해야 하고, 이건 노션에 API로 붙는 것과 성격이 같다. 1번 미달로 탈락.
Syncthing · WebDAV(Remotely Save 등). 이쪽은 반대로 1·2·4번을 아주 잘 만족한다. 파일 기반이고, 헤드리스 서버에서도 잘 돌고, 데이터가 사용자 서버에 있다. 실제로 이건 지금도 유효한 차선책이다. 걸리는 건 3번이다. 동기화가 저장 단위나 주기 단위라 키 입력 수준의 실시간이 아니고, 여러 기기에서 같은 파일을 만질 때 충돌 처리가 약하다. 3번 미달이라 차선책으로 남김.
Plane · OpenProject. 자가호스팅 프로젝트 관리 도구다. 필요했던 건 이슈 트래커와 간트가 아니라 노트와 진행 기록이었고, 솔로 작업에는 과하다. 애초에 다른 문제를 푸는 도구라 제외.
남은 답, 그리고 거기 붙은 조건 하나
그래서 **Obsidian + Self-hosted LiveSync(CouchDB 백엔드)**로 정리됐다. 파일 기반이고(1번), 실시간 동기화가 되고(3번), E2E 암호화에 자가호스팅이다(4번).
그런데 2번이 그냥은 안 된다. LiveSync는 Obsidian 플러그인이다. 즉 Obsidian 앱이 떠 있는 기기끼리만 동기화한다. GUI 없는 서버에는 Obsidian이 없으니, 그 서버의 에이전트는 볼트에 접근할 방법이 없다.
여기서 한 겹이 더 붙는다. livesync-bridge라는 별도 프로그램(Deno로 도는 헤드리스 도구)이 CouchDB에 직접 붙어서, 동기화되는 노트를 서버 파일시스템에 실제 .md 파일로 만들어준다. 그러면 서버의 에이전트는 LiveSync가 뭔지 몰라도 그냥 디렉토리에 있는 마크다운 파일을 읽고 쓰면 되고, 그 변경이 브리지를 통해 CouchDB로 올라가 다른 기기의 Obsidian에 반영된다.
결과적으로 구성은 이렇게 됐다.
- CouchDB — 동기화 허브. 외부에 직접 노출하지 않고 로컬에만 바인딩한다.
- 각 기기의 Obsidian + LiveSync 플러그인 — 데스크탑·폰이 여기 붙는다.
- livesync-bridge — CouchDB의 내용을 서버 파일시스템에
.md로 만들어두는 양방향 미러. 헤드리스 세션이 붙는 지점이 여기다. - tailscale — 기기 간 접속 경로. 공개 도메인을 열지 않고, 켜져 있는 사용자 본인 기기끼리만 붙는다. 왜 Cloudflare가 아니라 tailscale인지는 그 자체로 한 편짜리 이야기라 목차 2번에서 따로 다룬다.
정리하면 이렇다. "데이터를 내 서버에 둔다"와 "에이전트가 붙을 수 있어야 한다"가 겹치면서 노션이 떨어지고 Obsidian·LiveSync·CouchDB 조합이 남았으며, 헤드리스 기기까지 커버하려고 브리지 한 겹이 더 얹혔다. 요구조건을 만족하는 구성을 그렇게 찾아냈고 실제로 목적도 달성했지만, 그 마지막 한 겹이 이후 수많은 고장의 진원지가 됐다. 아래 목차의 상당수가 바로 이 브리지에서 터진 일이다.
그래서 뭐가 깨졌나 (시리즈 목차)
이 구성으로 굴리며 겪은 것들을 시간순으로 정리했다. 공통점이 하나 있는데, 대부분 요란하게 실패하지 않고 조용히 멈췄다는 것이다. 어느 순간부터 동기화가 안 되고 있는데 아무도 모르는 상태가 반복됐다.
링크가 걸린 항목은 이미 공개된 편이고, 링크가 없는 항목은 앞으로 한 편씩 올라온다. 공개되는 대로 이 글 아래의 시리즈 목록에도 자동으로 붙는다.
- CouchDB 컨테이너가 로그 한 줄 없이 즉사할 때 (그리고 이름이
_로 시작하면 안 되는 이유) - Cloudflare Access 뒤에서 LiveSync가 안 붙던 이야기 — 그리고 그것만 넘었다고 동기화가 다 살아나지는 않았다는 것
- 수동 Replicate는 되는데 자동 push만 안 될 때 — 반복된 DB wipe가 원인이었다
- 브리지가 하루 열네 번 조용히 재시작하던 원인
- 동기화 허브를 다른 서버로 옮겼더니 새 서버가 아무것도 못 받아온 이유
- pull이 에러 한 줄 없이 죽는다 — 그리고 그걸 잡는 감시 크론
- 10분마다 바뀌는 감시용 파일이 Obsidian에서 충돌을 일으킬 때
- 조용히 죽던 연결의 근본 원인과 두 줄짜리 수정
- 신규 기기 최초 동기화가 761/23585에서 멈출 때 (Fast fetch heartbeat 버그 #953)
- 고아 청크로 부푼 CouchDB를 안전하게 청소하기 (9번에서 발견한 DB 비대화의 후속 정리)
- 앱에서 지운 노트가 서버 파일에는 살아있을 때
이 시리즈를 읽는 법
각 편은 혼자 읽어도 되게 쓸 생각이다. 검색해서 들어온 사람이 앞 편을 안 읽었다고 막히는 구간이 없도록, 필요한 배경은 그 편 안에서 한 줄씩 다시 설명한다. 순서대로 읽으면 시스템이 어떻게 자라고 어디서 삐걱댔는지가 보이고, 필요한 편만 읽으면 그 증상에 대한 답이 나오는 구성을 목표로 한다.
그리고 이 시리즈의 결론을 미리 말해두면, "자가호스팅 하지 마라"가 아니다. 요구조건이 명확하면 이 구성은 지금도 잘 돌아간다. 다만 조용히 깨지는 종류의 고장이 많아서, 깨진 걸 알아차리는 장치(감시·자가복구)가 구축만큼이나 중요하다는 게 지금까지의 교훈이다. 그 얘기는 목차 6번과 8번에서 다룰 예정이다.