mirror of
https://github.com/Tencent/WeKnora.git
synced 2026-06-04 13:30:32 +08:00
- Add crypto utility (internal/utils/crypto.go) with AES-256-GCM encrypt/decrypt using SYSTEM_AES_KEY env var, with "enc:v1:" prefix for versioned ciphertext - Encrypt tenant API key via GORM BeforeSave/AfterFind hooks and manual encryption in CreateTenant/UpdateAPIKey (db.Updates bypasses hooks) - Encrypt model API key in ModelParameters Value/Scan (driver.Valuer) - Widen api_key column from varchar(64) to varchar(256) across all DB dialects (MySQL, ParadeDB, SQLite) and add versioned migration 000018 - Propagate SYSTEM_AES_KEY through docker-compose, Helm secrets and values - Fix migration 000017 PL/pgSQL dollar-quoting syntax ($ -> $$)
326 lines
10 KiB
YAML
326 lines
10 KiB
YAML
services:
|
||
frontend:
|
||
image: wechatopenai/weknora-ui:${WEKNORA_VERSION:-latest}
|
||
build:
|
||
context: ./frontend
|
||
args:
|
||
- MAX_FILE_SIZE_MB=${MAX_FILE_SIZE_MB:-50}
|
||
container_name: WeKnora-frontend
|
||
ports:
|
||
- "${FRONTEND_PORT:-80}:80"
|
||
environment:
|
||
- MAX_FILE_SIZE_MB=${MAX_FILE_SIZE_MB:-50}
|
||
- APP_HOST=${APP_HOST:-app}
|
||
# APP_BACKEND_PORT: the port NGINX proxies to (default 8080).
|
||
# For local deployment this is the App container's listening port, independent of host-mapped APP_PORT.
|
||
# For remote deployment, set this to the remote App's service port.
|
||
- APP_PORT=${APP_BACKEND_PORT:-8080}
|
||
- APP_SCHEME=${APP_SCHEME:-http}
|
||
# NOTE: If using a remote App backend, comment out or remove the depends_on
|
||
# block below and set APP_HOST/APP_BACKEND_PORT/APP_SCHEME in your .env file.
|
||
depends_on:
|
||
app:
|
||
condition: service_healthy
|
||
networks:
|
||
- WeKnora-network
|
||
restart: unless-stopped
|
||
|
||
app:
|
||
image: wechatopenai/weknora-app:${WEKNORA_VERSION:-latest}
|
||
build:
|
||
context: .
|
||
dockerfile: docker/Dockerfile.app
|
||
args:
|
||
- APK_MIRROR_ARG=${APK_MIRROR_ARG:-}
|
||
container_name: WeKnora-app
|
||
ports:
|
||
- "${APP_PORT:-8080}:8080"
|
||
volumes:
|
||
- data-files:/data/files
|
||
- docreader-tmp:/tmp/docreader:ro
|
||
# Optional: mount custom config file
|
||
# - ./config/config.yaml:/app/config/config.yaml
|
||
# Optional: mount custom skills directory (allows adding skills without rebuilding image)
|
||
- ./skills/preloaded:/app/skills/preloaded
|
||
healthcheck:
|
||
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
|
||
interval: 30s
|
||
timeout: 10s
|
||
retries: 3
|
||
start_period: 60s
|
||
environment:
|
||
- LOG_LEVEL=${LOG_LEVEL:-}
|
||
- COS_SECRET_ID=${COS_SECRET_ID:-}
|
||
- COS_SECRET_KEY=${COS_SECRET_KEY:-}
|
||
- COS_REGION=${COS_REGION:-}
|
||
- COS_BUCKET_NAME=${COS_BUCKET_NAME:-}
|
||
- COS_APP_ID=${COS_APP_ID:-}
|
||
- COS_PATH_PREFIX=${COS_PATH_PREFIX:-}
|
||
- COS_ENABLE_OLD_DOMAIN=${COS_ENABLE_OLD_DOMAIN:-}
|
||
- GIN_MODE=${GIN_MODE:-release}
|
||
- DISABLE_REGISTRATION=${DISABLE_REGISTRATION:-false}
|
||
- DB_DRIVER=postgres
|
||
- DB_HOST=postgres
|
||
- DB_PORT=5432
|
||
- DB_USER=${DB_USER:-}
|
||
- DB_PASSWORD=${DB_PASSWORD:-}
|
||
- DB_NAME=${DB_NAME:-}
|
||
- TZ=Asia/Shanghai
|
||
- OTEL_EXPORTER_OTLP_ENDPOINT=jaeger:4317
|
||
- OTEL_SERVICE_NAME=WeKnora
|
||
- OTEL_TRACES_EXPORTER=otlp
|
||
- OTEL_METRICS_EXPORTER=none
|
||
- OTEL_LOGS_EXPORTER=none
|
||
- OTEL_PROPAGATORS=tracecontext,baggage
|
||
- RETRIEVE_DRIVER=${RETRIEVE_DRIVER:-}
|
||
- ELASTICSEARCH_ADDR=${ELASTICSEARCH_ADDR:-}
|
||
- ELASTICSEARCH_USERNAME=${ELASTICSEARCH_USERNAME:-}
|
||
- ELASTICSEARCH_PASSWORD=${ELASTICSEARCH_PASSWORD:-}
|
||
- ELASTICSEARCH_INDEX=${ELASTICSEARCH_INDEX:-}
|
||
- QDRANT_HOST=qdrant
|
||
- QDRANT_PORT=${QDRANT_PORT:-6334}
|
||
- QDRANT_COLLECTION=${QDRANT_COLLECTION:-weknora_embeddings}
|
||
- QDRANT_API_KEY=${QDRANT_API_KEY:-}
|
||
- QDRANT_USE_TLS=${QDRANT_USE_TLS:-false}
|
||
- MILVUS_ADDRESS=milvus:19530
|
||
- MILVUS_COLLECTION=${MILVUS_COLLECTION:-weknora_embeddings}
|
||
- DOCREADER_ADDR=${DOCREADER_ADDR:-docreader:50051}
|
||
- DOCREADER_TRANSPORT=${DOCREADER_TRANSPORT:-grpc}
|
||
- STORAGE_TYPE=${STORAGE_TYPE:-}
|
||
- LOCAL_STORAGE_BASE_DIR=${LOCAL_STORAGE_BASE_DIR:-}
|
||
- AUTO_RECOVER_DIRTY=${AUTO_RECOVER_DIRTY:-true}
|
||
- MINIO_ENDPOINT=minio:9000
|
||
- MINIO_ACCESS_KEY_ID=${MINIO_ACCESS_KEY_ID:-minioadmin}
|
||
- MINIO_SECRET_ACCESS_KEY=${MINIO_SECRET_ACCESS_KEY:-minioadmin}
|
||
- MINIO_BUCKET_NAME=${MINIO_BUCKET_NAME:-}
|
||
- OLLAMA_BASE_URL=${OLLAMA_BASE_URL:-http://host.docker.internal:11434}
|
||
- STREAM_MANAGER_TYPE=${STREAM_MANAGER_TYPE:-}
|
||
- REDIS_ADDR=redis:6379
|
||
- REDIS_USERNAME=${REDIS_USERNAME:-}
|
||
- REDIS_PASSWORD=${REDIS_PASSWORD:-}
|
||
- REDIS_DB=${REDIS_DB:-}
|
||
- REDIS_PREFIX=${REDIS_PREFIX:-}
|
||
- ENABLE_GRAPH_RAG=${ENABLE_GRAPH_RAG:-}
|
||
- NEO4J_ENABLE=${NEO4J_ENABLE:-}
|
||
- NEO4J_URI=bolt://neo4j:7687
|
||
- NEO4J_USERNAME=${NEO4J_USERNAME:-neo4j}
|
||
- NEO4J_PASSWORD=${NEO4J_PASSWORD:-password}
|
||
- TENANT_AES_KEY=${TENANT_AES_KEY:-}
|
||
- SYSTEM_AES_KEY=${SYSTEM_AES_KEY:-}
|
||
- CONCURRENCY_POOL_SIZE=${CONCURRENCY_POOL_SIZE:-5}
|
||
- JWT_SECRET=${JWT_SECRET:-}
|
||
# File size limit (in MB)
|
||
- MAX_FILE_SIZE_MB=${MAX_FILE_SIZE_MB:-50}
|
||
# Agent Skills Sandbox
|
||
- WEKNORA_SANDBOX_MODE=${WEKNORA_SANDBOX_MODE:-docker}
|
||
- WEKNORA_SANDBOX_TIMEOUT=${WEKNORA_SANDBOX_TIMEOUT:-60}
|
||
- WEKNORA_SANDBOX_DOCKER_IMAGE=${WEKNORA_SANDBOX_DOCKER_IMAGE:-wechatopenai/weknora-sandbox:${WEKNORA_VERSION:-latest}}
|
||
- APK_MIRROR_ARG=${APK_MIRROR_ARG:-}
|
||
depends_on:
|
||
redis:
|
||
condition: service_started
|
||
postgres:
|
||
condition: service_healthy
|
||
docreader:
|
||
condition: service_healthy
|
||
networks:
|
||
- WeKnora-network
|
||
restart: unless-stopped
|
||
extra_hosts:
|
||
- "host.docker.internal:host-gateway"
|
||
|
||
# Sandbox 镜像:仅用于 build/pull,非常驻服务;app 执行 Skills 时按需 docker run 该镜像,用毕即释
|
||
sandbox:
|
||
image: wechatopenai/weknora-sandbox:${WEKNORA_VERSION:-latest}
|
||
container_name: WeKnora-sandbox
|
||
build:
|
||
context: .
|
||
dockerfile: docker/Dockerfile.sandbox
|
||
profiles:
|
||
- full
|
||
command: ["true"]
|
||
restart: "no"
|
||
|
||
docreader:
|
||
image: wechatopenai/weknora-docreader:${WEKNORA_VERSION:-latest}
|
||
build:
|
||
context: .
|
||
dockerfile: docker/Dockerfile.docreader
|
||
args:
|
||
- APT_MIRROR=${APT_MIRROR:-}
|
||
container_name: WeKnora-docreader
|
||
ports:
|
||
- "${DOCREADER_PORT:-50051}:50051"
|
||
volumes:
|
||
- docreader-tmp:/tmp/docreader
|
||
environment:
|
||
- DOCREADER_IMAGE_OUTPUT_DIR=/tmp/docreader
|
||
- MAX_FILE_SIZE_MB=${MAX_FILE_SIZE_MB:-}
|
||
healthcheck:
|
||
test: ["CMD", "grpc_health_probe", "-addr=:50051"]
|
||
interval: 30s
|
||
timeout: 10s
|
||
retries: 3
|
||
start_period: 60s
|
||
networks:
|
||
- WeKnora-network
|
||
restart: unless-stopped
|
||
extra_hosts:
|
||
- "host.docker.internal:host-gateway"
|
||
|
||
# 修改的PostgreSQL配置
|
||
postgres:
|
||
image: paradedb/paradedb:v0.21.4-pg17
|
||
container_name: WeKnora-postgres
|
||
environment:
|
||
- POSTGRES_USER=${DB_USER}
|
||
- POSTGRES_PASSWORD=${DB_PASSWORD}
|
||
- POSTGRES_DB=${DB_NAME}
|
||
volumes:
|
||
- postgres-data:/var/lib/postgresql/data
|
||
networks:
|
||
- WeKnora-network
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "pg_isready -U ${DB_USER}"]
|
||
interval: 10s # 增加时间间隔
|
||
timeout: 10s # 增加超时时间
|
||
retries: 3 # 减少重试次数,让失败更快反馈
|
||
start_period: 30s # 给予初始启动更多时间
|
||
restart: unless-stopped
|
||
# 添加停机时的优雅退出时间
|
||
stop_grace_period: 1m
|
||
|
||
redis:
|
||
image: redis:7.0-alpine
|
||
container_name: WeKnora-redis
|
||
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
|
||
restart: always
|
||
networks:
|
||
- WeKnora-network
|
||
|
||
minio:
|
||
image: minio/minio:RELEASE.2025-09-07T16-13-09Z
|
||
container_name: WeKnora-minio
|
||
ports:
|
||
- "${MINIO_PORT:-9000}:9000"
|
||
- "${MINIO_CONSOLE_PORT:-9001}:9001"
|
||
environment:
|
||
- MINIO_ROOT_USER=${MINIO_ACCESS_KEY_ID:-minioadmin}
|
||
- MINIO_ROOT_PASSWORD=${MINIO_SECRET_ACCESS_KEY:-minioadmin}
|
||
command: server --console-address ":9001" /data
|
||
volumes:
|
||
- minio_data:/data
|
||
healthcheck:
|
||
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
|
||
interval: 30s
|
||
timeout: 20s
|
||
retries: 3
|
||
networks:
|
||
- WeKnora-network
|
||
profiles:
|
||
- minio
|
||
- full
|
||
|
||
jaeger:
|
||
image: jaegertracing/all-in-one:1.76.0
|
||
container_name: WeKnora-jaeger
|
||
ports:
|
||
- "6831:6831/udp" # Jaeger Thrift接收器
|
||
- "6832:6832/udp" # Jaeger Thrift接收器(Compact)
|
||
- "5778:5778" # 配置端口
|
||
- "16686:16686" # Web UI
|
||
- "4317:4317" # OTLP gRPC接收器
|
||
- "4318:4318" # OTLP HTTP接收器
|
||
- "14250:14250" # 接收模型端口
|
||
- "14268:14268" # Jaeger HTTP接收器
|
||
- "9411:9411" # Zipkin兼容性端口
|
||
environment:
|
||
- COLLECTOR_OTLP_ENABLED=true
|
||
- COLLECTOR_ZIPKIN_HOST_PORT=:9411
|
||
volumes:
|
||
- jaeger_data:/var/lib/jaeger # 持久化 Jaeger 数据
|
||
networks:
|
||
- WeKnora-network
|
||
restart: unless-stopped
|
||
profiles:
|
||
- jaeger
|
||
- full
|
||
|
||
neo4j:
|
||
image: neo4j:2025.10.1
|
||
container_name: WeKnora-neo4j
|
||
volumes:
|
||
- neo4j-data:/data
|
||
environment:
|
||
- NEO4J_AUTH=${NEO4J_USERNAME:-neo4j}/${NEO4J_PASSWORD:-password}
|
||
- NEO4J_apoc_export_file_enabled=true
|
||
- NEO4J_apoc_import_file_enabled=true
|
||
- NEO4J_apoc_import_file_use__neo4j__config=true
|
||
- NEO4JLABS_PLUGINS=["apoc"]
|
||
ports:
|
||
- "7474:7474"
|
||
- "7687:7687"
|
||
restart: always
|
||
networks:
|
||
- WeKnora-network
|
||
profiles:
|
||
- neo4j
|
||
- full
|
||
|
||
qdrant:
|
||
image: qdrant/qdrant:v1.16.2
|
||
container_name: WeKnora-qdrant
|
||
ports:
|
||
- "${QDRANT_REST_PORT:-6333}:6333"
|
||
- "${QDRANT_PORT:-6334}:6334"
|
||
volumes:
|
||
- qdrant_data:/qdrant/storage
|
||
networks:
|
||
- WeKnora-network
|
||
restart: unless-stopped
|
||
profiles:
|
||
- qdrant
|
||
- full
|
||
|
||
milvus:
|
||
image: milvusdb/milvus:v2.6.11
|
||
container_name: WeKnora-milvus
|
||
security_opt:
|
||
- seccomp:unconfined
|
||
command: ["milvus", "run", "standalone"]
|
||
environment:
|
||
- ETCD_USE_EMBED=true
|
||
- ETCD_DATA_DIR=/var/lib/milvus/etcd
|
||
- COMMON_STORAGETYPE=local
|
||
- DEPLOY_MODE=STANDALONE
|
||
healthcheck:
|
||
test: ["CMD", "curl", "-f", "http://localhost:9091/healthz"]
|
||
interval: 30s
|
||
start_period: 90s
|
||
timeout: 20s
|
||
retries: 3
|
||
ports:
|
||
- "19530:19530"
|
||
- "9091:9091"
|
||
volumes:
|
||
- milvus_data:/var/lib/milvus
|
||
networks:
|
||
- WeKnora-network
|
||
restart: unless-stopped
|
||
profiles:
|
||
- milvus
|
||
|
||
networks:
|
||
WeKnora-network:
|
||
driver: bridge
|
||
|
||
volumes:
|
||
postgres-data:
|
||
data-files:
|
||
docreader-tmp:
|
||
jaeger_data:
|
||
minio_data:
|
||
neo4j-data:
|
||
qdrant_data:
|
||
milvus_data:
|