Files
obsidian/infra/outline.md
Heimdall f595889e9e outline: fix DATABASE_URL pointing at Patroni replica, document MCP setup
- Patch DATABASE_URL to OpenWrt HAProxy (192.168.9.1:5432) so Outline
  follows Patroni leader automatically
- Record 2026-04-08 incident: postgres-1 demoted to replica caused all
  write queries (incl. apiKeys.lastActiveAt) to fail with 500
- Document heimdall outline MCP setup and new agent-qna collection
2026-04-08 21:48:18 +00:00

3.5 KiB

title, updated, tags
title updated tags
Outline Wiki 2026-03-30
k3s
wiki
outline

개요

Outline은 팀 위키/문서 관리 플랫폼. K3s 클러스터에 배포.

항목
URL https://outline.inouter.com
네임스페이스 outline
이미지 outlinewiki/outline:0.82.0
인증 Gitea OAuth2 (OIDC)
기본 언어 한국어

구성 요소

컴포넌트 설정
DB Patroni HA via OpenWrt HAProxy (192.168.9.1:5432), DB명: outline, 유저: outline
Redis outline-redis (outline 네임스페이스 내 전용)
파일 저장소 로컬 (Longhorn PVC 5Gi, /var/lib/outline/data)
TLS (Traefik) wildcard-inouter-tls (*.inouter.com)
TLS (CDN) Let's Encrypt via BunnyCDN
CDN BunnyCDN iron-kr 존 (ID 5555227, 쿠키 허용)
DNS outline.inouter.com CNAME → iron-kr.b-cdn.net (Cloudflare, proxied OFF)
Ingress Traefik IngressRoute (CRD)

인증 (Gitea OAuth2)

항목
OIDC Provider Gitea (gitea.inouter.com)
Client ID cb804835-416c-4730-86b4-26d2c129b164
Redirect URI https://outline.inouter.com/auth/oidc.callback
OIDC Endpoints authorize, access_token, userinfo (Gitea 표준)
Client Secret Vault secret/apps/outline 참조

시크릿

Kubernetes Secret: outline-secrets (outline 네임스페이스)

  • SECRET_KEY, UTILS_SECRET, DATABASE_URL, REDIS_URL
  • OIDC_CLIENT_ID, OIDC_CLIENT_SECRET, OIDC 엔드포인트들

pgcat 연동

현재 pgcat 미사용 (직접 PostgreSQL 접속). 필요 시 pgcat pool 추가 가능.

MCP 연동

Outline MCP 서버 도입 시 헤임달이 직접 문서 CRUD 가능.

  • 참고: https://github.com/Vortiago/mcp-outline
  • heimdall ~/.claude.json /root 프로젝트 mcpServers에 outline 항목 추가 (stdio, uvx mcp-outline, OUTLINE_API_KEY는 Vault secret/apps/outline brokkr-api-key, OUTLINE_API_URL=https://outline.inouter.com)
  • 새 컬렉션 agent-qna (id c3ab34ab-fae4-4642-8f4e-12728e293e1b) — 에이전트 간 장문 Q&A 교환 공간 (kappa↔heimdall이 tmux로 짧게 질문 → 답변은 여기에 작성)

2026-04-08 사고: DATABASE_URL이 Patroni replica 직결

outline-secrets Secret의 DATABASE_URL이 Patroni 노드 IP 10.100.2.5(postgres-1)를 직접 가리키도록 설정되어 있었음. Patroni failover로 postgres-1이 replica로 강등되자 Outline의 모든 write 쿼리가 cannot execute UPDATE in a read-only transaction 에러로 실패. API는 500을 반환(apiKeys.lastActiveAt UPDATE 실패 → 인증 자체가 깨짐).

복구: DATABASE_URL을 OpenWrt HAProxy 경유로 변경.

kubectl patch secret outline-secrets -n outline --type=json \
  -p='[{"op":"replace","path":"/data/DATABASE_URL","value":"<base64 of postgresql://outline:outline@192.168.9.1:5432/outline>"}]'
kubectl rollout restart deployment/outline -n outline
# RWO PVC 때문에 old pod를 수동 삭제해야 새 pod attach 가능
kubectl delete pod -n outline <old-pod>

원인: 이 Secret은 nocodb/n8n/pgcat 변경(2026-04-08 postgresql-ha#2026-04-08 사고 기록)과 함께 일괄 마이그레이션되지 않았음. 나머지 Patroni 사용자도 동일 검증 필요kubectl get secret -A -o json | jq -r '.items[] | select(.data.DATABASE_URL) | "\(.metadata.namespace)/\(.metadata.name)"'로 검수 권장.

교훈: Patroni 사용 애플리케이션의 DB endpoint는 항상 OpenWrt HAProxy(192.168.9.1:5432) 또는 pgcat(db.svc.cluster.local:6432)을 통해야 한다. 노드 IP 직접 박지 말 것.