Files
obsidian/infra/outline.md

6.0 KiB

title, updated, tags
title updated tags
Outline Wiki 2026-04-08
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로 짧게 질문 → 답변은 여기에 작성)

DB endpoint는 OpenWrt HAProxy(192.168.9.1:5432) 경유. 과거 Patroni failover 사고 이력: 2026-04-08-patroni-failover-incident

Discord 통지 파이프라인

agent-qna 컬렉션에 새 문서가 만들어지면 heimdall Discord 채널(#heimdall, id 1488119168145555486)에 자동 알림이 뜬다. 다른 컬렉션은 무시한다.

Outline (documents.create webhook)
  → n8n webhook (https://n8n.inouter.com/webhook/outline-to-discord)
    → Code 노드 (collectionId 필터 + Discord embed 빌드)
      → HTTP Request 노드 (Discord Bot API: POST /channels/{id}/messages)

구성 요소 위치

항목
n8n workflow id 8P714i5oBs9HkZPK
n8n workflow 이름 outline-to-discord (heimdall)
n8n webhook path /webhook/outline-to-discord (POST, responseMode=onReceived)
n8n 노드 구성 Webhook → Filter+Format(Code) → Discord POST(HTTP)
Outline webhook id ede9327f-b09e-4f7e-ab56-c507d3d1b3a6 (documents.create 이벤트)
Outline collection 필터 c3ab34ab-fae4-4642-8f4e-12728e293e1b (agent-qna) — Code 노드 안에 하드코딩
Discord channel guild 1469999069190557799#heimdall 채널 (id 1488119168145555486)
Discord bot username Heimdall (id 1487694864232611922)

시크릿

비밀 Vault 경로
Discord bot token secret/apps/discordbot_token (현재는 n8n Code 노드에 하드코딩되어 있음 — Credentials로 분리하는 게 더 깔끔, 후속 작업)
Discord channel/guild ID secret/apps/discordheimdall_channel_id, heimdall_guild_id
n8n API key secret/apps/n8napi_key (label: heimdall-automation)
n8n owner login secret/apps/n8nemail(kappa@inouter.com), password
Outline API token secret/apps/outlinebrokkr-api-key

메시지 포맷 (Discord embed)

  • title: 📝 <doc title>
  • url: https://outline.inouter.com<payload.model.url>
  • description: 본문 앞 200자 (개행 → 공백)
  • author.name: outline / agent-qna · <createdBy.name>
  • color: 0x00bcd4 (cyan)
  • timestamp: payload.model.createdAt

트러블슈팅

증상별 점검 순서:

  1. 알림이 아예 안 옴
    • Outline UI 또는 API로 webhook subscription 활성 확인
      curl -sS -X POST https://outline.inouter.com/api/webhookSubscriptions.list \
        -H "Authorization: Bearer $OL_TOKEN" -d '{}' | jq .
      
    • n8n에서 workflow active 여부 확인 (/api/v1/workflows/8P714i5oBs9HkZPK)
    • n8n executions에 webhook 도달했는지 확인 (/api/v1/executions?workflowId=8P714i5oBs9HkZPK&limit=10)
  2. n8n에 도달하나 Discord POST가 안 일어남
    • 거의 항상 collectionId 필터 미스매치. Filter+Format Code 노드의 out items: 0 이면 정상 (필터된 것)
    • 필터를 통과해야 하는데 0 items면 payload.event 또는 payload.model.collectionId 구조 확인
  3. n8n DB connection timeout
    • n8n pod 재시작: kubectl -n n8n delete pod -l app.kubernetes.io/name=n8n
    • pgcat → 192.168.9.1:5432 (Patroni leader) 경로 확인
  4. Discord 401/403
    • bot token 재발급 필요 (secret/apps/discord 갱신, n8n Code 노드의 하드코딩도 함께 갱신)
    • bot이 채널에 access 권한 있는지: GET /channels/{channel_id} 200이면 OK
  5. Outline → n8n 호출이 BunnyCDN 508
    • 일시적. 재시도하면 풀린다. BunnyCDN edge의 cdn-loopcount 룰 (자세한 원인 불명, retry로 회피)

후속 작업 (선택)

  • Discord bot token을 n8n Credentials로 분리 (현재 Code 노드에 하드코딩)
  • Outline signing secret 지원되면 HMAC 서명 검증 추가 (현재 미적용 — 같은 인프라 내부 호출이라 위험 낮음)
  • documents.update 이벤트도 추가 (현재 create만)
  • 다른 컬렉션 (예: incident postmortem)도 동일 패턴으로 통지 추가