- 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
76 lines
3.5 KiB
Markdown
76 lines
3.5 KiB
Markdown
---
|
|
title: Outline Wiki
|
|
updated: 2026-03-30
|
|
tags: [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 경유로 변경.
|
|
|
|
```bash
|
|
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 직접 박지 말 것.
|