설치 및 배포
WeKnora는 Docker Compose, Kubernetes Helm, Lite 단일 바이너리, 데스크톱 앱을 지원합니다. 서버 배포에는 Compose 또는 Helm을, 로컬 사용에는 Lite를 선택할 수 있으며, 개발에 참여할 때는 독립된 개발용 구성을 사용합니다. 각 방식의 의존성, 시작 명령, 데이터 디렉터리는 다음과 같습니다.
배포 형태 개요
| 형태 | 진입점 | 데이터베이스 | 큐/스트림 | 활용 시나리오 |
|---|---|---|---|---|
| Docker Compose(표준) | docker-compose.yml | ParadeDB(PostgreSQL) | Redis + Asynq | 프로덕션 / 팀 자체 호스팅, 권장 |
| Docker Compose(개발) | docker-compose.dev.yml | 위와 동일(인프라만 컨테이너에서 실행) | 위와 동일 | 로컬 개발: app / frontend는 호스트에서 실행 |
| Helm | helm/ | ParadeDB(chart 내장) | Redis(chart 내장) | Kubernetes >= 1.25 |
| Lite 단일 바이너리 | make build-lite / scripts/package-lite.sh | SQLite(FTS5 + sqlite-vec) | 메모리(Redis 없음) | 개인 / 오프라인 / 저사양 환경 |
| 데스크톱 앱(정식 출시 전) | cmd/desktop(Wails v2) + scripts/package-mac-app.sh | SQLite | 메모리 | GUI와 로컬 데이터 디렉터리를 갖춘 데스크톱 단독 사용 |
| Homebrew | Formula/weknora-lite.rb | SQLite | 메모리 | macOS / Linux 명령줄에서 Lite 설치 |
하드웨어 및 의존성 요구 사항
- 표준 Docker 배포: Docker 20.10+와 Docker Compose v2(v1
docker-compose도 호환되며scripts/start_all.sh가 자동 감지합니다). CPU 4코어 / 메모리 8GB 이상을 권장합니다(docreader에 LibreOffice와 Playwright가 포함되어 메모리 사용량이 많습니다). 디스크는 지식 베이스 규모에 맞춰 확보합니다(Postgres 볼륨 +/data/files파일 볼륨). Milvus / OpenSearch / Langfuse 등의 선택 구성 요소를 활성화하면 그에 맞춰 메모리를 추가해야 합니다. - 모델 서비스: 로컬 추론에는 Ollama가 필요합니다(기본 주소
http://host.docker.internal:11434,OLLAMA_OPTIONAL=true이면 사용할 수 없어도 경고만 표시하고 시작을 차단하지 않습니다). 또는 OpenAI 호환 API(DeepSeek, Tongyi, Zhipu, SiliconFlow 등)를 사용할 수 있습니다. - 소스 컴파일: Go 1.26(
docker/Dockerfile.app의 builder 단계golang:1.26-bookworm참고), CGO(libsqlite3-dev의존), Node.js + npm(프런트엔드), Python 3.10 + uv(docreader). - Kubernetes: >= 1.25.0(
helm/Chart.yaml).
1. Docker Compose 표준 배포(docker-compose.yml)
가장 빠른 방법:
git clone https://github.com/Tencent/WeKnora.git && cd WeKnora
cp .env.example .env # 필수 항목 수정: DB_USER/DB_PASSWORD/DB_NAME, REDIS_PASSWORD, JWT_SECRET, SYSTEM_AES_KEY
make start-all # ./scripts/start_all.sh와 동일(기본적으로 최신 이미지 가져오기)
# 또는 직접 실행:
docker compose pull # WEKNORA_VERSION에 맞는 이미지 가져오기
docker compose up -d
docker compose ps # 모든 서비스가 healthy/running 상태가 될 때까지 대기중지하려면 docker compose down을 사용합니다(-v를 추가하면 데이터 볼륨까지 삭제하므로 주의하세요). 저장소의 make start-all은 같은 명령의 래퍼입니다(scripts/start_all.sh, Ollama 확인, .env 대체 처리, 샌드박스 이미지 사전 가져오기를 추가 수행). 둘 중 하나만 선택하면 됩니다.
시작한 뒤 브라우저에서 http://localhost를 열면 프런트엔드가 표시됩니다(포트는 FRONTEND_PORT로 결정하며 기본값은 80). 처음 접속하면 가입 페이지로 이동합니다. 프런트엔드 Nginx가 /api/를 백엔드로 리버스 프록시하므로 API 호출도 http://localhost/api/v1을 사용합니다. 백엔드의 8080 포트도 호스트에 직접 매핑되므로 curl http://localhost:8080/health로 백엔드 준비 상태를 확인할 수 있습니다.
참고:
docker-compose.yml의 app 서비스는env_file: [.env]를 사용하므로.env가 없으면 compose 파싱에 실패합니다.make docker-run/start_all.sh는 자동으로cp .env.example .env또는touch .env를 실행하여 처리합니다.
버전 업그레이드
기존 배포가 있고 새 release를 다운로드했다면:
# .env에서 WEKNORA_VERSION을 대상 버전(예: 0.7.0)으로 설정하거나 latest 유지
docker compose pull
docker compose up -d
docker compose up -d만 실행하면 로컬에 캐시된 이미지를 재사용하므로, Web UI에 표시되는 버전이 다운로드한 release와 다를 수 있습니다.
핵심 서비스(기본 시작)
| 서비스 | 이미지 | 포트(호스트:컨테이너) | 의존성 | 설명 |
|---|---|---|---|---|
frontend | wechatopenai/weknora-ui:${WEKNORA_VERSION:-latest} | ${FRONTEND_PORT:-80}:80 | app(healthy) | Nginx가 SPA를 호스팅하고 app으로 리버스 프록시합니다. APP_HOST/APP_BACKEND_PORT/APP_SCHEME으로 원격 백엔드를 지정할 수 있습니다 |
app | wechatopenai/weknora-app | ${APP_PORT:-8080}:8080 | postgres(healthy), redis, docreader(healthy) | Go 백엔드. ./config/config.yaml과 data-files 볼륨을 마운트합니다. 상태 확인은 GET /health |
docreader | wechatopenai/weknora-docreader | expose: 50051만 사용(호스트에 공개하지 않음) | — | 문서 파싱 gRPC 서비스. 상태 확인은 grpc_health_probe. app과 docreader-tmp 볼륨을 공유하여 이미지를 전달합니다 |
postgres | paradedb/paradedb:v0.22.2-pg17 | 호스트 포트 매핑 없음 | — | ParadeDB = PostgreSQL 17 + BM25/벡터 확장, 기본 검색 엔진 |
redis | redis:7.0-alpine | 호스트 포트 매핑 없음 | — | --appendonly yes --requirepass ${REDIS_PASSWORD} |
선택 서비스와 profiles
필요에 따라 docker compose --profile <name> up -d로 활성화합니다.
| profile | 서비스 | 포트 | 용도 |
|---|---|---|---|
searxng(full 포함) | searxng-init + searxng | 127.0.0.1:8888(SEARXNG_BIND/SEARXNG_PORT) | 자체 호스팅 웹 검색. 기본적으로 루프백에만 바인딩하며, 공개 전에 반드시 SEARXNG_SECRET을 교체해야 합니다 |
minio(full 포함) | minio | 9000(S3) / 9001(콘솔) | S3 호환 객체 스토리지(STORAGE_TYPE=minio), 기본 계정 minioadmin/minioadmin |
neo4j(full 포함) | neo4j | 7474 / 7687 | 지식 그래프(NEO4J_ENABLE=true), 기본값 neo4j/password |
qdrant(full 포함) | qdrant | 6333(REST) / 6334(gRPC) | 벡터 데이터베이스(RETRIEVE_DRIVER=qdrant) |
milvus | milvus | 19530 / 9091 | 벡터 데이터베이스(standalone, etcd 내장) |
weaviate | weaviate | 9035(HTTP) / 50052(gRPC) | 벡터 데이터베이스 |
doris | doris-fe + doris-be | 8030(FE HTTP) / 9030(FE MySQL) / 8040(BE) | Apache Doris 4.1 검색 엔진(>= 3.0 필요, HNSW ANN) |
dex(full 포함) | dex | 5556 | OIDC 테스트용 IdP(misc/dex-config.yaml에서 설정) |
langfuse(full 포함) | langfuse-db-init, langfuse-clickhouse, langfuse-minio, langfuse-worker, langfuse-web | 3000(UI) / 9100/9101(전용 MinIO) | 자체 호스팅 Langfuse 관측 스택. WeKnora의 postgres(langfuse 데이터베이스 생성)와 redis(DB 1)를 재사용합니다 |
odl-hybrid | odl-hybrid | expose 5002 | OpenDataLoader/Docling PDF 하이브리드 파싱 백엔드(로컬 빌드만 지원, DOCREADER_ODL_HYBRID와 함께 사용) |
full | sandbox, mcp 및 위에서 full로 표시된 서비스 | mcp: ${MCP_PORT:-8082}:8000 | sandbox는 이미지 build/pull 전용입니다(command: ["true"], 상주하지 않음). Docker 샌드박스는 기본적으로 꺼져 있으며, WEKNORA_SANDBOX_DOCKER_ENABLED=true 설정과 docker.sock 마운트가 필요합니다(호스트 root와 동등한 권한). Cube/E2B는 로컬 daemon에 의존하지 않습니다. mcp는 MCP Server입니다 |
app 컨테이너의 environment 섹션은 전체 환경 변수 목록입니다(데이터베이스, 벡터 데이터베이스, 객체 스토리지, Docreader 튜닝, 테넌트 정책, OIDC 등). 자세한 내용은 04-configuration.md를 참고하세요.
2. 개발 모드(docker-compose.dev.yml + scripts/dev.sh)
개발 구성은 인프라만 컨테이너에서 실행합니다(postgres, redis, docreader 포트를 모두 호스트에 매핑). app과 frontend는 호스트에서 핫 리로드 방식으로 실행합니다.
make dev-start # ./scripts/dev.sh start, DEV_ARGS=--odl-hybrid / --minio / --qdrant / --neo4j / --dex / --full 추가 가능
make dev-app # 호스트에서 Go 백엔드 시작(DB_HOST/REDIS_ADDR을 자동으로 localhost로 지정)
make dev-frontend # 호스트에서 Vue 프런트엔드 dev server 시작
make dev-logs / dev-status / dev-stop / dev-restart프로덕션 구성과의 차이:
- postgres(
5432), redis(6379), docreader(50051) 모두 호스트 포트에 공개되어 로컬 프로세스에서 직접 연결할 수 있습니다. opensearch(9200)와opensearch-dashboards(5601, profileopensearch-ui)의 단일 노드 개발 환경을 추가 제공합니다(security 플러그인 비활성화).dev.sh는.env와.env.local을 로드하며(후자가 전자를 덮어씀),DEV_REMOTE_HOST로 원격 인프라를 지정할 수 있습니다.
3. 이미지 빌드(docker/ 디렉터리)
| Dockerfile | 결과 이미지 | 주요 사항 |
|---|---|---|
docker/Dockerfile.app | wechatopenai/weknora-app | 2단계: golang:1.26-bookworm에서 컴파일(make build-prod, 기본 WITH_ANYDOC=1로 프로세스 내 office 파싱 엔진 링크, 버전 정보 주입, DuckDB 확장 cmd/download/duckdb 사전 다운로드) → debian:12.12-slim 실행 계층(migrate 마이그레이션 도구, python3/node/uvx(stdio MCP 및 Skills용), ffmpeg(ASR), gosu 권한 낮추기 포함). 진입점 scripts/docker-entrypoint.sh: 마운트 디렉터리 소유자를 수정하고, docker.sock이 마운트되면 socket GID에 따라 appuser를 해당 그룹에 추가합니다(compose group_add는 gosu 이후 무효). 이후 appuser로 ./WeKnora를 실행합니다. EXPOSE 8080 |
docker/Dockerfile.docreader | wechatopenai/weknora-docreader | Python 3.10 + uv 의존성 잠금, protobuf 생성. 실행 계층에 LibreOffice, OpenJDK 17, antiword, Playwright(webkit), grpc_health_probe를 설치합니다. 경량 버전에는 PaddleOCR이 없습니다. EXPOSE 50051. APT_MIRROR 빌드 인수를 지원합니다 |
docker/Dockerfile.odl-hybrid | weknora-odl-hybrid:local | opendataloader-pdf[hybrid](Docling) 설치, 5002에서 수신, 기본 --no-ocr. 로컬 빌드 전용으로 배포하지 않습니다 |
docker/Dockerfile.sandbox | wechatopenai/weknora-sandbox | Python 3.12-slim + Node 20 + jq. 기본적으로 root로 실행하며 명시적으로 선택할 수 있도록 user(UID 1000)를 유지합니다. Agent Skills 세션 샌드박스 이미지 |
frontend/Dockerfile | wechatopenai/weknora-ui | 2단계: digest로 고정한 node:24-bookworm-slim($BUILDPLATFORM, 다중 아키텍처 CI에서 QEMU로 Vite를 실행하지 않도록 함)에서 npm ci + npm run build(VITE_IS_DOCKER / VITE_FRONTEND_COMMIT), 선택적으로 NPM_REGISTRY / NODE_MAX_OLD_SPACE_SIZE 사용. 실행 계층은 digest로 고정한 nginx:1.30.3-alpine(CentOS 7의 오래된 커널과 호환). 호스트에서 dist/를 미리 빌드할 필요가 없습니다 |
소스에서 모든 이미지 빌드:
make build-images # ./scripts/build_images.sh, 인수 --app/--docreader/--frontend/--sandbox/--clean
# 또는 개별 빌드:
make docker-build-app
make docker-build-docreader
make docker-build-frontend4. Makefile 배포 관련 타깃 빠른 참조
| 타깃 | 역할 |
|---|---|
make start-all / stop-all | scripts/start_all.sh를 호출하여 전체 서비스 시작/중지(Ollama 확인, .env 대체 처리, 샌드박스 이미지 사전 가져오기 포함) |
make start-ollama / start-docker | Ollama만 시작 / Docker 서비스만 시작 |
make docker-run / docker-stop / docker-restart | 기존 docker-compose up/down/restart(.env 자동 대체 처리) |
make build-images* / clean-images / pull-images | 소스 빌드 / 이미지 정리 / 가져오기 |
make check-env / list-containers / show-platform | 환경 확인(scripts/check-env.sh가 .env 필수 변수와 도구 체인 검증) / 컨테이너 목록 / 빌드 플랫폼(amd64/arm64 자동 감지) |
make migrate-up / migrate-down / migrate-version / migrate-create name=x / migrate-force version=n / migrate-goto version=n | 데이터베이스 마이그레이션(scripts/migrate.sh, 컨테이너에서는 기본 AUTO_MIGRATE=true로 시작 시 자동 마이그레이션) |
make dev-* | 개발 모드(위 내용 참고) |
make build / run / build-prod | 로컬에서 cmd/server 컴파일 및 실행(build-prod는 CGO가 필요하며 버전 번호와 Edition=standard 주입) |
make build-lite / run-lite / package-lite | Lite 모드 빌드 / 실행(.env.lite 읽기) / 배포 패키지 생성 |
make package-mac-app | macOS 데스크톱 앱 패키징 |
make docs / install-swagger | Swagger 문서 생성(http://localhost:8080/swagger/index.html, release 모드에서는 비활성화) |
make clean-db | postgres/minio/redis 데이터 볼륨 삭제(위험한 작업) |
5. scripts/ 시작 스크립트
| 스크립트 | 역할 |
|---|---|
scripts/start_all.sh | 한 번에 시작: 인수 -o(Ollama만), -d(Docker만), -a(전체, 기본값), -s(중지), -c(환경 확인), -l(컨테이너 목록), -p(이미지 가져오기). compose v1/v2 자동 감지, uname -m에 따라 PLATFORM 설정, 백그라운드에서 sandbox 이미지 사전 가져오기 |
scripts/dev.sh | 개발 환경 구성(위 내용 참고), 하위 명령 start/stop/restart/logs/status/app/frontend |
scripts/check-env.sh | .env 필수 변수(DB_*, STORAGE_TYPE, REDIS_ADDR, OLLAMA_BASE_URL 등)와 Go/npm/Docker/Air 도구 체인 검증 |
scripts/build_images.sh | 이미지 빌드 및 버전 주입(git tag / commit / build time), 교차 아키텍처 지원 |
scripts/build_frontend_dist.sh | 호스트에서 프런트엔드 정적 산출물 frontend/dist 빌드(Lite / 데스크톱 패키징 등 Docker 외 환경용. UI 이미지는 Dockerfile 다단계 빌드로 전환) |
scripts/migrate.sh | golang-migrate 래퍼 |
scripts/docker-entrypoint.sh | app 컨테이너 진입점(소유자 수정 + 내장 Skills 병합 + docker.sock GID 그룹 추가 + gosu 권한 낮추기) |
scripts/package-lite.sh / package-mac-app.sh | Lite tarball / macOS .app 패키징 |
6. Helm 배포(helm/)
helm/Chart.yaml: apiVersion v2, chart 이름 weknora, appVersion은 버전을 따릅니다(예: v0.8.0). Kubernetes >= 1.25.0이 필요합니다.
Chart에는 app(wechatopenai/weknora-app), frontend(wechatopenai/weknora-ui), docreader, postgresql(ParadeDB 이미지), redis(redis:7-alpine)의 5개 구성 요소가 포함되며, 선택적으로 minio와 neo4j를 활성화할 수 있습니다.
helm/values.yaml의 주요 설정:
app:
replicaCount: 1
env:
GIN_MODE: release
RETRIEVE_DRIVER: postgres # postgres / elasticsearch_v7 / elasticsearch_v8 / qdrant ...
STORAGE_TYPE: local # local / minio / cos / tos / s3
STREAM_MANAGER_TYPE: redis
postgresql:
enabled: true
persistence: { enabled: true, size: 10Gi }
redis:
enabled: true
persistence: { enabled: true, size: 1Gi }
dataFiles:
persistence: { enabled: true, size: 10Gi }
secrets: # 필수 항목. 또는 existingSecret으로 기존 Secret 참조
dbPassword: ""
redisPassword: ""
jwtSecret: ""
systemAesKey: "" # 32바이트 AES-256 마스터 키helm install weknora ./helm -n weknora --create-namespace \
--set secrets.dbPassword=xxx --set secrets.redisPassword=xxx \
--set secrets.jwtSecret=xxx --set secrets.systemAesKey=$(openssl rand -hex 16)7. 데스크톱(Lite 모드 / 데스크톱 앱 / Homebrew)
데스크톱은 로컬 및 저사양 환경을 대상으로 하며, 모두 동일한 Lite 런타임(단일 프로세스 + SQLite + 메모리 큐)을 사용합니다. 배포와 시작 방식만 다릅니다. 단일 바이너리(명령줄 실행, 백그라운드 서비스로도 사용 가능), 데스크톱 앱(GUI, 더블 클릭으로 실행), Homebrew(macOS/Linux 명령줄에서 Lite 설치)의 기능 범위는 같습니다.
Lite 런타임(외부 의존성 없음)
Lite 모드는 컴파일 시 EDITION=lite와 실행 시 .env.lite 환경을 통해 전체 기능을 하나의 프로세스에서 실행합니다.
- 데이터베이스:
DB_DRIVER=sqlite+DB_PATH=./data/weknora.db, 컴파일 시-tags "sqlite_fts5"추가. - 검색:
RETRIEVE_DRIVER=sqlite, SQLite FTS5 전문 검색 + sqlite-vec 벡터 검색을 사용하므로 별도의 벡터 데이터베이스가 필요하지 않습니다. - 큐/스트림:
STREAM_MANAGER_TYPE=memory(internal/stream/factory.go), Redis가 필요 없으며 Lite 모드의 Asynq 분산 큐는 메모리/no-op입니다. - 프런트엔드:
make build-lite가frontend/dist를 저장소 루트의web/로 복사하며, 바이너리에 정적 리소스를 직접 내장하여 호스팅합니다(WEKNORA_WEB_DIR로 디렉터리를 지정할 수 있으며 router의serveFrontendStatic이 제공합니다). - 문서 파싱: 선택적으로 로컬 docreader에 연결할 수 있습니다(
DOCREADER_ADDR=127.0.0.1:50051). - 샌드박스: Lite 시작 시 백엔드를 미리 설정하지 않습니다. 설정 페이지에서 공간별로 Docker, CubeSandbox 또는 E2B를 통합 설정할 수 있습니다.
cp .env.lite.example .env.lite # SYSTEM_AES_KEY / JWT_SECRET 수정
make run-lite # 빌드 후 .env.lite 환경으로 ./WeKnora-lite 시작
make package-lite # 배포 tarball 패키징(scripts/package-lite.sh)Lite는 POST /auth/auto-setup으로 로컬 계정을 한 번에 생성하는 기능도 제공합니다(lite edition에서만 사용 가능, internal/handler/auth.go 참고). 데스크톱 앱은 이를 통해 가입 없이 시작합니다.
데스크톱 앱(cmd/desktop, Wails v2)
데스크톱 앱은 GUI로 로컬에서 사용할 수 있습니다. 더블 클릭하면 시작되며, 프로세스에 백엔드와 SQLite가 포함되고 데이터는 시스템의 앱 데이터 디렉터리에 저장됩니다. 포트 설정, LAN 바인딩, 업데이트 확인 등의 데스크톱 전용 기능도 제공합니다. 런타임 기능은 Lite 런타임(외부 의존성 없음)과 같습니다.
아직 정식 출시되지 않았어요
현재 데스크톱 앱은 Release에 설치 패키지를 제공하지 않으므로, 아래 단계에 따라 직접 빌드해야 해요. release-lite.yml에는 크로스 플랫폼(macOS universal/amd64/arm64, Linux amd64, Windows amd64) 빌드 작업이 있지만, 워크플로의 tag 트리거가 주석 처리되어 수동으로만 실행할 수 있어요. 현재 최신 Release에는 산출물이 첨부되어 있지 않아요.
- 진입점은
cmd/desktop/main.go+cmd/desktop/wails.json입니다.cmd/desktop/app.go는 프런트엔드에GetAPIBaseURL(http://127.0.0.1:PORT/api/v1반환), HTTP 포트 및 'LAN에 바인딩' 설정,CheckForUpdates자동 업데이트 확인 등의 바인딩 메서드를 노출합니다. scripts/package-mac-app.sh: 먼저 프런트엔드를web/로 빌드하고,wails build -tags "sqlite_fts5"를 실행한 다음.app패키지를 구성합니다.Contents/MacOS/WeKnora Lite가 주 프로그램이며,Contents/Resources에.env, config,migrations/sqlite, web 프런트엔드를 포함합니다. 상대 경로 데이터는 자동으로~/Library/Application Support/WeKnora Lite/data/로 리디렉션되며, 로그는~/Library/Logs/WeKnora Lite/에 기록합니다.
make package-mac-appHomebrew(Formula/weknora-lite.rb)
brew install weknora-lite # GitHub Releases에서 WeKnora-lite_v{ver}_{os}_{arch}.tar.gz 다운로드
brew services start weknora-lite # 백그라운드 서비스로 실행(keep_alive, 로그 var/log/weknora-lite.log)Formula의 설명은 "Knowledge base management system — single-binary Lite edition"이며, macOS/Linux의 arm64와 amd64를 지원합니다. 래퍼 스크립트는 처음 실행할 때 .env.lite.example을 ~/.config/weknora/.env.lite로 복사합니다(WEKNORA_CONFIG_DIR / WEKNORA_DATA_DIR로 설정 및 데이터 디렉터리를 재정의할 수 있으며, 데이터 기본 위치는 ~/.local/share/weknora입니다).
8. 소스 컴파일 및 실행
# 백엔드(표준 버전, 로컬 postgres/redis/docreader 필요, 개발 모드 참고)
go mod download
make build && ./WeKnora # 또는 make build-prod
# 프런트엔드
cd frontend && npm ci && npm run dev # 개발. npm run build는 dist/ 생성
# docreader
cd docreader && uv sync --locked && bash scripts/generate_proto.sh && python -m docreader.server # 구체적인 진입점은 docreader/ 참고설정 파일 검색 순서(internal/config/config.go의 LoadConfig): 현재 디렉터리 → ./config → $HOME/.appname → /etc/appname/, 파일 이름은 config.yaml입니다.
일반적인 배포 토폴로지
다음 단계
배포를 완료한 뒤 03-quickstart.md를 읽고 초기 설정과 첫 질의응답을 진행하세요.