From 7ba15cceba37e659e8467fa9e69b2deebc56db85 Mon Sep 17 00:00:00 2001 From: YuTengjing Date: Fri, 6 Feb 2026 12:21:30 +0800 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor(docker-compose):?= =?UTF-8?q?=20restructure=20dev=20environment=20(#12132)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🔥 chore(docker-compose): remove Casdoor SSO dependency Casdoor is no longer needed since BetterAuth now supports email/password registration natively. LOBE-3907 * ♻️ refactor(docker-compose): restructure directories - Rename local/ to dev/ for development dependencies - Remove logto/ and zitadel/ from production/ - Restore Casdoor config in production/grafana/ - Simplify dev/ to core services only (postgresql, redis, rustfs, searxng) - Update docker-compose.development.yml to use dev/ - Remove minio-bucket.config.json (switched to rustfs) * ♻️ refactor(docker-compose): simplify dev environment setup - Remove docker-compose.development.yml, use dev/docker-compose.yml directly - Add npm scripts: dev:docker, dev:docker:down, dev:docker:reset - Simplify .env.example.development (remove variable refs, redundant vars) - Update docker-compose/dev/.env.example (consistent passwords) - Add docker-compose/dev/data/ to .gitignore - Update setup docs: use npm scripts, remove image generation section * 🔧 chore: add SSRF_ALLOW_PRIVATE_IP_ADDRESS to dev env example * 🔒 security: auto-generate KEY_VAULTS_SECRET and AUTH_SECRET in setup.sh - Remove hardcoded secrets from docker-compose.yml - Add placeholders to .env.example files - Generate secrets dynamically in setup.sh using openssl rand -base64 32 * 🔧 chore(docker-compose): expose SearXNG port and improve dev scripts - Add SearXNG port mapping (8180:8080) for host access - Use --wait flag in dev:docker to ensure services are healthy - Include db:migrate in dev:docker:reset for one-command reset - Update MinIO reference to RustFS in zh-CN docs - Add SearXNG to service URLs and port conflict docs --- .env.example.development | 122 +- .gitignore | 3 + docker-compose.development.yml | 90 - docker-compose/deploy/.env.example | 4 + docker-compose/deploy/.env.zh-CN.example | 6 +- docker-compose/deploy/docker-compose.yml | 4 +- .../{local/logto => dev}/.env.example | 31 +- .../{local/logto => dev}/.env.zh-CN.example | 33 +- docker-compose/{local => dev}/.gitignore | 0 docker-compose/dev/bucket.config.json | 18 + docker-compose/dev/docker-compose.yml | 122 + .../{local => dev}/searxng-settings.yml | 0 docker-compose/local/.env.example | 46 - docker-compose/local/.env.zh-CN.example | 43 - docker-compose/local/bucket.config.json | 24 - docker-compose/local/docker-compose.yml | 297 -- docker-compose/local/grafana/.env.example | 41 - .../local/grafana/.env.zh-CN.example | 41 - .../local/grafana/docker-compose.yml | 251 -- .../local/grafana/grafana/dashboards/.gitkeep | 0 .../datasources/datasource-prometheus.yaml | 15 - .../grafana/datasources/datasource-tempo.yaml | 16 - .../otel-collector/collector-config.yaml | 45 - .../local/grafana/prometheus/prometheus.yml | 11 - docker-compose/local/grafana/tempo/tempo.yaml | 58 - docker-compose/local/logto/docker-compose.yml | 124 - docker-compose/local/zitadel/.env.example | 31 - .../local/zitadel/.env.zh-CN.example | 30 - .../local/zitadel/docker-compose.yml | 86 - .../local/zitadel/zitadel-config.yaml | 26 - .../local/zitadel/zitadel-init-steps.yaml | 11 - docker-compose/minio-bucket.config.json | 34 - .../grafana}/init_data.json | 0 .../production/grafana/searxng-settings.yml | 2582 +++++++++++++++++ docker-compose/production/logto/.env.example | 52 - .../production/logto/.env.zh-CN.example | 51 - .../production/logto/docker-compose.yml | 71 - .../production/zitadel/.env.example | 49 - .../production/zitadel/.env.zh-CN.example | 44 - .../production/zitadel/docker-compose.yml | 69 - .../production/zitadel/zitadel-config.yaml | 25 - .../zitadel/zitadel-init-steps.yaml | 11 - docker-compose/setup.sh | 23 +- docs/development/basic/setup-development.mdx | 129 +- .../basic/setup-development.zh-CN.mdx | 129 +- package.json | 3 + 46 files changed, 2872 insertions(+), 2029 deletions(-) delete mode 100644 docker-compose.development.yml rename docker-compose/{local/logto => dev}/.env.example (58%) rename docker-compose/{local/logto => dev}/.env.zh-CN.example (57%) rename docker-compose/{local => dev}/.gitignore (100%) create mode 100644 docker-compose/dev/bucket.config.json create mode 100644 docker-compose/dev/docker-compose.yml rename docker-compose/{local => dev}/searxng-settings.yml (100%) delete mode 100644 docker-compose/local/.env.example delete mode 100644 docker-compose/local/.env.zh-CN.example delete mode 100644 docker-compose/local/bucket.config.json delete mode 100644 docker-compose/local/docker-compose.yml delete mode 100644 docker-compose/local/grafana/.env.example delete mode 100644 docker-compose/local/grafana/.env.zh-CN.example delete mode 100644 docker-compose/local/grafana/docker-compose.yml delete mode 100644 docker-compose/local/grafana/grafana/dashboards/.gitkeep delete mode 100644 docker-compose/local/grafana/grafana/datasources/datasource-prometheus.yaml delete mode 100644 docker-compose/local/grafana/grafana/datasources/datasource-tempo.yaml delete mode 100644 docker-compose/local/grafana/otel-collector/collector-config.yaml delete mode 100644 docker-compose/local/grafana/prometheus/prometheus.yml delete mode 100644 docker-compose/local/grafana/tempo/tempo.yaml delete mode 100644 docker-compose/local/logto/docker-compose.yml delete mode 100644 docker-compose/local/zitadel/.env.example delete mode 100644 docker-compose/local/zitadel/.env.zh-CN.example delete mode 100644 docker-compose/local/zitadel/docker-compose.yml delete mode 100644 docker-compose/local/zitadel/zitadel-config.yaml delete mode 100644 docker-compose/local/zitadel/zitadel-init-steps.yaml delete mode 100644 docker-compose/minio-bucket.config.json rename docker-compose/{local => production/grafana}/init_data.json (100%) create mode 100644 docker-compose/production/grafana/searxng-settings.yml delete mode 100644 docker-compose/production/logto/.env.example delete mode 100644 docker-compose/production/logto/.env.zh-CN.example delete mode 100644 docker-compose/production/logto/docker-compose.yml delete mode 100644 docker-compose/production/zitadel/.env.example delete mode 100644 docker-compose/production/zitadel/.env.zh-CN.example delete mode 100644 docker-compose/production/zitadel/docker-compose.yml delete mode 100644 docker-compose/production/zitadel/zitadel-config.yaml delete mode 100644 docker-compose/production/zitadel/zitadel-init-steps.yaml diff --git a/.env.example.development b/.env.example.development index 0f980072bf..c112d36ad5 100644 --- a/.env.example.development +++ b/.env.example.development @@ -1,114 +1,48 @@ -# LobeChat Development Server Configuration -# This file contains environment variables for both LobeChat server mode and Docker compose setup +# LobeChat Development Environment Configuration +# ⚠️ DO NOT USE THESE VALUES IN PRODUCTION! -COMPOSE_FILE="docker-compose.development.yml" +# Application +APP_URL=http://localhost:3010 -# ⚠️⚠️⚠️ DO NOT USE THE SECRETS BELOW IN PRODUCTION! -UNSAFE_SECRET="ww+0igxjGRAAR/eTNFQ55VmhQB5KE5trFZseuntThJs=" -UNSAFE_PASSWORD="CHANGE_THIS_PASSWORD_IN_PRODUCTION" +# Allow access to private IP addresses (localhost services) in development +# https://lobehub.com/docs/self-hosting/environment-variables/basic#ssrf-allow-private-ip-address +SSRF_ALLOW_PRIVATE_IP_ADDRESS=1 -# Core Server Configuration +# Secrets (pre-generated for development only) +KEY_VAULTS_SECRET=ww+0igxjGRAAR/eTNFQ55VmhQB5KE5trFZseuntThJs= +AUTH_SECRET=ww+0igxjGRAAR/eTNFQ55VmhQB5KE5trFZseuntThJs= -# Service Ports Configuration -LOBE_PORT=3010 - -# Application URL - the base URL where LobeChat will be accessible -APP_URL=http://localhost:${LOBE_PORT} - -# Secret key for encrypting vault data (generate with: openssl rand -base64 32) -KEY_VAULTS_SECRET=${UNSAFE_SECRET} - -# Database Configuration -# Database name for LobeChat -LOBE_DB_NAME=lobechat - -# PostgreSQL password -POSTGRES_PASSWORD=${UNSAFE_PASSWORD} - -# PostgreSQL database connection URL -DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@localhost:5432/${LOBE_DB_NAME} - -# Database driver type +# Database (PostgreSQL) +DATABASE_URL=postgresql://postgres:change_this_password_on_production@localhost:5432/lobechat DATABASE_DRIVER=node -# Redis Cache/Queue Configuration +# Redis REDIS_URL=redis://localhost:6379 REDIS_PREFIX=lobechat REDIS_TLS=0 -# Authentication Configuration -# Auth secret for JWT signing (generate with: openssl rand -base64 32) -AUTH_SECRET=${UNSAFE_SECRET} - -# SSO providers configuration - using Casdoor for development -AUTH_SSO_PROVIDERS=casdoor - -# Casdoor Configuration -# Casdoor service port -CASDOOR_PORT=8000 - -# Casdoor OIDC issuer URL -AUTH_CASDOOR_ISSUER=http://localhost:${CASDOOR_PORT} - -# Casdoor application client ID -AUTH_CASDOOR_ID=a387a4892ee19b1a2249 # DO NOT USE IN PROD - -# Casdoor application client secret -AUTH_CASDOOR_SECRET=dbf205949d704de81b0b5b3603174e23fbecc354 # DO NOT USE IN PROD - -# Origin URL for Casdoor internal configuration -origin=http://localhost:${CASDOOR_PORT} - -# MinIO Storage Configuration -# MinIO service port -MINIO_PORT=9000 - -# MinIO root user (admin username) -MINIO_ROOT_USER=admin - -# MinIO root password -MINIO_ROOT_PASSWORD=${UNSAFE_PASSWORD} - -# MinIO bucket for LobeChat files -MINIO_LOBE_BUCKET=lobe - -# S3/MinIO Configuration for LobeChat -# S3/MinIO access key ID -S3_ACCESS_KEY_ID=${MINIO_ROOT_USER} - -# S3/MinIO secret access key -S3_SECRET_ACCESS_KEY=${MINIO_ROOT_PASSWORD} - -# S3/MinIO endpoint URL -S3_ENDPOINT=http://localhost:${MINIO_PORT} - -# S3 bucket name for storing files -S3_BUCKET=${MINIO_LOBE_BUCKET} - -# Enable path-style S3 requests (required for MinIO) +# S3 Storage (RustFS) +S3_ACCESS_KEY_ID=admin +S3_SECRET_ACCESS_KEY=change_this_password_on_production +S3_ENDPOINT=http://localhost:9000 +S3_BUCKET=lobe S3_ENABLE_PATH_STYLE=1 - -# Disable S3 ACL setting (for MinIO compatibility) S3_SET_ACL=0 -# Use base64 encoding for LLM vision images +# LLM vision uses base64 to avoid S3 presigned URL issues in development LLM_VISION_IMAGE_USE_BASE64=1 -# Search Service Configuration -# SearXNG search engine URL -SEARXNG_URL=http://searxng:8080 +# Search (SearXNG) +SEARXNG_URL=http://localhost:8180 -# Development Options -# Uncomment to skip authentication during development - -# Proxy Configuration (Optional) -# Uncomment if you need proxy support (e.g., for GitHub auth or API access) +# Proxy (Optional) # HTTP_PROXY=http://localhost:7890 # HTTPS_PROXY=http://localhost:7890 -# AI Model Configuration (Optional) -# Add your AI model API keys and configurations here -# ⚠️ WARNING: Never commit real API keys to version control! -# OPENAI_API_KEY=sk-NEVER_USE_REAL_API_KEYS_IN_CONFIG_FILES +# AI Model API Keys (Required for chat functionality) +# ANTHROPIC_API_KEY=sk-ant-xxx +# ANTHROPIC_PROXY_URL=https://api.anthropic.com + +# OPENAI_API_KEY=sk-xxx # OPENAI_PROXY_URL=https://api.openai.com/v1 -# OPENAI_MODEL_LIST=... + diff --git a/.gitignore b/.gitignore index 2925b43649..c58033a8ed 100644 --- a/.gitignore +++ b/.gitignore @@ -108,6 +108,9 @@ CLAUDE.local.md # MCP tools .serena/** +# Docker development data +docker-compose/dev/data/ + # Migration scripts data scripts/clerk-to-betterauth/test/*.csv scripts/clerk-to-betterauth/test/*.json diff --git a/docker-compose.development.yml b/docker-compose.development.yml deleted file mode 100644 index 91dbe54fca..0000000000 --- a/docker-compose.development.yml +++ /dev/null @@ -1,90 +0,0 @@ -name: lobe-chat-development -services: - network-service: - image: alpine - container_name: lobe-network - restart: always - ports: - - '${MINIO_PORT}:${MINIO_PORT}' # MinIO API - - '9001:9001' # MinIO Console - - '${CASDOOR_PORT}:${CASDOOR_PORT}' # Casdoor - - '3000:3000' # Grafana - - '4318:4318' # otel-collector HTTP - - '4317:4317' # otel-collector gRPC - command: tail -f /dev/null - networks: - - lobe-network - - postgresql: - extends: - file: docker-compose/local/docker-compose.yml - service: postgresql - redis: - extends: - file: docker-compose/local/docker-compose.yml - service: redis - minio: - extends: - file: docker-compose/local/docker-compose.yml - service: minio - casdoor: - extends: - file: docker-compose/local/docker-compose.yml - service: casdoor - searxng: - extends: - file: docker-compose/local/docker-compose.yml - service: searxng - - grafana: - profiles: - - otel - extends: - file: docker-compose/local/grafana/docker-compose.yml - service: grafana - - tempo: - profiles: - - otel - extends: - file: docker-compose/local/grafana/docker-compose.yml - service: tempo - - prometheus: - profiles: - - otel - extends: - file: docker-compose/local/grafana/docker-compose.yml - service: prometheus - - otel-collector: - profiles: - - otel - extends: - file: docker-compose/local/grafana/docker-compose.yml - service: otel-collector - - otel-tracing-test: - profiles: - - otel-test - extends: - file: docker-compose/local/grafana/docker-compose.yml - service: otel-tracing-test - -volumes: - data: - driver: local - s3_data: - driver: local - grafana_data: - driver: local - tempo_data: - driver: local - prometheus_data: - driver: local - redis_data: - driver: local - -networks: - lobe-network: - driver: bridge diff --git a/docker-compose/deploy/.env.example b/docker-compose/deploy/.env.example index 8dfdc5d4ef..65947d5a11 100644 --- a/docker-compose/deploy/.env.example +++ b/docker-compose/deploy/.env.example @@ -22,6 +22,10 @@ APP_URL=http://localhost:3210 # to bypass CDN/proxy. If not set, defaults to APP_URL. # Example: INTERNAL_APP_URL=http://localhost:3210 +# Secrets (auto-generated by setup.sh) +KEY_VAULTS_SECRET=YOUR_KEY_VAULTS_SECRET +AUTH_SECRET=YOUR_AUTH_SECRET + # Postgres related, which are the necessary environment variables for DB LOBE_DB_NAME=lobechat POSTGRES_PASSWORD=uWNZugjBqixf8dxC diff --git a/docker-compose/deploy/.env.zh-CN.example b/docker-compose/deploy/.env.zh-CN.example index e9c8034923..cf4351782c 100644 --- a/docker-compose/deploy/.env.zh-CN.example +++ b/docker-compose/deploy/.env.zh-CN.example @@ -19,8 +19,12 @@ LOBE_PORT=3210 RUSTFS_PORT=9000 APP_URL=http://localhost:3210 +# 密钥配置(由 setup.sh 自动生成) +KEY_VAULTS_SECRET=YOUR_KEY_VAULTS_SECRET +AUTH_SECRET=YOUR_AUTH_SECRET + # Postgres 相关,也即 DB 必须的环境变量 -LOBE_DB_NAME=lobehub +LOBE_DB_NAME=lobechat POSTGRES_PASSWORD=uWNZugjBqixf8dxC # RustFS S3 配置 diff --git a/docker-compose/deploy/docker-compose.yml b/docker-compose/deploy/docker-compose.yml index e4e243eeb8..4b0ddef25a 100644 --- a/docker-compose/deploy/docker-compose.yml +++ b/docker-compose/deploy/docker-compose.yml @@ -117,8 +117,8 @@ services: redis: condition: service_healthy environment: - - 'KEY_VAULTS_SECRET=Kix2wcUONd4CX51E/ZPAd36BqM4wzJgKjPtz2sGztqQ=' - - 'AUTH_SECRET=NX2kaPE923dt6BL2U8e9oSre5RfoT7hg' + - 'KEY_VAULTS_SECRET=${KEY_VAULTS_SECRET}' + - 'AUTH_SECRET=${AUTH_SECRET}' - 'DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgresql:5432/${LOBE_DB_NAME}' - 'S3_BUCKET=${RUSTFS_LOBE_BUCKET}' - 'S3_ENABLE_PATH_STYLE=1' diff --git a/docker-compose/local/logto/.env.example b/docker-compose/dev/.env.example similarity index 58% rename from docker-compose/local/logto/.env.example rename to docker-compose/dev/.env.example index 9377bfe0a9..ed31f730b2 100644 --- a/docker-compose/local/logto/.env.example +++ b/docker-compose/dev/.env.example @@ -1,17 +1,3 @@ -# Logto secret -AUTH_LOGTO_ID= -AUTH_LOGTO_SECRET= -AUTH_LOGTO_ISSUER= - -# MinIO S3 configuration -MINIO_ROOT_USER=YOUR_MINIO_USER -MINIO_ROOT_PASSWORD=YOUR_MINIO_PASSWORD - -# Configure the bucket information of MinIO -MINIO_LOBE_BUCKET=lobe -S3_ACCESS_KEY_ID= -S3_SECRET_ACCESS_KEY= - # Proxy, if you need it # HTTP_PROXY=http://localhost:7890 # HTTPS_PROXY=http://localhost:7890 @@ -23,12 +9,21 @@ S3_SECRET_ACCESS_KEY= # OPENAI_MODEL_LIST=... -# ----- Other config ----- +# =========================== +# ====== Preset config ====== +# =========================== # if no special requirements, no need to change LOBE_PORT=3210 -LOGTO_PORT=3001 -MINIO_PORT=9000 +RUSTFS_PORT=9000 # Postgres related, which are the necessary environment variables for DB LOBE_DB_NAME=lobechat -POSTGRES_PASSWORD=uWNZugjBqixf8dxC +POSTGRES_PASSWORD=change_this_password_on_production + +# RUSTFS S3 configuration +RUSTFS_ACCESS_KEY=admin +RUSTFS_SECRET_KEY=change_this_password_on_production + +# Configure the bucket information of RUSTFS +S3_ENDPOINT=http://localhost:9000 +RUSTFS_LOBE_BUCKET=lobe diff --git a/docker-compose/local/logto/.env.zh-CN.example b/docker-compose/dev/.env.zh-CN.example similarity index 57% rename from docker-compose/local/logto/.env.zh-CN.example rename to docker-compose/dev/.env.zh-CN.example index a5021a9765..8665f45ddd 100644 --- a/docker-compose/local/logto/.env.zh-CN.example +++ b/docker-compose/dev/.env.zh-CN.example @@ -1,34 +1,29 @@ -# Logto 鉴权相关 -AUTH_LOGTO_ID= -AUTH_LOGTO_SECRET= -AUTH_LOGTO_ISSUER= - -# MinIO S3 配置 -MINIO_ROOT_USER=YOUR_MINIO_USER -MINIO_ROOT_PASSWORD=YOUR_MINIO_PASSWORD - -# 在下方配置 minio 中添加的桶 -MINIO_LOBE_BUCKET=lobe -S3_ACCESS_KEY_ID= -S3_SECRET_ACCESS_KEY= - - # Proxy,如果你需要的话(比如你使用 GitHub 作为鉴权服务提供商) # HTTP_PROXY=http://localhost:7890 # HTTPS_PROXY=http://localhost:7890 + # 其他环境变量,视需求而定,可以参照客户端版本的环境变量配置,注意不要有 ACCESS_CODE # OPENAI_API_KEY=sk-xxxx # OPENAI_PROXY_URL=https://api.openai.com/v1 # OPENAI_MODEL_LIST=... -# ----- 相关配置 start ----- +# =================== +# ===== 预设配置 ===== +# =================== # 如没有特殊需要不用更改 LOBE_PORT=3210 -LOGTO_PORT=3001 -MINIO_PORT=9000 +RUSTFS_PORT=9000 # Postgres 相关,也即 DB 必须的环境变量 LOBE_DB_NAME=lobechat -POSTGRES_PASSWORD=uWNZugjBqixf8dxC +POSTGRES_PASSWORD=change_this_password_on_production + +# RustFS S3 配置 +RUSTFS_ACCESS_KEY=admin +RUSTFS_SECRET_KEY=change_this_password_on_production + +# RustFS bucket 配置 +S3_ENDPOINT=http://localhost:9000 +RUSTFS_LOBE_BUCKET=lobe diff --git a/docker-compose/local/.gitignore b/docker-compose/dev/.gitignore similarity index 100% rename from docker-compose/local/.gitignore rename to docker-compose/dev/.gitignore diff --git a/docker-compose/dev/bucket.config.json b/docker-compose/dev/bucket.config.json new file mode 100644 index 0000000000..e0cbd3bbd3 --- /dev/null +++ b/docker-compose/dev/bucket.config.json @@ -0,0 +1,18 @@ +{ + "ID": "", + "Statement": [ + { + "Sid": "", + "Effect": "Allow", + "Principal": { + "AWS": ["*"] + }, + "Action": ["s3:GetObject"], + "NotAction": [], + "Resource": ["arn:aws:s3:::lobe/*"], + "NotResource": [], + "Condition": {} + } + ], + "Version": "2012-10-17" +} diff --git a/docker-compose/dev/docker-compose.yml b/docker-compose/dev/docker-compose.yml new file mode 100644 index 0000000000..e3da0d55d8 --- /dev/null +++ b/docker-compose/dev/docker-compose.yml @@ -0,0 +1,122 @@ +name: lobehub +services: + network-service: + image: alpine + container_name: lobe-network + restart: always + ports: + - '${RUSTFS_PORT}:9000' # RustFS API + - '9001:9001' # RustFS Console + - '${LOBE_PORT}:3210' # LobeChat + command: tail -f /dev/null + networks: + - lobe-network + env_file: + - .env + + postgresql: + image: pgvector/pgvector:pg17 + container_name: lobe-postgres + ports: + - '5432:5432' + volumes: + - './data:/var/lib/postgresql/data' + environment: + - 'POSTGRES_DB=${LOBE_DB_NAME}' + - 'POSTGRES_PASSWORD=${POSTGRES_PASSWORD}' + healthcheck: + test: ['CMD-SHELL', 'pg_isready -U postgres'] + interval: 5s + timeout: 5s + retries: 5 + restart: always + networks: + - lobe-network + env_file: + - .env + + redis: + image: redis:7-alpine + container_name: lobe-redis + ports: + - '6379:6379' + command: redis-server --save 60 1000 --appendonly yes + volumes: + - 'redis_data:/data' + healthcheck: + test: ['CMD', 'redis-cli', 'ping'] + interval: 5s + timeout: 3s + retries: 5 + restart: always + networks: + - lobe-network + + rustfs: + image: rustfs/rustfs:latest + container_name: lobe-rustfs + network_mode: 'service:network-service' + environment: + - RUSTFS_CONSOLE_ENABLE=true + - RUSTFS_ACCESS_KEY=${RUSTFS_ACCESS_KEY} + - RUSTFS_SECRET_KEY=${RUSTFS_SECRET_KEY} + volumes: + - rustfs-data:/data + healthcheck: + test: ["CMD-SHELL", "wget -qO- http://localhost:9000/health >/dev/null 2>&1 || exit 1"] + interval: 5s + timeout: 3s + retries: 30 + command: ["--access-key","${RUSTFS_ACCESS_KEY}","--secret-key","${RUSTFS_SECRET_KEY}","/data"] + env_file: + - .env + + rustfs-init: + image: minio/mc:latest + container_name: lobe-rustfs-init + depends_on: + rustfs: + condition: service_healthy + volumes: + - ./bucket.config.json:/bucket.config.json:ro + entrypoint: /bin/sh + command: -c ' + set -eux; + echo "S3_ACCESS_KEY=${RUSTFS_ACCESS_KEY}, S3_SECRET_KEY=${RUSTFS_SECRET_KEY}"; + mc --version; + mc alias set rustfs "http://network-service:9000" "${RUSTFS_ACCESS_KEY}" "${RUSTFS_SECRET_KEY}"; + mc ls rustfs || true; + mc mb "rustfs/lobe" --ignore-existing; + mc admin info rustfs || true; + mc anonymous set-json "/bucket.config.json" "rustfs/lobe"; + ' + restart: "no" + networks: + - lobe-network + env_file: + - .env + + searxng: + image: searxng/searxng + container_name: lobe-searxng + ports: + - '8180:8080' + volumes: + - './searxng-settings.yml:/etc/searxng/settings.yml' + environment: + - 'SEARXNG_SETTINGS_FILE=/etc/searxng/settings.yml' + restart: always + networks: + - lobe-network + +volumes: + data: + driver: local + redis_data: + driver: local + rustfs-data: + driver: local + +networks: + lobe-network: + driver: bridge diff --git a/docker-compose/local/searxng-settings.yml b/docker-compose/dev/searxng-settings.yml similarity index 100% rename from docker-compose/local/searxng-settings.yml rename to docker-compose/dev/searxng-settings.yml diff --git a/docker-compose/local/.env.example b/docker-compose/local/.env.example deleted file mode 100644 index 4371008ebd..0000000000 --- a/docker-compose/local/.env.example +++ /dev/null @@ -1,46 +0,0 @@ -# Proxy, if you need it -# HTTP_PROXY=http://localhost:7890 -# HTTPS_PROXY=http://localhost:7890 - - -# Other environment variables, as needed. You can refer to the environment variables configuration for the client version, making sure not to have ACCESS_CODE. -# OPENAI_API_KEY=sk-xxxx -# OPENAI_PROXY_URL=https://api.openai.com/v1 -# OPENAI_MODEL_LIST=... - - -# =========================== -# ====== Preset config ====== -# =========================== -# if no special requirements, no need to change -LOBE_PORT=3210 -CASDOOR_PORT=8000 -RUSTFS_PORT=9000 -APP_URL=http://localhost:3210 -# INTERNAL_APP_URL is optional, used for server-to-server calls -# to bypass CDN/proxy. If not set, defaults to APP_URL. -# Example: INTERNAL_APP_URL=http://localhost:3210 - -# Postgres related, which are the necessary environment variables for DB -LOBE_DB_NAME=lobechat -POSTGRES_PASSWORD=uWNZugjBqixf8dxC - -AUTH_SSO_PROVIDERS=casdoor -AUTH_CASDOOR_ISSUER=http://localhost:8000 -# Casdoor secret -AUTH_CASDOOR_ID=a387a4892ee19b1a2249 -AUTH_CASDOOR_SECRET=dbf205949d704de81b0b5b3603174e23fbecc354 -CASDOOR_WEBHOOK_SECRET=casdoor-secret - -# RUSTFS S3 configuration -RUSTFS_ACCESS_KEY=admin -RUSTFS_SECRET_KEY=YOUR_RUSTFS_PASSWORD - -# Configure the bucket information of RUSTFS -S3_ENDPOINT=http://localhost:9000 -RUSTFS_LOBE_BUCKET=lobe - -# Configure for casdoor -origin=http://localhost:8000 - -JWKS_KEY={"keys":[{"d":"PVoFyqyrGstB8wU52S7gqqQQdZLtin_thcEM0nrNtqp9U-NlKLlhgEcWp5t89ycgvhsAzmrRbezGj4JBTr3jn7eWdwQpPJNYiipnsgeJn0pwsB0H2dMqtavxinoPVXkMTOuGHMTFhhyguFBw2JbIL0PTQUcUlXjv40OoJpYHZeggSxgfV-TuxjwW8Ll4-n84M5IOi6A53RvioE-Hm1iyIc2XLBCfyOu-SbAQYi8HzrA64kCxobAB0peLQMiAzfZmwPKiGOhnhKrAlYmG02qFnbUYiJu_-AXwsAyGv9S9i6dwK7QXaGGWYyis8LlPpd_JmPrBnrWomwDlI045NUMWZQ","dp":"OSXI2NBBZl2r0Dpf4-1z44A_jC5lOyXtJhXQYnSXy5eIuxTJcEtkUYagGEwnREO4Q3t-4J-lT_6Y71M1ZlgKG1upwfw1O4aE3vGpHOik9iZYYCjA8fe5uBfOpX1ELmOtHNoHRhMtyjuPxSFXLlSp3bgcF1f3F40ClukdvXCx0Mc","dq":"m6hNdfj-F8E_7nUlX2nG95OffkFrhHTo67ML9aPgpvFwBlzg-hk5LwtxMfUzngqWF78TMl0JDm7vS1bz0xlWqXqu8pFPoTUnUoWgYfvuyHLBwR5TgccQkfoKbkSMzYNy8VJPXZeyIjVXsW98tZvj-NZF-M9Pke_EWJm-jjXCu_8","e":"AQAB","kty":"RSA","n":"piffosMS0HOSgsSr_zQkXYaQt1kOCD73VR0b2XJD6UdQCKPbnBOzTIuA_xowX61QVsl5pCZLTw8ERC3r2Nlxj5Rp_H6RuOT7ioUqlbnxSGnfuAn8dFupY3A-sf9HVDOvtJdlS-nO9yA4wWU-A50zZ1Mf0pPZlUZE6dUQfsJFi5yXaNAybyk3U4VpMO_SXAilWEHVhiO0F0ccpJMCkT47AeXmYH9MlWwIGcay0UiAsdrs8J-q1arZ7Mbq0oxHmUXJG0vwRvAL8KnCEi8cJ3e2kKCRcr-BQCujsHUyUl6f_ATwSVuTHdAR1IzIcW37v27h3WQK_v0ffQM1NstamDX5vQ","p":"4myVm2M5cZGvVXsOmWUTUG87VC1GlQcL5tmMNSGSpQCL8yWZ1vANkmCxSMptrKB4dU9DAB3On6_oMhW1pJ3uYNGSW49BcmJoLkiWKeg5zWFnKPQNuThQmY1sCCubtKhBQgaYUr7TVzN9smrDV3zCu9MlRl-XPwnEmWaDII3g-f8","q":"u9v4IOEsb4l2Y3eWKE2bwJh5fJRR4vivaYA7U-1-OpvDwB3A48Rey9IL1ucXqE5G1Du8BtijPm5oSAar5uzrjtg1bZ9gevif6DnBGaIRE7LnSrUsTPfZwzntJ1rTaGiVe_pAdnTKXXaH6DxygXxH4wvGgA44V3TTfBXQUcjzdEM","qi":"lDBnSPKkRnYqQvbqVD1LxzqBPEeqEA3GyCqMj6fIZNgoEaBSLi0TSsUyGZ5mahX3KO35vKAZa5jvGjhvUGUiXycq8KvRZdeGK45vJdwZT2TiXiDwo9IQgJcbFMpxaB9DhjX2x0yqxgUY5ca75jLqbMuKBKBN0PVqIr9jlHkR8_s","use":"sig","kid":"6823046760c5d460","alg":"RS256"}]} \ No newline at end of file diff --git a/docker-compose/local/.env.zh-CN.example b/docker-compose/local/.env.zh-CN.example deleted file mode 100644 index d96818a0b0..0000000000 --- a/docker-compose/local/.env.zh-CN.example +++ /dev/null @@ -1,43 +0,0 @@ -# Proxy,如果你需要的话(比如你使用 GitHub 作为鉴权服务提供商) -# HTTP_PROXY=http://localhost:7890 -# HTTPS_PROXY=http://localhost:7890 - - -# 其他环境变量,视需求而定,可以参照客户端版本的环境变量配置,注意不要有 ACCESS_CODE -# OPENAI_API_KEY=sk-xxxx -# OPENAI_PROXY_URL=https://api.openai.com/v1 -# OPENAI_MODEL_LIST=... - - -# =================== -# ===== 预设配置 ===== -# =================== -# 如没有特殊需要不用更改 -LOBE_PORT=3210 -CASDOOR_PORT=8000 -RUSTFS_PORT=9000 -APP_URL=http://localhost:3210 - -# Postgres 相关,也即 DB 必须的环境变量 -LOBE_DB_NAME=lobechat -POSTGRES_PASSWORD=uWNZugjBqixf8dxC - -AUTH_SSO_PROVIDERS=casdoor -AUTH_CASDOOR_ISSUER=http://localhost:8000 -# Casdoor secret -AUTH_CASDOOR_ID=a387a4892ee19b1a2249 -AUTH_CASDOOR_SECRET=dbf205949d704de81b0b5b3603174e23fbecc354 -CASDOOR_WEBHOOK_SECRET=casdoor-secret - -# RustFS S3 配置 -RUSTFS_ACCESS_KEY=admin -RUSTFS_SECRET_KEY=YOUR_RUSTFS_PASSWORD - -# 在下方配置 rustfs 中添加的桶 -S3_ENDPOINT=http://localhost:9000 -RUSTFS_LOBE_BUCKET=lobe - -# 为 casdoor 配置 -origin=http://localhost:8000 - -JWKS_KEY={"keys":[{"d":"PVoFyqyrGstB8wU52S7gqqQQdZLtin_thcEM0nrNtqp9U-NlKLlhgEcWp5t89ycgvhsAzmrRbezGj4JBTr3jn7eWdwQpPJNYiipnsgeJn0pwsB0H2dMqtavxinoPVXkMTOuGHMTFhhyguFBw2JbIL0PTQUcUlXjv40OoJpYHZeggSxgfV-TuxjwW8Ll4-n84M5IOi6A53RvioE-Hm1iyIc2XLBCfyOu-SbAQYi8HzrA64kCxobAB0peLQMiAzfZmwPKiGOhnhKrAlYmG02qFnbUYiJu_-AXwsAyGv9S9i6dwK7QXaGGWYyis8LlPpd_JmPrBnrWomwDlI045NUMWZQ","dp":"OSXI2NBBZl2r0Dpf4-1z44A_jC5lOyXtJhXQYnSXy5eIuxTJcEtkUYagGEwnREO4Q3t-4J-lT_6Y71M1ZlgKG1upwfw1O4aE3vGpHOik9iZYYCjA8fe5uBfOpX1ELmOtHNoHRhMtyjuPxSFXLlSp3bgcF1f3F40ClukdvXCx0Mc","dq":"m6hNdfj-F8E_7nUlX2nG95OffkFrhHTo67ML9aPgpvFwBlzg-hk5LwtxMfUzngqWF78TMl0JDm7vS1bz0xlWqXqu8pFPoTUnUoWgYfvuyHLBwR5TgccQkfoKbkSMzYNy8VJPXZeyIjVXsW98tZvj-NZF-M9Pke_EWJm-jjXCu_8","e":"AQAB","kty":"RSA","n":"piffosMS0HOSgsSr_zQkXYaQt1kOCD73VR0b2XJD6UdQCKPbnBOzTIuA_xowX61QVsl5pCZLTw8ERC3r2Nlxj5Rp_H6RuOT7ioUqlbnxSGnfuAn8dFupY3A-sf9HVDOvtJdlS-nO9yA4wWU-A50zZ1Mf0pPZlUZE6dUQfsJFi5yXaNAybyk3U4VpMO_SXAilWEHVhiO0F0ccpJMCkT47AeXmYH9MlWwIGcay0UiAsdrs8J-q1arZ7Mbq0oxHmUXJG0vwRvAL8KnCEi8cJ3e2kKCRcr-BQCujsHUyUl6f_ATwSVuTHdAR1IzIcW37v27h3WQK_v0ffQM1NstamDX5vQ","p":"4myVm2M5cZGvVXsOmWUTUG87VC1GlQcL5tmMNSGSpQCL8yWZ1vANkmCxSMptrKB4dU9DAB3On6_oMhW1pJ3uYNGSW49BcmJoLkiWKeg5zWFnKPQNuThQmY1sCCubtKhBQgaYUr7TVzN9smrDV3zCu9MlRl-XPwnEmWaDII3g-f8","q":"u9v4IOEsb4l2Y3eWKE2bwJh5fJRR4vivaYA7U-1-OpvDwB3A48Rey9IL1ucXqE5G1Du8BtijPm5oSAar5uzrjtg1bZ9gevif6DnBGaIRE7LnSrUsTPfZwzntJ1rTaGiVe_pAdnTKXXaH6DxygXxH4wvGgA44V3TTfBXQUcjzdEM","qi":"lDBnSPKkRnYqQvbqVD1LxzqBPEeqEA3GyCqMj6fIZNgoEaBSLi0TSsUyGZ5mahX3KO35vKAZa5jvGjhvUGUiXycq8KvRZdeGK45vJdwZT2TiXiDwo9IQgJcbFMpxaB9DhjX2x0yqxgUY5ca75jLqbMuKBKBN0PVqIr9jlHkR8_s","use":"sig","kid":"6823046760c5d460","alg":"RS256"}]} \ No newline at end of file diff --git a/docker-compose/local/bucket.config.json b/docker-compose/local/bucket.config.json deleted file mode 100644 index ceac834a98..0000000000 --- a/docker-compose/local/bucket.config.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "ID": "", - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "", - "Effect": "Allow", - "Principal": { - "AWS": [ - "*" - ] - }, - "Action": [ - "s3:GetObject" - ], - "NotAction": [], - "Resource": [ - "arn:aws:s3:::lobe/*" - ], - "NotResource": [], - "Condition": {} - } - ] -} \ No newline at end of file diff --git a/docker-compose/local/docker-compose.yml b/docker-compose/local/docker-compose.yml deleted file mode 100644 index 89759ef9dc..0000000000 --- a/docker-compose/local/docker-compose.yml +++ /dev/null @@ -1,297 +0,0 @@ -name: lobehub -services: - network-service: - image: alpine - container_name: lobe-network - restart: always - ports: - - '${RUSTFS_PORT}:9000' # RustFS API - - '9001:9001' # RustFS Console - - '${CASDOOR_PORT}:${CASDOOR_PORT}' # Casdoor - - '${LOBE_PORT}:3210' # LobeChat - - '3000:3000' # Grafana - - '4318:4318' # otel-collector HTTP - - '4317:4317' # otel-collector gRPC - command: tail -f /dev/null - networks: - - lobe-network - - postgresql: - image: pgvector/pgvector:pg17 - container_name: lobe-postgres - ports: - - '5432:5432' - volumes: - - './data:/var/lib/postgresql/data' - environment: - - 'POSTGRES_DB=${LOBE_DB_NAME}' - - 'POSTGRES_PASSWORD=${POSTGRES_PASSWORD}' - healthcheck: - test: ['CMD-SHELL', 'pg_isready -U postgres'] - interval: 5s - timeout: 5s - retries: 5 - restart: always - networks: - - lobe-network - - redis: - image: redis:7-alpine - container_name: lobe-redis - ports: - - '6379:6379' - command: redis-server --save 60 1000 --appendonly yes - volumes: - - 'redis_data:/data' - healthcheck: - test: ['CMD', 'redis-cli', 'ping'] - interval: 5s - timeout: 3s - retries: 5 - restart: always - networks: - - lobe-network - - - rustfs: - image: rustfs/rustfs:latest - container_name: lobe-rustfs - network_mode: 'service:network-service' - environment: - - RUSTFS_CONSOLE_ENABLE=true - - RUSTFS_ACCESS_KEY=${RUSTFS_ACCESS_KEY} - - RUSTFS_SECRET_KEY=${RUSTFS_SECRET_KEY} - volumes: - - rustfs-data:/data - healthcheck: - test: ["CMD-SHELL", "wget -qO- http://localhost:9000/health >/dev/null 2>&1 || exit 1"] - interval: 5s - timeout: 3s - retries: 30 - command: ["--access-key","${RUSTFS_ACCESS_KEY}","--secret-key","${RUSTFS_SECRET_KEY}","/data"] - - rustfs-init: - image: minio/mc:latest - container_name: lobe-rustfs-init - depends_on: - rustfs: - condition: service_healthy - volumes: - - ./bucket.config.json:/bucket.config.json:ro - entrypoint: /bin/sh - command: -c ' - set -eux; - echo "S3_ACCESS_KEY=${RUSTFS_ACCESS_KEY}, S3_SECRET_KEY=${RUSTFS_SECRET_KEY}"; - mc --version; - mc alias set rustfs "http://network-service:9000" "${RUSTFS_ACCESS_KEY}" "${RUSTFS_SECRET_KEY}"; - mc ls rustfs || true; - mc mb "rustfs/lobe" --ignore-existing; - mc admin info rustfs || true; - mc anonymous set-json "/bucket.config.json" "rustfs/lobe"; - ' - restart: "no" - networks: - - lobe-network - - # version lock ref: https://github.com/lobehub/lobe-chat/pull/7331 - casdoor: - image: casbin/casdoor:v2.13.0 - container_name: lobe-casdoor - entrypoint: /bin/sh -c './server --createDatabase=true' - network_mode: 'service:network-service' - depends_on: - postgresql: - condition: service_healthy - environment: - httpport: ${CASDOOR_PORT} - RUNNING_IN_DOCKER: 'true' - driverName: 'postgres' - dataSourceName: 'user=postgres password=${POSTGRES_PASSWORD} host=postgresql port=5432 sslmode=disable dbname=casdoor' - runmode: 'dev' - volumes: - - ./init_data.json:/init_data.json - env_file: - - .env - - searxng: - image: searxng/searxng - container_name: lobe-searxng - volumes: - - './searxng-settings.yml:/etc/searxng/settings.yml' - environment: - - 'SEARXNG_SETTINGS_FILE=/etc/searxng/settings.yml' - restart: always - networks: - - lobe-network - env_file: - - .env - - lobe: - image: lobehub/lobehub - container_name: lobehub - network_mode: 'service:network-service' - depends_on: - postgresql: - condition: service_healthy - network-service: - condition: service_started - rustfs: - condition: service_healthy - rustfs-init: - condition: service_completed_successfully - casdoor: - condition: service_started - redis: - condition: service_healthy - - environment: - - 'AUTH_SSO_PROVIDERS=casdoor' - - 'KEY_VAULTS_SECRET=Kix2wcUONd4CX51E/ZPAd36BqM4wzJgKjPtz2sGztqQ=' - - 'AUTH_SECRET=NX2kaPE923dt6BL2U8e9oSre5RfoT7hg' - - 'DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgresql:5432/${LOBE_DB_NAME}' - - 'S3_BUCKET=${RUSTFS_LOBE_BUCKET}' - - 'S3_ENABLE_PATH_STYLE=1' - - 'S3_ACCESS_KEY=${RUSTFS_ACCESS_KEY}' - - 'S3_ACCESS_KEY_ID=${RUSTFS_ACCESS_KEY}' - - 'S3_SECRET_ACCESS_KEY=${RUSTFS_SECRET_KEY}' - - 'LLM_VISION_IMAGE_USE_BASE64=1' - - 'S3_SET_ACL=0' - - 'SEARXNG_URL=http://searxng:8080' - - 'REDIS_URL=redis://redis:6379' - - 'REDIS_PREFIX=lobechat' - - 'REDIS_TLS=0' - env_file: - - .env - restart: always - entrypoint: > - /bin/sh -c " - /bin/node /app/startServer.js & - LOBE_PID=\$! - sleep 3 - if [ $(wget --timeout=5 --spider --server-response ${AUTH_CASDOOR_ISSUER}/.well-known/openid-configuration 2>&1 | grep -c 'HTTP/1.1 200 OK') -eq 0 ]; then - echo '⚠️Warning: Unable to fetch OIDC configuration from Casdoor' - echo 'Request URL: ${AUTH_CASDOOR_ISSUER}/.well-known/openid-configuration' - echo 'Read more at: https://lobehub.com/docs/self-hosting/server-database/docker-compose#necessary-configuration' - echo '' - echo '⚠️注意:无法从 Casdoor 获取 OIDC 配置' - echo '请求 URL: ${AUTH_CASDOOR_ISSUER}/.well-known/openid-configuration' - echo '了解更多:https://lobehub.com/zh/docs/self-hosting/server-database/docker-compose#necessary-configuration' - echo '' - else - if ! wget -O - --timeout=5 ${AUTH_CASDOOR_ISSUER}/.well-known/openid-configuration 2>&1 | grep 'issuer' | grep ${AUTH_CASDOOR_ISSUER}; then - printf '❌Error: The Auth issuer is conflict, Issuer in OIDC configuration is: %s' \$(wget -O - --timeout=5 ${AUTH_CASDOOR_ISSUER}/.well-known/openid-configuration 2>&1 | grep -E 'issuer.*' | awk -F '\"' '{print \$4}') - echo ' , but the issuer in .env file is: ${AUTH_CASDOOR_ISSUER} ' - echo 'Request URL: ${AUTH_CASDOOR_ISSUER}/.well-known/openid-configuration' - echo 'Read more at: https://lobehub.com/docs/self-hosting/server-database/docker-compose#necessary-configuration' - echo '' - printf '❌错误:Auth 的 issuer 冲突,OIDC 配置中的 issuer 是:%s' \$(wget -O - --timeout=5 ${AUTH_CASDOOR_ISSUER}/.well-known/openid-configuration 2>&1 | grep -E 'issuer.*' | awk -F '\"' '{print \$4}') - echo ' , 但 .env 文件中的 issuer 是:${AUTH_CASDOOR_ISSUER} ' - echo '请求 URL: ${AUTH_CASDOOR_ISSUER}/.well-known/openid-configuration' - echo '了解更多:https://lobehub.com/zh/docs/self-hosting/server-database/docker-compose#necessary-configuration' - echo '' - fi - fi - if [ $(wget --timeout=5 --spider --server-response ${S3_ENDPOINT}/health 2>&1 | grep -c 'HTTP/1.1 200 OK') -eq 0 ]; then - echo '⚠️Warning: Unable to fetch RustFS health status' - echo 'Request URL: ${S3_ENDPOINT}/health' - echo 'Read more at: https://lobehub.com/docs/self-hosting/server-database/docker-compose#necessary-configuration' - echo '' - echo '⚠️注意:无法获取 RustFS 健康状态' - echo '请求 URL: ${S3_ENDPOINT}/health' - echo '了解更多:https://lobehub.com/zh/docs/self-hosting/server-database/docker-compose#necessary-configuration' - echo '' - fi - wait \$LOBE_PID - " - - grafana: - profiles: - - otel - image: grafana/grafana:12.2.0-17419259409 - container_name: lobe-grafana - network_mode: 'service:network-service' - restart: always - environment: - - GF_AUTH_ANONYMOUS_ENABLED=true - - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin - - GF_AUTH_DISABLE_LOGIN_FORM=true - - GF_FEATURE_TOGGLES_ENABLE=traceqlEditor - volumes: - - grafana_data:/var/lib/grafana - - ./grafana/dashboards:/etc/grafana/provisioning/dashboards - - ./grafana/datasources:/etc/grafana/provisioning/datasources - depends_on: - - tempo - - prometheus - - tempo: - profiles: - - otel - image: grafana/tempo:latest - container_name: lobe-tempo - network_mode: 'service:network-service' - restart: always - volumes: - - ./tempo/tempo.yaml:/etc/tempo.yaml - - tempo_data:/var/tempo - command: ['-config.file=/etc/tempo.yaml'] - - prometheus: - profiles: - - otel - image: prom/prometheus - container_name: lobe-prometheus - network_mode: 'service:network-service' - restart: always - volumes: - - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml - - prometheus_data:/prometheus - command: - - '--config.file=/etc/prometheus/prometheus.yml' - - '--web.enable-otlp-receiver' - - '--web.enable-remote-write-receiver' - - '--enable-feature=exemplar-storage' - - otel-collector: - profiles: - - otel - image: otel/opentelemetry-collector - container_name: lobe-otel-collector - network_mode: 'service:network-service' - restart: always - volumes: - - ./otel-collector/collector-config.yaml:/etc/otelcol/config.yaml - command: ['--config', '/etc/otelcol/config.yaml'] - depends_on: - - tempo - - prometheus - - otel-tracing-test: - profiles: - - otel-test - image: ghcr.io/grafana/xk6-client-tracing:v0.0.9 - container_name: lobe-otel-tracing-test - network_mode: 'service:network-service' - restart: always - environment: - - ENDPOINT=127.0.0.1:4317 - -volumes: - data: - driver: local - s3_data: - driver: local - grafana_data: - driver: local - tempo_data: - driver: local - prometheus_data: - driver: local - redis_data: - driver: local - rustfs-data: - driver: local - -networks: - lobe-network: - driver: bridge diff --git a/docker-compose/local/grafana/.env.example b/docker-compose/local/grafana/.env.example deleted file mode 100644 index e9c22ccc87..0000000000 --- a/docker-compose/local/grafana/.env.example +++ /dev/null @@ -1,41 +0,0 @@ -# Proxy, if you need it -# HTTP_PROXY=http://localhost:7890 -# HTTPS_PROXY=http://localhost:7890 - - -# Other environment variables, as needed. You can refer to the environment variables configuration for the client version, making sure not to have ACCESS_CODE. -# OPENAI_API_KEY=sk-xxxx -# OPENAI_PROXY_URL=https://api.openai.com/v1 -# OPENAI_MODEL_LIST=... - - -# =========================== -# ====== Preset config ====== -# =========================== -# if no special requirements, no need to change -LOBE_PORT=3210 -CASDOOR_PORT=8000 -MINIO_PORT=9000 -APP_URL=http://localhost:3210 -AUTH_URL=http://localhost:3210/api/auth - -# Postgres related, which are the necessary environment variables for DB -LOBE_DB_NAME=lobechat -POSTGRES_PASSWORD=uWNZugjBqixf8dxC - -AUTH_CASDOOR_ISSUER=http://localhost:8000 -# Casdoor secret -AUTH_CASDOOR_ID=a387a4892ee19b1a2249 -AUTH_CASDOOR_SECRET=dbf205949d704de81b0b5b3603174e23fbecc354 -CASDOOR_WEBHOOK_SECRET=casdoor-secret - -# MinIO S3 configuration -MINIO_ROOT_USER=admin -MINIO_ROOT_PASSWORD=YOUR_MINIO_PASSWORD - -# Configure the bucket information of MinIO -S3_ENDPOINT=http://localhost:9000 -MINIO_LOBE_BUCKET=lobe - -# Configure for casdoor -origin=http://localhost:8000 \ No newline at end of file diff --git a/docker-compose/local/grafana/.env.zh-CN.example b/docker-compose/local/grafana/.env.zh-CN.example deleted file mode 100644 index a144db373f..0000000000 --- a/docker-compose/local/grafana/.env.zh-CN.example +++ /dev/null @@ -1,41 +0,0 @@ -# Proxy,如果你需要的话(比如你使用 GitHub 作为鉴权服务提供商) -# HTTP_PROXY=http://localhost:7890 -# HTTPS_PROXY=http://localhost:7890 - - -# 其他环境变量,视需求而定,可以参照客户端版本的环境变量配置,注意不要有 ACCESS_CODE -# OPENAI_API_KEY=sk-xxxx -# OPENAI_PROXY_URL=https://api.openai.com/v1 -# OPENAI_MODEL_LIST=... - - -# =================== -# ===== 预设配置 ===== -# =================== -# 如没有特殊需要不用更改 -LOBE_PORT=3210 -CASDOOR_PORT=8000 -MINIO_PORT=9000 -APP_URL=http://localhost:3210 -AUTH_URL=http://localhost:3210/api/auth - -# Postgres 相关,也即 DB 必须的环境变量 -LOBE_DB_NAME=lobechat -POSTGRES_PASSWORD=uWNZugjBqixf8dxC - -AUTH_CASDOOR_ISSUER=http://localhost:8000 -# Casdoor secret -AUTH_CASDOOR_ID=a387a4892ee19b1a2249 -AUTH_CASDOOR_SECRET=dbf205949d704de81b0b5b3603174e23fbecc354 -CASDOOR_WEBHOOK_SECRET=casdoor-secret - -# MinIO S3 配置 -MINIO_ROOT_USER=admin -MINIO_ROOT_PASSWORD=YOUR_MINIO_PASSWORD - -# 在下方配置 minio 中添加的桶 -S3_ENDPOINT=http://localhost:9000 -MINIO_LOBE_BUCKET=lobe - -# 为 casdoor 配置 -origin=http://localhost:8000 \ No newline at end of file diff --git a/docker-compose/local/grafana/docker-compose.yml b/docker-compose/local/grafana/docker-compose.yml deleted file mode 100644 index 506bf8d21f..0000000000 --- a/docker-compose/local/grafana/docker-compose.yml +++ /dev/null @@ -1,251 +0,0 @@ -name: lobehub -services: - network-service: - image: alpine - container_name: lobe-network - restart: always - ports: - - '${MINIO_PORT}:${MINIO_PORT}' # MinIO API - - '9001:9001' # MinIO Console - - '${CASDOOR_PORT}:${CASDOOR_PORT}' # Casdoor - - '${LOBE_PORT}:3210' # LobeChat - - '3000:3000' # Grafana - - '4318:4318' # otel-collector HTTP - - '4317:4317' # otel-collector gRPC - command: tail -f /dev/null - networks: - - lobe-network - - postgresql: - image: pgvector/pgvector:pg17 - container_name: lobe-postgres - ports: - - '5432:5432' - volumes: - - './data:/var/lib/postgresql/data' - environment: - - 'POSTGRES_DB=${LOBE_DB_NAME}' - - 'POSTGRES_PASSWORD=${POSTGRES_PASSWORD}' - healthcheck: - test: ['CMD-SHELL', 'pg_isready -U postgres'] - interval: 5s - timeout: 5s - retries: 5 - restart: always - networks: - - lobe-network - - minio: - image: minio/minio:RELEASE.2025-04-22T22-12-26Z - container_name: lobe-minio - network_mode: 'service:network-service' - volumes: - - './s3_data:/etc/minio/data' - environment: - - 'MINIO_API_CORS_ALLOW_ORIGIN=*' - env_file: - - .env - restart: always - entrypoint: > - /bin/sh -c " - minio server /etc/minio/data --address ':${MINIO_PORT}' --console-address ':9001' & - MINIO_PID=\$! - while ! curl -s http://localhost:${MINIO_PORT}/minio/health/live; do - echo 'Waiting for MinIO to start...' - sleep 1 - done - sleep 5 - mc alias set myminio http://localhost:${MINIO_PORT} ${MINIO_ROOT_USER} ${MINIO_ROOT_PASSWORD} - echo 'Creating bucket ${MINIO_LOBE_BUCKET}' - mc mb myminio/${MINIO_LOBE_BUCKET} - wait \$MINIO_PID - " - - # version lock ref: https://github.com/lobehub/lobe-chat/pull/7331 - casdoor: - image: casbin/casdoor:v2.13.0 - container_name: lobe-casdoor - entrypoint: /bin/sh -c './server --createDatabase=true' - network_mode: 'service:network-service' - depends_on: - postgresql: - condition: service_healthy - environment: - httpport: ${CASDOOR_PORT} - RUNNING_IN_DOCKER: 'true' - driverName: 'postgres' - dataSourceName: 'user=postgres password=${POSTGRES_PASSWORD} host=postgresql port=5432 sslmode=disable dbname=casdoor' - runmode: 'dev' - volumes: - - ./init_data.json:/init_data.json - env_file: - - .env - - searxng: - image: searxng/searxng - container_name: lobe-searxng - volumes: - - './searxng-settings.yml:/etc/searxng/settings.yml' - environment: - - 'SEARXNG_SETTINGS_FILE=/etc/searxng/settings.yml' - restart: always - networks: - - lobe-network - env_file: - - .env - - grafana: - image: grafana/grafana:12.2.0-17419259409 - container_name: lobe-grafana - network_mode: 'service:network-service' - restart: always - environment: - - GF_AUTH_ANONYMOUS_ENABLED=true - - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin - - GF_AUTH_DISABLE_LOGIN_FORM=true - - GF_FEATURE_TOGGLES_ENABLE=traceqlEditor - volumes: - - grafana_data:/var/lib/grafana - - ./grafana/dashboards:/etc/grafana/provisioning/dashboards - - ./grafana/datasources:/etc/grafana/provisioning/datasources - depends_on: - - tempo - - prometheus - - tempo: - image: grafana/tempo:latest - container_name: lobe-tempo - network_mode: 'service:network-service' - restart: always - volumes: - - ./tempo/tempo.yaml:/etc/tempo.yaml - - tempo_data:/var/tempo - command: ['-config.file=/etc/tempo.yaml'] - - prometheus: - image: prom/prometheus - container_name: lobe-prometheus - network_mode: 'service:network-service' - restart: always - volumes: - - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml - - prometheus_data:/prometheus - command: - - '--config.file=/etc/prometheus/prometheus.yml' - - '--web.enable-otlp-receiver' - - '--web.enable-remote-write-receiver' - - '--enable-feature=exemplar-storage' - - otel-collector: - image: otel/opentelemetry-collector - container_name: lobe-otel-collector - network_mode: 'service:network-service' - restart: always - volumes: - - ./otel-collector/collector-config.yaml:/etc/otelcol/config.yaml - command: ['--config', '/etc/otelcol/config.yaml'] - depends_on: - - tempo - - prometheus - - otel-tracing-test: - profiles: - - otel-test - image: ghcr.io/grafana/xk6-client-tracing:v0.0.9 - container_name: lobe-otel-tracing-test - network_mode: 'service:network-service' - restart: always - environment: - - ENDPOINT=127.0.0.1:4317 - - lobe: - image: lobehub/lobehub - container_name: lobehub - network_mode: 'service:network-service' - depends_on: - postgresql: - condition: service_healthy - network-service: - condition: service_started - minio: - condition: service_started - casdoor: - condition: service_started - - environment: - - 'AUTH_SSO_PROVIDERS=casdoor' - - 'KEY_VAULTS_SECRET=Kix2wcUONd4CX51E/ZPAd36BqM4wzJgKjPtz2sGztqQ=' - - 'AUTH_SECRET=NX2kaPE923dt6BL2U8e9oSre5RfoT7hg' - - 'DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgresql:5432/${LOBE_DB_NAME}' - - 'S3_BUCKET=${MINIO_LOBE_BUCKET}' - - 'S3_ENABLE_PATH_STYLE=1' - - 'S3_ACCESS_KEY=${MINIO_ROOT_USER}' - - 'S3_ACCESS_KEY_ID=${MINIO_ROOT_USER}' - - 'S3_SECRET_ACCESS_KEY=${MINIO_ROOT_PASSWORD}' - - 'LLM_VISION_IMAGE_USE_BASE64=1' - - 'S3_SET_ACL=0' - - 'SEARXNG_URL=http://searxng:8080' - - 'OTEL_EXPORTER_OTLP_METRICS_PROTOCOL=http/protobuf' - - 'OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://localhost:4318/v1/metrics' - - 'OTEL_EXPORTER_OTLP_TRACES_PROTOCOL=http/protobuf' - - 'OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4318/v1/traces' - env_file: - - .env - restart: always - entrypoint: > - /bin/sh -c " - /bin/node /app/startServer.js & - LOBE_PID=\$! - sleep 3 - if [ $(wget --timeout=5 --spider --server-response ${AUTH_CASDOOR_ISSUER}/.well-known/openid-configuration 2>&1 | grep -c 'HTTP/1.1 200 OK') -eq 0 ]; then - echo '⚠️Warning: Unable to fetch OIDC configuration from Casdoor' - echo 'Request URL: ${AUTH_CASDOOR_ISSUER}/.well-known/openid-configuration' - echo 'Read more at: https://lobehub.com/docs/self-hosting/server-database/docker-compose#necessary-configuration' - echo '' - echo '⚠️注意:无法从 Casdoor 获取 OIDC 配置' - echo '请求 URL: ${AUTH_CASDOOR_ISSUER}/.well-known/openid-configuration' - echo '了解更多:https://lobehub.com/zh/docs/self-hosting/server-database/docker-compose#necessary-configuration' - echo '' - else - if ! wget -O - --timeout=5 ${AUTH_CASDOOR_ISSUER}/.well-known/openid-configuration 2>&1 | grep 'issuer' | grep ${AUTH_CASDOOR_ISSUER}; then - printf '❌Error: The Auth issuer is conflict, Issuer in OIDC configuration is: %s' \$(wget -O - --timeout=5 ${AUTH_CASDOOR_ISSUER}/.well-known/openid-configuration 2>&1 | grep -E 'issuer.*' | awk -F '\"' '{print \$4}') - echo ' , but the issuer in .env file is: ${AUTH_CASDOOR_ISSUER} ' - echo 'Request URL: ${AUTH_CASDOOR_ISSUER}/.well-known/openid-configuration' - echo 'Read more at: https://lobehub.com/docs/self-hosting/server-database/docker-compose#necessary-configuration' - echo '' - printf '❌错误:Auth 的 issuer 冲突,OIDC 配置中的 issuer 是:%s' \$(wget -O - --timeout=5 ${AUTH_CASDOOR_ISSUER}/.well-known/openid-configuration 2>&1 | grep -E 'issuer.*' | awk -F '\"' '{print \$4}') - echo ' , 但 .env 文件中的 issuer 是:${AUTH_CASDOOR_ISSUER} ' - echo '请求 URL: ${AUTH_CASDOOR_ISSUER}/.well-known/openid-configuration' - echo '了解更多:https://lobehub.com/zh/docs/self-hosting/server-database/docker-compose#necessary-configuration' - echo '' - fi - fi - if [ $(wget --timeout=5 --spider --server-response ${S3_ENDPOINT}/minio/health/live 2>&1 | grep -c 'HTTP/1.1 200 OK') -eq 0 ]; then - echo '⚠️Warning: Unable to fetch MinIO health status' - echo 'Request URL: ${S3_ENDPOINT}/minio/health/live' - echo 'Read more at: https://lobehub.com/docs/self-hosting/server-database/docker-compose#necessary-configuration' - echo '' - echo '⚠️注意:无法获取 MinIO 健康状态' - echo '请求 URL: ${S3_ENDPOINT}/minio/health/live' - echo '了解更多:https://lobehub.com/zh/docs/self-hosting/server-database/docker-compose#necessary-configuration' - echo '' - fi - wait \$LOBE_PID - " - -volumes: - data: - driver: local - s3_data: - driver: local - grafana_data: - driver: local - tempo_data: - driver: local - prometheus_data: - driver: local - - -networks: - lobe-network: - driver: bridge diff --git a/docker-compose/local/grafana/grafana/dashboards/.gitkeep b/docker-compose/local/grafana/grafana/dashboards/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docker-compose/local/grafana/grafana/datasources/datasource-prometheus.yaml b/docker-compose/local/grafana/grafana/datasources/datasource-prometheus.yaml deleted file mode 100644 index 6420fc27f7..0000000000 --- a/docker-compose/local/grafana/grafana/datasources/datasource-prometheus.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: 1 - -prune: true - -datasources: - - name: Prometheus - type: prometheus - uid: prometheus - access: proxy - orgId: 1 - url: http://127.0.0.1:9090 - basicAuth: false - isDefault: false - version: 1 - editable: false diff --git a/docker-compose/local/grafana/grafana/datasources/datasource-tempo.yaml b/docker-compose/local/grafana/grafana/datasources/datasource-tempo.yaml deleted file mode 100644 index c4e667cac9..0000000000 --- a/docker-compose/local/grafana/grafana/datasources/datasource-tempo.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: 1 - -prune: true - -datasources: - - name: Tempo - type: tempo - access: proxy - orgId: 1 - url: http://127.0.0.1:3200 - basicAuth: false - isDefault: true - version: 1 - editable: false - apiVersion: 1 - uid: tempo diff --git a/docker-compose/local/grafana/otel-collector/collector-config.yaml b/docker-compose/local/grafana/otel-collector/collector-config.yaml deleted file mode 100644 index d57687726e..0000000000 --- a/docker-compose/local/grafana/otel-collector/collector-config.yaml +++ /dev/null @@ -1,45 +0,0 @@ -extensions: - health_check: - endpoint: 127.0.0.1:13133 - -receivers: - prometheus: - config: - scrape_configs: - - job_name: otel-collector-metrics - scrape_interval: 10s - static_configs: - - targets: ["127.0.0.1:8888"] - - otlp: - protocols: - grpc: - endpoint: 0.0.0.0:4317 - http: - endpoint: 0.0.0.0:4318 - -exporters: - prometheusremotewrite: - endpoint: http://127.0.0.1:9090/api/v1/write - tls: - insecure: true - - otlp: - endpoint: 127.0.0.1:14317 - tls: - insecure: true - - debug: - verbosity: detailed - -service: - pipelines: - metrics: - receivers: [prometheus, otlp] - exporters: [prometheusremotewrite] - traces: - receivers: [otlp] - exporters: [otlp] - logs: - receivers: [otlp] - exporters: [debug] diff --git a/docker-compose/local/grafana/prometheus/prometheus.yml b/docker-compose/local/grafana/prometheus/prometheus.yml deleted file mode 100644 index 0e37ced3c8..0000000000 --- a/docker-compose/local/grafana/prometheus/prometheus.yml +++ /dev/null @@ -1,11 +0,0 @@ -global: - scrape_interval: 15s - evaluation_interval: 15s - -scrape_configs: - - job_name: "prometheus" - static_configs: - - targets: ["127.0.0.1:9090"] - - job_name: "tempo" - static_configs: - - targets: ["127.0.0.1:3200"] diff --git a/docker-compose/local/grafana/tempo/tempo.yaml b/docker-compose/local/grafana/tempo/tempo.yaml deleted file mode 100644 index 5b4f5017f7..0000000000 --- a/docker-compose/local/grafana/tempo/tempo.yaml +++ /dev/null @@ -1,58 +0,0 @@ -stream_over_http_enabled: true -server: - http_listen_port: 3200 - log_level: info - -query_frontend: - search: - duration_slo: 5s - throughput_bytes_slo: 1.073741824e+09 - metadata_slo: - duration_slo: 5s - throughput_bytes_slo: 1.073741824e+09 - trace_by_id: - duration_slo: 5s - -distributor: - max_attribute_bytes: 10485760 - receivers: - otlp: - protocols: - grpc: - endpoint: 127.0.0.1:14317 - http: - endpoint: 127.0.0.1:14318 - -ingester: - max_block_duration: 5m # cut the headblock when this much time passes. this is being set for demo purposes and should probably be left alone normally - -compactor: - compaction: - block_retention: 1h # overall Tempo trace retention. set for demo purposes - -metrics_generator: - registry: - external_labels: - source: tempo - cluster: docker-compose - storage: - path: /var/tempo/generator/wal - remote_write: - - url: http://127.0.0.1:9090/api/v1/write - send_exemplars: true - traces_storage: - path: /var/tempo/generator/traces - -storage: - trace: - backend: local # backend configuration to use - wal: - path: /var/tempo/wal # where to store the wal locally - local: - path: /var/tempo/blocks - -overrides: - defaults: - metrics_generator: - processors: [service-graphs, span-metrics, local-blocks] # enables metrics generator - generate_native_histograms: both diff --git a/docker-compose/local/logto/docker-compose.yml b/docker-compose/local/logto/docker-compose.yml deleted file mode 100644 index ba1e96d063..0000000000 --- a/docker-compose/local/logto/docker-compose.yml +++ /dev/null @@ -1,124 +0,0 @@ -name: lobehub -services: - network-service: - image: alpine - container_name: lobe-network - ports: - - '${MINIO_PORT}:${MINIO_PORT}' # MinIO API - - '9001:9001' # MinIO Console - - '${LOGTO_PORT}:${LOGTO_PORT}' # Logto - - '3002:3002' # Logto Admin - - '${LOBE_PORT}:3210' # LobeChat - command: tail -f /dev/null - networks: - - lobe-network - - postgresql: - image: pgvector/pgvector:pg16 - container_name: lobe-postgres - ports: - - '5432:5432' - volumes: - - './data:/var/lib/postgresql/data' - environment: - - 'POSTGRES_DB=${LOBE_DB_NAME}' - - 'POSTGRES_PASSWORD=${POSTGRES_PASSWORD}' - healthcheck: - test: ['CMD-SHELL', 'pg_isready -U postgres'] - interval: 5s - timeout: 5s - retries: 5 - restart: always - networks: - - lobe-network - - redis: - image: redis:7-alpine - container_name: lobe-redis - ports: - - '6379:6379' - command: redis-server --save 60 1000 --appendonly yes - volumes: - - 'redis_data:/data' - healthcheck: - test: ['CMD', 'redis-cli', 'ping'] - interval: 5s - timeout: 3s - retries: 5 - restart: always - networks: - - lobe-network - - minio: - image: minio/minio:RELEASE.2025-04-22T22-12-26Z - container_name: lobe-minio - network_mode: "service:network-service" - volumes: - - './s3_data:/etc/minio/data' - environment: - - 'MINIO_ROOT_USER=${MINIO_ROOT_USER}' - - 'MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD}' - - 'MINIO_API_CORS_ALLOW_ORIGIN=http://localhost:${LOBE_PORT}' - restart: always - command: > - server /etc/minio/data --address ":${MINIO_PORT}" --console-address ":9001" - - logto: - image: svhd/logto - container_name: lobe-logto - network_mode: 'service:network-service' - depends_on: - postgresql: - condition: service_healthy - environment: - - 'TRUST_PROXY_HEADER=1' - - 'PORT=${LOGTO_PORT}' - - 'DB_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgresql:5432/logto' - - 'ENDPOINT=http://localhost:${LOGTO_PORT}' - - 'ADMIN_ENDPOINT=http://localhost:3002' - entrypoint: ['sh', '-c', 'npm run cli db seed -- --swe && npm start'] - - lobe: - image: lobehub/lobehub - container_name: lobehub - network_mode: 'service:network-service' - depends_on: - postgresql: - condition: service_healthy - network-service: - condition: service_started - minio: - condition: service_started - logto: - condition: service_started - redis: - condition: service_healthy - - environment: - - 'APP_URL=http://localhost:3210' - - 'AUTH_SSO_PROVIDERS=logto' - - 'KEY_VAULTS_SECRET=Kix2wcUONd4CX51E/ZPAd36BqM4wzJgKjPtz2sGztqQ=' - - 'AUTH_SECRET=NX2kaPE923dt6BL2U8e9oSre5RfoT7hg' - - 'AUTH_LOGTO_ISSUER=http://localhost:${LOGTO_PORT}/oidc' - - 'DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgresql:5432/${LOBE_DB_NAME}' - - 'S3_ENDPOINT=http://localhost:${MINIO_PORT}' - - 'S3_BUCKET=${MINIO_LOBE_BUCKET}' - - 'S3_ENABLE_PATH_STYLE=1' - - 'REDIS_URL=redis://redis:6379' - - 'REDIS_PREFIX=lobechat' - - 'REDIS_TLS=0' - env_file: - - .env - restart: always - -volumes: - data: - driver: local - s3_data: - driver: local - redis_data: - driver: local - -networks: - lobe-network: - driver: bridge diff --git a/docker-compose/local/zitadel/.env.example b/docker-compose/local/zitadel/.env.example deleted file mode 100644 index 7e54936cf5..0000000000 --- a/docker-compose/local/zitadel/.env.example +++ /dev/null @@ -1,31 +0,0 @@ -# Required: LobeChat domain for tRPC calls -# Ensure this domain is whitelisted in your SSO providers and S3 service CORS settings -APP_URL=http://localhost:3210 - -# Postgres related environment variables -# Required: Secret key for encrypting sensitive information. Generate with: openssl rand -base64 32 -KEY_VAULTS_SECRET=Kix2wcUONd4CX51E/ZPAd36BqM4wzJgKjPtz2sGztqQ= -# Required: Postgres database connection string -DATABASE_URL=postgresql://postgres:uWNZugjBqixf8dxC@postgresql:5432/lobechat - -# Authentication related environment variables -AUTH_SECRET=NX2kaPE923dt6BL2U8e9oSre5RfoT7hg -AUTH_SSO_PROVIDERS=zitadel -# ZiTADEL provider configuration -# Please refer to: https://lobehub.com/docs/self-hosting/auth/providers/zitadel -AUTH_ZITADEL_ID=285945938244075523 -AUTH_ZITADEL_SECRET=hkbtzHLaCEIeHeFThym14UcydpmQiEB5JtAX08HSqSoJxhAlVVkyovTuNUZ5TNrT -AUTH_ZITADEL_ISSUER=http://localhost:8080 - -# MinIO S3 configuration -S3_ACCESS_KEY_ID= -S3_SECRET_ACCESS_KEY= -S3_ENDPOINT=http://localhost:9000 -S3_BUCKET=lobe -S3_ENABLE_PATH_STYLE=1 -LLM_VISION_IMAGE_USE_BASE64=1 - -# Other environment variables, as needed. You can refer to the environment variables configuration for the client version, making sure not to have ACCESS_CODE. -# OPENAI_API_KEY=sk-xxxx -# OPENAI_PROXY_URL=https://api.openai.com/v1 -# OPENAI_MODEL_LIST=... diff --git a/docker-compose/local/zitadel/.env.zh-CN.example b/docker-compose/local/zitadel/.env.zh-CN.example deleted file mode 100644 index 111f78d63c..0000000000 --- a/docker-compose/local/zitadel/.env.zh-CN.example +++ /dev/null @@ -1,30 +0,0 @@ -# LobeChat 域名 -APP_URL=http://localhost:3210 - -# Postgres 相关,也即 DB 必须的环境变量 -# 用于加密敏感信息的密钥,可以使用 openssl rand -base64 32 生成 -KEY_VAULTS_SECRET=Kix2wcUONd4CX51E/ZPAd36BqM4wzJgKjPtz2sGztqQ= -# Postgres 数据库连接字符串 -DATABASE_URL=postgresql://postgres:uWNZugjBqixf8dxC@postgresql:5432/lobechat - -# 鉴权相关 -AUTH_SECRET=NX2kaPE923dt6BL2U8e9oSre5RfoT7hg -AUTH_SSO_PROVIDERS=zitadel -# ZiTADEL 鉴权服务提供商部分 -# 请参考:https://lobehub.com/zh/docs/self-hosting/auth/providers/zitadel -AUTH_ZITADEL_ID=285945938244075523 -AUTH_ZITADEL_SECRET=hkbtzHLaCEIeHeFThym14UcydpmQiEB5JtAX08HSqSoJxhAlVVkyovTuNUZ5TNrT -AUTH_ZITADEL_ISSUER=http://localhost:8080 - -# MinIO S3 配置 -S3_ACCESS_KEY_ID= -S3_SECRET_ACCESS_KEY= -S3_ENDPOINT=http://localhost:9000 -S3_BUCKET=lobe -S3_ENABLE_PATH_STYLE=1 -LLM_VISION_IMAGE_USE_BASE64=1 - -# 其他环境变量,视需求而定,可以参照客户端版本的环境变量配置,注意不要有 ACCESS_CODE -# OPENAI_API_KEY=sk-xxxx -# OPENAI_PROXY_URL=https://api.openai.com/v1 -# OPENAI_MODEL_LIST=... diff --git a/docker-compose/local/zitadel/docker-compose.yml b/docker-compose/local/zitadel/docker-compose.yml deleted file mode 100644 index 388c4ffc7e..0000000000 --- a/docker-compose/local/zitadel/docker-compose.yml +++ /dev/null @@ -1,86 +0,0 @@ -name: lobehub -services: - network-service: - image: alpine - container_name: lobe-network - ports: - - '9000:9000' # MinIO API - - '9001:9001' # MinIO Console - - '8080:8080' # Zitadel Console - - '3210:3210' # LobeChat - command: tail -f /dev/null - networks: - - lobe-network - - postgresql: - image: pgvector/pgvector:pg16 - container_name: lobe-postgres - ports: - - '5432:5432' - volumes: - - './data:/var/lib/postgresql/data' - environment: - - 'POSTGRES_DB=lobechat' - - 'POSTGRES_PASSWORD=uWNZugjBqixf8dxC' - healthcheck: - test: ['CMD-SHELL', 'pg_isready -U postgres'] - interval: 5s - timeout: 5s - retries: 5 - restart: always - networks: - - lobe-network - - minio: - image: minio/minio:RELEASE.2025-04-22T22-12-26Z - container_name: lobe-minio - network_mode: 'service:network-service' - volumes: - - './s3_data:/etc/minio/data' - environment: - - 'MINIO_ROOT_USER=YOUR_MINIO_USER' - - 'MINIO_ROOT_PASSWORD=YOUR_MINIO_PASSWORD' - - 'MINIO_API_CORS_ALLOW_ORIGIN=http://localhost:3210' - restart: always - command: > - server /etc/minio/data --address ":9000" --console-address ":9001" - - - zitadel: - restart: 'always' - image: 'ghcr.io/zitadel/zitadel:latest' - container_name: lobe-zitadel - network_mode: 'service:network-service' - command: start-from-init --config /zitadel-config.yaml --steps /zitadel-init-steps.yaml --masterkey "cft3Tekr/rQBOqwoQSCPoncA9BHbn7QJ" --tlsMode disabled #MasterkeyNeedsToHave32Characters - volumes: - - ./zitadel-config.yaml:/zitadel-config.yaml:ro - - ./zitadel-init-steps.yaml:/zitadel-init-steps.yaml:ro - depends_on: - postgresql: - condition: service_healthy - - lobe: - image: lobehub/lobehub - container_name: lobehub - network_mode: 'service:network-service' - depends_on: - postgresql: - condition: service_healthy - network-service: - condition: service_started - minio: - condition: service_started - zitadel: - condition: service_started - env_file: - - .env - restart: always - -volumes: - data: - driver: local - s3_data: - driver: local -networks: - lobe-network: - driver: bridge diff --git a/docker-compose/local/zitadel/zitadel-config.yaml b/docker-compose/local/zitadel/zitadel-config.yaml deleted file mode 100644 index f84a33182b..0000000000 --- a/docker-compose/local/zitadel/zitadel-config.yaml +++ /dev/null @@ -1,26 +0,0 @@ -Log: - Level: 'info' - -Port: 8080 -ExternalPort: 8080 -ExternalDomain: localhost -ExternalSecure: false -TLS: - Enabled: false - -# If not using the docker compose example, adjust these values for connecting ZITADEL to your PostgreSQL -Database: - postgres: - Host: postgresql - Port: 5432 - Database: zitadel - User: - Username: 'zitadel' - Password: 'zitadel' - SSL: - Mode: 'disable' - Admin: - Username: 'postgres' - Password: 'uWNZugjBqixf8dxC' #postgres password - SSL: - Mode: 'disable' diff --git a/docker-compose/local/zitadel/zitadel-init-steps.yaml b/docker-compose/local/zitadel/zitadel-init-steps.yaml deleted file mode 100644 index 9e24208522..0000000000 --- a/docker-compose/local/zitadel/zitadel-init-steps.yaml +++ /dev/null @@ -1,11 +0,0 @@ -# All possible options and their defaults: https://github.com/zitadel/zitadel/blob/main/cmd/setup/steps.yaml -FirstInstance: - Org: - Human: - # use the loginname root@zitadel.localhost - Username: 'root' - # The password must be 8 characters or more and must contain uppercase letters, lowercase letters, symbols, and numbers. The first login will require a password change. - Password: 'Password1!' - Email: - # Optional, if set, can be used to log in with email. - Address: 'example@zitadel.com' # ZITADEL_FIRSTINSTANCE_ORG_HUMAN_EMAIL_ADDRESS diff --git a/docker-compose/minio-bucket.config.json b/docker-compose/minio-bucket.config.json deleted file mode 100644 index b974b2c806..0000000000 --- a/docker-compose/minio-bucket.config.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "Statement": [ - { - "Effect": "Allow", - "Principal": { - "AWS": ["*"] - }, - "Action": ["s3:GetBucketLocation"], - "Resource": ["arn:aws:s3:::lobe"] - }, - { - "Effect": "Allow", - "Principal": { - "AWS": ["*"] - }, - "Action": ["s3:ListBucket"], - "Resource": ["arn:aws:s3:::lobe"], - "Condition": { - "StringEquals": { - "s3:prefix": ["files/*"] - } - } - }, - { - "Effect": "Allow", - "Principal": { - "AWS": ["*"] - }, - "Action": ["s3:PutObject", "s3:DeleteObject", "s3:GetObject"], - "Resource": ["arn:aws:s3:::lobe/files/**"] - } - ], - "Version": "2012-10-17" -} diff --git a/docker-compose/local/init_data.json b/docker-compose/production/grafana/init_data.json similarity index 100% rename from docker-compose/local/init_data.json rename to docker-compose/production/grafana/init_data.json diff --git a/docker-compose/production/grafana/searxng-settings.yml b/docker-compose/production/grafana/searxng-settings.yml new file mode 100644 index 0000000000..ffb5e42299 --- /dev/null +++ b/docker-compose/production/grafana/searxng-settings.yml @@ -0,0 +1,2582 @@ +general: + # Debug mode, only for development. Is overwritten by ${SEARXNG_DEBUG} + debug: false + # displayed name + instance_name: "searxng" + # For example: https://example.com/privacy + privacypolicy_url: false + # use true to use your own donation page written in searx/info/en/donate.md + # use false to disable the donation link + donation_url: false + # mailto:contact@example.com + contact_url: false + # record stats + enable_metrics: true + # expose stats in open metrics format at /metrics + # leave empty to disable (no password set) + # open_metrics: + open_metrics: '' + +brand: + new_issue_url: https://github.com/searxng/searxng/issues/new + docs_url: https://docs.searxng.org/ + public_instances: https://searx.space + wiki_url: https://github.com/searxng/searxng/wiki + issue_url: https://github.com/searxng/searxng/issues + # custom: + # maintainer: "Jon Doe" + # # Custom entries in the footer: [title]: [link] + # links: + # Uptime: https://uptime.searxng.org/history/darmarit-org + # About: "https://searxng.org" + +search: + # Filter results. 0: None, 1: Moderate, 2: Strict + safe_search: 0 + # Existing autocomplete backends: "baidu", "brave", "dbpedia", "duckduckgo", "google", "yandex", + # "mwmbl", "seznam", "stract", "swisscows", "qwant", "wikipedia" - + # leave blank to turn it off by default. + autocomplete: "" + # minimun characters to type before autocompleter starts + autocomplete_min: 4 + # backend for the favicon near URL in search results. + # Available resolvers: "allesedv", "duckduckgo", "google", "yandex" - leave blank to turn it off by default. + favicon_resolver: "" + # Default search language - leave blank to detect from browser information or + # use codes from 'languages.py' + default_lang: "auto" + # max_page: 0 # if engine supports paging, 0 means unlimited numbers of pages + # Available languages + # languages: + # - all + # - en + # - en-US + # - de + # - it-IT + # - fr + # - fr-BE + # ban time in seconds after engine errors + ban_time_on_fail: 5 + # max ban time in seconds after engine errors + max_ban_time_on_fail: 120 + suspended_times: + # Engine suspension time after error (in seconds; set to 0 to disable) + # For error "Access denied" and "HTTP error [402, 403]" + SearxEngineAccessDenied: 86400 + # For error "CAPTCHA" + SearxEngineCaptcha: 86400 + # For error "Too many request" and "HTTP error 429" + SearxEngineTooManyRequests: 3600 + # Cloudflare CAPTCHA + cf_SearxEngineCaptcha: 1296000 + cf_SearxEngineAccessDenied: 86400 + # ReCAPTCHA + recaptcha_SearxEngineCaptcha: 604800 + + # remove format to deny access, use lower case. + # formats: [html, csv, json, rss] + formats: + - html + - json +server: + # Is overwritten by ${SEARXNG_PORT} and ${SEARXNG_BIND_ADDRESS} + port: 8888 + bind_address: "127.0.0.1" + # public URL of the instance, to ensure correct inbound links. Is overwritten + # by ${SEARXNG_URL}. + base_url: / # "http://example.com/location" + # rate limit the number of request on the instance, block some bots. + # Is overwritten by ${SEARXNG_LIMITER} + limiter: false + # enable features designed only for public instances. + # Is overwritten by ${SEARXNG_PUBLIC_INSTANCE} + public_instance: false + + # If your instance owns a /etc/searxng/settings.yml file, then set the following + # values there. + + secret_key: "779c5b69fe650f147be9012abca6b44a8697acdb2817b46353f4779bb07d81d1" # Is overwritten by ${SEARXNG_SECRET} + # Proxy image results through SearXNG. Is overwritten by ${SEARXNG_IMAGE_PROXY} + image_proxy: false + # 1.0 and 1.1 are supported + http_protocol_version: "1.0" + # POST queries are more secure as they don't show up in history but may cause + # problems when using Firefox containers + method: "POST" + default_http_headers: + X-Content-Type-Options: nosniff + X-Download-Options: noopen + X-Robots-Tag: noindex, nofollow + Referrer-Policy: no-referrer + +redis: + # URL to connect redis database. Is overwritten by ${SEARXNG_REDIS_URL}. + # https://docs.searxng.org/admin/settings/settings_redis.html#settings-redis + url: false + +ui: + # Custom static path - leave it blank if you didn't change + static_path: "" + # Is overwritten by ${SEARXNG_STATIC_USE_HASH}. + static_use_hash: false + # Custom templates path - leave it blank if you didn't change + templates_path: "" + # query_in_title: When true, the result page's titles contains the query + # it decreases the privacy, since the browser can records the page titles. + query_in_title: false + # infinite_scroll: When true, automatically loads the next page when scrolling to bottom of the current page. + infinite_scroll: false + # ui theme + default_theme: simple + # center the results ? + center_alignment: false + # URL prefix of the internet archive, don't forget trailing slash (if needed). + # cache_url: "https://webcache.googleusercontent.com/search?q=cache:" + # Default interface locale - leave blank to detect from browser information or + # use codes from the 'locales' config section + default_locale: "" + # Open result links in a new tab by default + # results_on_new_tab: false + theme_args: + # style of simple theme: auto, light, dark + simple_style: auto + # Perform search immediately if a category selected. + # Disable to select multiple categories at once and start the search manually. + search_on_category_select: true + # Hotkeys: default or vim + hotkeys: default + # URL formatting: pretty, full or host + url_formatting: pretty + +# Lock arbitrary settings on the preferences page. +# +# preferences: +# lock: +# - categories +# - language +# - autocomplete +# - favicon +# - safesearch +# - method +# - doi_resolver +# - locale +# - theme +# - results_on_new_tab +# - infinite_scroll +# - search_on_category_select +# - method +# - image_proxy +# - query_in_title + +# searx supports result proxification using an external service: +# https://github.com/asciimoo/morty uncomment below section if you have running +# morty proxy the key is base64 encoded (keep the !!binary notation) +# Note: since commit af77ec3, morty accepts a base64 encoded key. +# +# result_proxy: +# url: http://127.0.0.1:3000/ +# # the key is a base64 encoded string, the YAML !!binary prefix is optional +# key: !!binary "your_morty_proxy_key" +# # [true|false] enable the "proxy" button next to each result +# proxify_results: true + +# communication with search engines +# +outgoing: + # default timeout in seconds, can be override by engine + request_timeout: 3.0 + # the maximum timeout in seconds + # max_request_timeout: 10.0 + # suffix of searx_useragent, could contain information like an email address + # to the administrator + useragent_suffix: "" + # The maximum number of concurrent connections that may be established. + pool_connections: 100 + # Allow the connection pool to maintain keep-alive connections below this + # point. + pool_maxsize: 20 + # See https://www.python-httpx.org/http2/ + enable_http2: true + # uncomment below section if you want to use a custom server certificate + # see https://www.python-httpx.org/advanced/#changing-the-verification-defaults + # and https://www.python-httpx.org/compatibility/#ssl-configuration + # verify: ~/.mitmproxy/mitmproxy-ca-cert.cer + # + # uncomment below section if you want to use a proxyq see: SOCKS proxies + # https://2.python-requests.org/en/latest/user/advanced/#proxies + # are also supported: see + # https://2.python-requests.org/en/latest/user/advanced/#socks + # + # proxies: + # all://: + # - http://proxy1:8080 + # - http://proxy2:8080 + # + # using_tor_proxy: true + # + # Extra seconds to add in order to account for the time taken by the proxy + # + # extra_proxy_timeout: 10 + # + # uncomment below section only if you have more than one network interface + # which can be the source of outgoing search requests + # + # source_ips: + # - 1.1.1.1 + # - 1.1.1.2 + # - fe80::/126 + +# External plugin configuration, for more details see +# https://docs.searxng.org/admin/settings/settings_plugins.html +# +# plugins: +# - mypackage.mymodule.MyPlugin +# - mypackage.mymodule.MyOtherPlugin +# - ... + +# Comment or un-comment plugin to activate / deactivate by default. +# https://docs.searxng.org/admin/settings/settings_plugins.html +# +# enabled_plugins: +# # these plugins are enabled if nothing is configured .. +# - 'Basic Calculator' +# - 'Hash plugin' +# - 'Self Information' +# - 'Tracker URL remover' +# - 'Unit converter plugin' +# - 'Ahmia blacklist' # activation depends on outgoing.using_tor_proxy +# # these plugins are disabled if nothing is configured .. +# - 'Hostnames plugin' # see 'hostnames' configuration below +# - 'Open Access DOI rewrite' +# - 'Tor check plugin' + +# Configuration of the "Hostnames plugin": +# +# hostnames: +# replace: +# '(.*\.)?youtube\.com$': 'invidious.example.com' +# '(.*\.)?youtu\.be$': 'invidious.example.com' +# '(.*\.)?reddit\.com$': 'teddit.example.com' +# '(.*\.)?redd\.it$': 'teddit.example.com' +# '(www\.)?twitter\.com$': 'nitter.example.com' +# remove: +# - '(.*\.)?facebook.com$' +# low_priority: +# - '(.*\.)?google(\..*)?$' +# high_priority: +# - '(.*\.)?wikipedia.org$' +# +# Alternatively you can use external files for configuring the "Hostnames plugin": +# +# hostnames: +# replace: 'rewrite-hosts.yml' +# +# Content of 'rewrite-hosts.yml' (place the file in the same directory as 'settings.yml'): +# '(.*\.)?youtube\.com$': 'invidious.example.com' +# '(.*\.)?youtu\.be$': 'invidious.example.com' +# + +checker: + # disable checker when in debug mode + off_when_debug: true + + # use "scheduling: false" to disable scheduling + # scheduling: interval or int + + # to activate the scheduler: + # * uncomment "scheduling" section + # * add "cache2 = name=searxngcache,items=2000,blocks=2000,blocksize=4096,bitmap=1" + # to your uwsgi.ini + + # scheduling: + # start_after: [300, 1800] # delay to start the first run of the checker + # every: [86400, 90000] # how often the checker runs + + # additional tests: only for the YAML anchors (see the engines section) + # + additional_tests: + rosebud: &test_rosebud + matrix: + query: rosebud + lang: en + result_container: + - not_empty + - ['one_title_contains', 'citizen kane'] + test: + - unique_results + + android: &test_android + matrix: + query: ['android'] + lang: ['en', 'de', 'fr', 'zh-CN'] + result_container: + - not_empty + - ['one_title_contains', 'google'] + test: + - unique_results + + # tests: only for the YAML anchors (see the engines section) + tests: + infobox: &tests_infobox + infobox: + matrix: + query: ["linux", "new york", "bbc"] + result_container: + - has_infobox + +categories_as_tabs: + general: + images: + videos: + news: + map: + music: + it: + science: + files: + social media: + +engines: + - name: 9gag + engine: 9gag + shortcut: 9g + disabled: true + + - name: adobe stock + engine: adobe_stock + shortcut: asi + categories: ["images"] + # https://docs.searxng.org/dev/engines/online/adobe_stock.html + adobe_order: relevance + adobe_content_types: ["photo", "illustration", "zip_vector", "template", "3d", "image"] + timeout: 6 + disabled: true + + - name: adobe stock video + engine: adobe_stock + shortcut: asv + network: adobe stock + categories: ["videos"] + adobe_order: relevance + adobe_content_types: ["video"] + timeout: 6 + disabled: true + + - name: adobe stock audio + engine: adobe_stock + shortcut: asa + network: adobe stock + categories: ["music"] + adobe_order: relevance + adobe_content_types: ["audio"] + timeout: 6 + disabled: true + + - name: alexandria + engine: json_engine + shortcut: alx + categories: general + paging: true + search_url: https://api.alexandria.org/?a=1&q={query}&p={pageno} + results_query: results + title_query: title + url_query: url + content_query: snippet + timeout: 1.5 + disabled: true + about: + website: https://alexandria.org/ + official_api_documentation: https://github.com/alexandria-org/alexandria-api/raw/master/README.md + use_official_api: true + require_api_key: false + results: JSON + + # - name: astrophysics data system + # engine: astrophysics_data_system + # sort: asc + # weight: 5 + # categories: [science] + # api_key: your-new-key + # shortcut: ads + + - name: alpine linux packages + engine: alpinelinux + disabled: true + shortcut: alp + + - name: annas archive + engine: annas_archive + disabled: true + shortcut: aa + + # - name: annas articles + # engine: annas_archive + # shortcut: aaa + # # https://docs.searxng.org/dev/engines/online/annas_archive.html + # aa_content: 'magazine' # book_fiction, book_unknown, book_nonfiction, book_comic + # aa_ext: 'pdf' # pdf, epub, .. + # aa_sort: oldest' # newest, oldest, largest, smallest + + - name: apk mirror + engine: apkmirror + timeout: 4.0 + shortcut: apkm + disabled: true + + - name: apple app store + engine: apple_app_store + shortcut: aps + disabled: true + + # Requires Tor + - name: ahmia + engine: ahmia + categories: onions + enable_http: true + shortcut: ah + + - name: anaconda + engine: xpath + paging: true + first_page_num: 0 + search_url: https://anaconda.org/search?q={query}&page={pageno} + results_xpath: //tbody/tr + url_xpath: ./td/h5/a[last()]/@href + title_xpath: ./td/h5 + content_xpath: ./td[h5]/text() + categories: it + timeout: 6.0 + shortcut: conda + disabled: true + + - name: arch linux wiki + engine: archlinux + shortcut: al + + - name: nixos wiki + engine: mediawiki + shortcut: nixw + base_url: https://wiki.nixos.org/ + search_type: text + disabled: true + categories: [it, software wikis] + + - name: artic + engine: artic + shortcut: arc + timeout: 4.0 + + - name: arxiv + engine: arxiv + shortcut: arx + timeout: 4.0 + + - name: ask + engine: ask + shortcut: ask + disabled: true + + # tmp suspended: dh key too small + # - name: base + # engine: base + # shortcut: bs + + - name: bandcamp + engine: bandcamp + shortcut: bc + categories: music + + - name: wikipedia + engine: wikipedia + shortcut: wp + # add "list" to the array to get results in the results list + display_type: ["infobox"] + categories: [general] + + - name: bilibili + engine: bilibili + shortcut: bil + disabled: true + + - name: bing + engine: bing + shortcut: bi + disabled: true + + - name: bing images + engine: bing_images + shortcut: bii + + - name: bing news + engine: bing_news + shortcut: bin + + - name: bing videos + engine: bing_videos + shortcut: biv + + - name: bitbucket + engine: xpath + paging: true + search_url: https://bitbucket.org/repo/all/{pageno}?name={query} + url_xpath: //article[@class="repo-summary"]//a[@class="repo-link"]/@href + title_xpath: //article[@class="repo-summary"]//a[@class="repo-link"] + content_xpath: //article[@class="repo-summary"]/p + categories: [it, repos] + timeout: 4.0 + disabled: true + shortcut: bb + about: + website: https://bitbucket.org/ + wikidata_id: Q2493781 + official_api_documentation: https://developer.atlassian.com/bitbucket + use_official_api: false + require_api_key: false + results: HTML + + - name: bpb + engine: bpb + shortcut: bpb + disabled: true + + - name: btdigg + engine: btdigg + shortcut: bt + disabled: true + + - name: openverse + engine: openverse + categories: images + shortcut: opv + + - name: media.ccc.de + engine: ccc_media + shortcut: c3tv + # We don't set language: de here because media.ccc.de is not just + # for a German audience. It contains many English videos and many + # German videos have English subtitles. + disabled: true + + - name: chefkoch + engine: chefkoch + shortcut: chef + # to show premium or plus results too: + # skip_premium: false + + - name: cloudflareai + engine: cloudflareai + shortcut: cfai + # get api token and accont id from https://developers.cloudflare.com/workers-ai/get-started/rest-api/ + cf_account_id: 'your_cf_accout_id' + cf_ai_api: 'your_cf_api' + # create your ai gateway by https://developers.cloudflare.com/ai-gateway/get-started/creating-gateway/ + cf_ai_gateway: 'your_cf_ai_gateway_name' + # find the model name from https://developers.cloudflare.com/workers-ai/models/#text-generation + cf_ai_model: 'ai_model_name' + # custom your preferences + # cf_ai_model_display_name: 'Cloudflare AI' + # cf_ai_model_assistant: 'prompts_for_assistant_role' + # cf_ai_model_system: 'prompts_for_system_role' + timeout: 30 + disabled: true + + # - name: core.ac.uk + # engine: core + # categories: science + # shortcut: cor + # # get your API key from: https://core.ac.uk/api-keys/register/ + # api_key: 'unset' + + - name: cppreference + engine: cppreference + shortcut: cpp + paging: false + disabled: true + + - name: crossref + engine: crossref + shortcut: cr + timeout: 30 + disabled: true + + - name: crowdview + engine: json_engine + shortcut: cv + categories: general + paging: false + search_url: https://crowdview-next-js.onrender.com/api/search-v3?query={query} + results_query: results + url_query: link + title_query: title + content_query: snippet + title_html_to_text: true + content_html_to_text: true + disabled: true + about: + website: https://crowdview.ai/ + + - name: yep + engine: yep + shortcut: yep + categories: general + search_type: web + timeout: 5 + disabled: true + + - name: yep images + engine: yep + shortcut: yepi + categories: images + search_type: images + disabled: true + + - name: yep news + engine: yep + shortcut: yepn + categories: news + search_type: news + disabled: true + + - name: curlie + engine: xpath + shortcut: cl + categories: general + disabled: true + paging: true + lang_all: '' + search_url: https://curlie.org/search?q={query}&lang={lang}&start={pageno}&stime=92452189 + page_size: 20 + results_xpath: //div[@id="site-list-content"]/div[@class="site-item"] + url_xpath: ./div[@class="title-and-desc"]/a/@href + title_xpath: ./div[@class="title-and-desc"]/a/div + content_xpath: ./div[@class="title-and-desc"]/div[@class="site-descr"] + about: + website: https://curlie.org/ + wikidata_id: Q60715723 + use_official_api: false + require_api_key: false + results: HTML + + - name: currency + engine: currency_convert + categories: general + shortcut: cc + + - name: deezer + engine: deezer + shortcut: dz + disabled: true + + - name: destatis + engine: destatis + shortcut: destat + disabled: true + + - name: deviantart + engine: deviantart + shortcut: da + timeout: 3.0 + + - name: ddg definitions + engine: duckduckgo_definitions + shortcut: ddd + weight: 2 + disabled: true + tests: *tests_infobox + + # cloudflare protected + # - name: digbt + # engine: digbt + # shortcut: dbt + # timeout: 6.0 + # disabled: true + + - name: docker hub + engine: docker_hub + shortcut: dh + categories: [it, packages] + + - name: encyclosearch + engine: json_engine + shortcut: es + categories: general + paging: true + search_url: https://encyclosearch.org/encyclosphere/search?q={query}&page={pageno}&resultsPerPage=15 + results_query: Results + url_query: SourceURL + title_query: Title + content_query: Description + disabled: true + about: + website: https://encyclosearch.org + official_api_documentation: https://encyclosearch.org/docs/#/rest-api + use_official_api: true + require_api_key: false + results: JSON + + - name: erowid + engine: xpath + paging: true + first_page_num: 0 + page_size: 30 + search_url: https://www.erowid.org/search.php?q={query}&s={pageno} + url_xpath: //dl[@class="results-list"]/dt[@class="result-title"]/a/@href + title_xpath: //dl[@class="results-list"]/dt[@class="result-title"]/a/text() + content_xpath: //dl[@class="results-list"]/dd[@class="result-details"] + categories: [] + shortcut: ew + disabled: true + about: + website: https://www.erowid.org/ + wikidata_id: Q1430691 + official_api_documentation: + use_official_api: false + require_api_key: false + results: HTML + + # - name: elasticsearch + # shortcut: es + # engine: elasticsearch + # base_url: http://localhost:9200 + # username: elastic + # password: changeme + # index: my-index + # # available options: match, simple_query_string, term, terms, custom + # query_type: match + # # if query_type is set to custom, provide your query here + # #custom_query_json: {"query":{"match_all": {}}} + # #show_metadata: false + # disabled: true + + - name: wikidata + engine: wikidata + shortcut: wd + timeout: 3.0 + weight: 2 + # add "list" to the array to get results in the results list + display_type: ["infobox"] + tests: *tests_infobox + categories: [general] + + - name: duckduckgo + engine: duckduckgo + shortcut: ddg + + - name: duckduckgo images + engine: duckduckgo_extra + categories: [images, web] + ddg_category: images + shortcut: ddi + disabled: true + + - name: duckduckgo videos + engine: duckduckgo_extra + categories: [videos, web] + ddg_category: videos + shortcut: ddv + disabled: true + + - name: duckduckgo news + engine: duckduckgo_extra + categories: [news, web] + ddg_category: news + shortcut: ddn + disabled: true + + - name: duckduckgo weather + engine: duckduckgo_weather + shortcut: ddw + disabled: true + + - name: apple maps + engine: apple_maps + shortcut: apm + disabled: true + timeout: 5.0 + + - name: emojipedia + engine: emojipedia + timeout: 4.0 + shortcut: em + disabled: true + + - name: tineye + engine: tineye + shortcut: tin + timeout: 9.0 + disabled: true + + - name: etymonline + engine: xpath + paging: true + search_url: https://etymonline.com/search?page={pageno}&q={query} + url_xpath: //a[contains(@class, "word__name--")]/@href + title_xpath: //a[contains(@class, "word__name--")] + content_xpath: //section[contains(@class, "word__defination")] + first_page_num: 1 + shortcut: et + categories: [dictionaries] + about: + website: https://www.etymonline.com/ + wikidata_id: Q1188617 + official_api_documentation: + use_official_api: false + require_api_key: false + results: HTML + + # - name: ebay + # engine: ebay + # shortcut: eb + # base_url: 'https://www.ebay.com' + # disabled: true + # timeout: 5 + + - name: 1x + engine: www1x + shortcut: 1x + timeout: 3.0 + disabled: true + + - name: fdroid + engine: fdroid + shortcut: fd + disabled: true + + - name: findthatmeme + engine: findthatmeme + shortcut: ftm + disabled: true + + - name: flickr + categories: images + shortcut: fl + # You can use the engine using the official stable API, but you need an API + # key, see: https://www.flickr.com/services/apps/create/ + # engine: flickr + # api_key: 'apikey' # required! + # Or you can use the html non-stable engine, activated by default + engine: flickr_noapi + + - name: free software directory + engine: mediawiki + shortcut: fsd + categories: [it, software wikis] + base_url: https://directory.fsf.org/ + search_type: title + timeout: 5.0 + disabled: true + about: + website: https://directory.fsf.org/ + wikidata_id: Q2470288 + + # - name: freesound + # engine: freesound + # shortcut: fnd + # disabled: true + # timeout: 15.0 + # API key required, see: https://freesound.org/docs/api/overview.html + # api_key: MyAPIkey + + - name: frinkiac + engine: frinkiac + shortcut: frk + disabled: true + + - name: fyyd + engine: fyyd + shortcut: fy + timeout: 8.0 + disabled: true + + - name: geizhals + engine: geizhals + shortcut: geiz + disabled: true + + - name: genius + engine: genius + shortcut: gen + + - name: gentoo + engine: mediawiki + shortcut: ge + categories: ["it", "software wikis"] + base_url: "https://wiki.gentoo.org/" + api_path: "api.php" + search_type: text + timeout: 10 + + - name: gitlab + engine: gitlab + base_url: https://gitlab.com + shortcut: gl + disabled: true + about: + website: https://gitlab.com/ + wikidata_id: Q16639197 + + # - name: gnome + # engine: gitlab + # base_url: https://gitlab.gnome.org + # shortcut: gn + # about: + # website: https://gitlab.gnome.org + # wikidata_id: Q44316 + + - name: github + engine: github + shortcut: gh + + - name: codeberg + # https://docs.searxng.org/dev/engines/online/gitea.html + engine: gitea + base_url: https://codeberg.org + shortcut: cb + disabled: true + + - name: gitea.com + engine: gitea + base_url: https://gitea.com + shortcut: gitea + disabled: true + + - name: goodreads + engine: goodreads + shortcut: good + timeout: 4.0 + disabled: true + + - name: google + engine: google + shortcut: go + # additional_tests: + # android: *test_android + + - name: google images + engine: google_images + shortcut: goi + # additional_tests: + # android: *test_android + # dali: + # matrix: + # query: ['Dali Christ'] + # lang: ['en', 'de', 'fr', 'zh-CN'] + # result_container: + # - ['one_title_contains', 'Salvador'] + + - name: google news + engine: google_news + shortcut: gon + # additional_tests: + # android: *test_android + + - name: google videos + engine: google_videos + shortcut: gov + # additional_tests: + # android: *test_android + + - name: google scholar + engine: google_scholar + shortcut: gos + + - name: google play apps + engine: google_play + categories: [files, apps] + shortcut: gpa + play_categ: apps + disabled: true + + - name: google play movies + engine: google_play + categories: videos + shortcut: gpm + play_categ: movies + disabled: true + + - name: material icons + engine: material_icons + categories: images + shortcut: mi + disabled: true + + - name: habrahabr + engine: xpath + paging: true + search_url: https://habr.com/en/search/page{pageno}/?q={query} + results_xpath: //article[contains(@class, "tm-articles-list__item")] + url_xpath: .//a[@class="tm-title__link"]/@href + title_xpath: .//a[@class="tm-title__link"] + content_xpath: .//div[contains(@class, "article-formatted-body")] + categories: it + timeout: 4.0 + disabled: true + shortcut: habr + about: + website: https://habr.com/ + wikidata_id: Q4494434 + official_api_documentation: https://habr.com/en/docs/help/api/ + use_official_api: false + require_api_key: false + results: HTML + + - name: hackernews + engine: hackernews + shortcut: hn + disabled: true + + - name: hex + engine: hex + shortcut: hex + disabled: true + # Valid values: name inserted_at updated_at total_downloads recent_downloads + sort_criteria: "recent_downloads" + page_size: 10 + + - name: crates.io + engine: crates + shortcut: crates + disabled: true + timeout: 6.0 + + - name: hoogle + engine: xpath + search_url: https://hoogle.haskell.org/?hoogle={query} + results_xpath: '//div[@class="result"]' + title_xpath: './/div[@class="ans"]//a' + url_xpath: './/div[@class="ans"]//a/@href' + content_xpath: './/div[@class="from"]' + page_size: 20 + categories: [it, packages] + shortcut: ho + about: + website: https://hoogle.haskell.org/ + wikidata_id: Q34010 + official_api_documentation: https://hackage.haskell.org/api + use_official_api: false + require_api_key: false + results: JSON + + - name: imdb + engine: imdb + shortcut: imdb + timeout: 6.0 + disabled: true + + - name: imgur + engine: imgur + shortcut: img + disabled: true + + - name: ina + engine: ina + shortcut: in + timeout: 6.0 + disabled: true + + - name: invidious + engine: invidious + # Instanes will be selected randomly, see https://api.invidious.io/ for + # instances that are stable (good uptime) and close to you. + base_url: + - https://invidious.adminforge.de + - https://inv.nadeko.net + shortcut: iv + timeout: 3.0 + disabled: true + + - name: ipernity + engine: ipernity + shortcut: ip + disabled: true + + - name: jisho + engine: jisho + shortcut: js + timeout: 3.0 + disabled: true + + - name: kickass + engine: kickass + base_url: + - https://kickasstorrents.to + - https://kickasstorrents.cr + - https://kickasstorrent.cr + - https://kickass.sx + - https://kat.am + shortcut: kc + timeout: 4.0 + + - name: lemmy communities + engine: lemmy + lemmy_type: Communities + shortcut: leco + + - name: lemmy users + engine: lemmy + network: lemmy communities + lemmy_type: Users + shortcut: leus + + - name: lemmy posts + engine: lemmy + network: lemmy communities + lemmy_type: Posts + shortcut: lepo + + - name: lemmy comments + engine: lemmy + network: lemmy communities + lemmy_type: Comments + shortcut: lecom + + - name: library genesis + engine: xpath + # search_url: https://libgen.is/search.php?req={query} + search_url: https://libgen.rs/search.php?req={query} + url_xpath: //a[contains(@href,"book/index.php?md5")]/@href + title_xpath: //a[contains(@href,"book/")]/text()[1] + content_xpath: //td/a[1][contains(@href,"=author")]/text() + categories: files + timeout: 7.0 + disabled: true + shortcut: lg + about: + website: https://libgen.fun/ + wikidata_id: Q22017206 + official_api_documentation: + use_official_api: false + require_api_key: false + results: HTML + + - name: z-library + engine: zlibrary + shortcut: zlib + categories: files + timeout: 7.0 + + - name: library of congress + engine: loc + shortcut: loc + categories: images + + - name: libretranslate + engine: libretranslate + # https://github.com/LibreTranslate/LibreTranslate?tab=readme-ov-file#mirrors + base_url: + - https://libretranslate.com/translate + # api_key: abc123 + shortcut: lt + disabled: true + + - name: lingva + engine: lingva + shortcut: lv + # set lingva instance in url, by default it will use the official instance + # url: https://lingva.thedaviddelta.com + + - name: lobste.rs + engine: xpath + search_url: https://lobste.rs/search?q={query}&what=stories&order=relevance + results_xpath: //li[contains(@class, "story")] + url_xpath: .//a[@class="u-url"]/@href + title_xpath: .//a[@class="u-url"] + content_xpath: .//a[@class="domain"] + categories: it + shortcut: lo + timeout: 5.0 + disabled: true + about: + website: https://lobste.rs/ + wikidata_id: Q60762874 + official_api_documentation: + use_official_api: false + require_api_key: false + results: HTML + + - name: mastodon users + engine: mastodon + mastodon_type: accounts + base_url: https://mastodon.social + shortcut: mau + + - name: mastodon hashtags + engine: mastodon + mastodon_type: hashtags + base_url: https://mastodon.social + shortcut: mah + + # - name: matrixrooms + # engine: mrs + # # https://docs.searxng.org/dev/engines/online/mrs.html + # # base_url: https://mrs-api-host + # shortcut: mtrx + # disabled: true + + - name: mdn + shortcut: mdn + engine: json_engine + categories: [it] + paging: true + search_url: https://developer.mozilla.org/api/v1/search?q={query}&page={pageno} + results_query: documents + url_query: mdn_url + url_prefix: https://developer.mozilla.org + title_query: title + content_query: summary + about: + website: https://developer.mozilla.org + wikidata_id: Q3273508 + official_api_documentation: null + use_official_api: false + require_api_key: false + results: JSON + + - name: metacpan + engine: metacpan + shortcut: cpan + disabled: true + number_of_results: 20 + + # - name: meilisearch + # engine: meilisearch + # shortcut: mes + # enable_http: true + # base_url: http://localhost:7700 + # index: my-index + + - name: mixcloud + engine: mixcloud + shortcut: mc + + # MongoDB engine + # Required dependency: pymongo + # - name: mymongo + # engine: mongodb + # shortcut: md + # exact_match_only: false + # host: '127.0.0.1' + # port: 27017 + # enable_http: true + # results_per_page: 20 + # database: 'business' + # collection: 'reviews' # name of the db collection + # key: 'name' # key in the collection to search for + + - name: mozhi + engine: mozhi + base_url: + - https://mozhi.aryak.me + - https://translate.bus-hit.me + - https://nyc1.mz.ggtyler.dev + # mozhi_engine: google - see https://mozhi.aryak.me for supported engines + timeout: 4.0 + shortcut: mz + disabled: true + + - name: mwmbl + engine: mwmbl + # api_url: https://api.mwmbl.org + shortcut: mwm + disabled: true + + - name: npm + engine: npm + shortcut: npm + timeout: 5.0 + disabled: true + + - name: nyaa + engine: nyaa + shortcut: nt + disabled: true + + - name: mankier + engine: json_engine + search_url: https://www.mankier.com/api/v2/mans/?q={query} + results_query: results + url_query: url + title_query: name + content_query: description + categories: it + shortcut: man + about: + website: https://www.mankier.com/ + official_api_documentation: https://www.mankier.com/api + use_official_api: true + require_api_key: false + results: JSON + + # read https://docs.searxng.org/dev/engines/online/mullvad_leta.html + # - name: mullvadleta + # engine: mullvad_leta + # leta_engine: google # choose one of the following: google, brave + # use_cache: true # Only 100 non-cache searches per day, suggested only for private instances + # search_url: https://leta.mullvad.net + # categories: [general, web] + # shortcut: ml + + - name: odysee + engine: odysee + shortcut: od + disabled: true + + - name: openairedatasets + engine: json_engine + paging: true + search_url: https://api.openaire.eu/search/datasets?format=json&page={pageno}&size=10&title={query} + results_query: response/results/result + url_query: metadata/oaf:entity/oaf:result/children/instance/webresource/url/$ + title_query: metadata/oaf:entity/oaf:result/title/$ + content_query: metadata/oaf:entity/oaf:result/description/$ + content_html_to_text: true + categories: "science" + shortcut: oad + timeout: 5.0 + about: + website: https://www.openaire.eu/ + wikidata_id: Q25106053 + official_api_documentation: https://api.openaire.eu/ + use_official_api: false + require_api_key: false + results: JSON + + - name: openairepublications + engine: json_engine + paging: true + search_url: https://api.openaire.eu/search/publications?format=json&page={pageno}&size=10&title={query} + results_query: response/results/result + url_query: metadata/oaf:entity/oaf:result/children/instance/webresource/url/$ + title_query: metadata/oaf:entity/oaf:result/title/$ + content_query: metadata/oaf:entity/oaf:result/description/$ + content_html_to_text: true + categories: science + shortcut: oap + timeout: 5.0 + about: + website: https://www.openaire.eu/ + wikidata_id: Q25106053 + official_api_documentation: https://api.openaire.eu/ + use_official_api: false + require_api_key: false + results: JSON + + - name: openlibrary + engine: openlibrary + shortcut: ol + timeout: 5 + disabled: true + + - name: openmeteo + engine: open_meteo + shortcut: om + disabled: true + + # - name: opensemanticsearch + # engine: opensemantic + # shortcut: oss + # base_url: 'http://localhost:8983/solr/opensemanticsearch/' + + - name: openstreetmap + engine: openstreetmap + shortcut: osm + + - name: openrepos + engine: xpath + paging: true + search_url: https://openrepos.net/search/node/{query}?page={pageno} + url_xpath: //li[@class="search-result"]//h3[@class="title"]/a/@href + title_xpath: //li[@class="search-result"]//h3[@class="title"]/a + content_xpath: //li[@class="search-result"]//div[@class="search-snippet-info"]//p[@class="search-snippet"] + categories: files + timeout: 4.0 + disabled: true + shortcut: or + about: + website: https://openrepos.net/ + wikidata_id: + official_api_documentation: + use_official_api: false + require_api_key: false + results: HTML + + - name: packagist + engine: json_engine + paging: true + search_url: https://packagist.org/search.json?q={query}&page={pageno} + results_query: results + url_query: url + title_query: name + content_query: description + categories: [it, packages] + disabled: true + timeout: 5.0 + shortcut: pack + about: + website: https://packagist.org + wikidata_id: Q108311377 + official_api_documentation: https://packagist.org/apidoc + use_official_api: true + require_api_key: false + results: JSON + + - name: pdbe + engine: pdbe + shortcut: pdb + # Hide obsolete PDB entries. Default is not to hide obsolete structures + # hide_obsolete: false + + - name: photon + engine: photon + shortcut: ph + + - name: pinterest + engine: pinterest + shortcut: pin + + - name: piped + engine: piped + shortcut: ppd + categories: videos + piped_filter: videos + timeout: 3.0 + + # URL to use as link and for embeds + frontend_url: https://srv.piped.video + # Instance will be selected randomly, for more see https://piped-instances.kavin.rocks/ + backend_url: + - https://pipedapi.adminforge.de + - https://pipedapi.nosebs.ru + - https://pipedapi.ducks.party + - https://pipedapi.reallyaweso.me + - https://api.piped.private.coffee + - https://pipedapi.darkness.services + + - name: piped.music + engine: piped + network: piped + shortcut: ppdm + categories: music + piped_filter: music_songs + timeout: 3.0 + + - name: piratebay + engine: piratebay + shortcut: tpb + # You may need to change this URL to a proxy if piratebay is blocked in your + # country + url: https://thepiratebay.org/ + timeout: 3.0 + + - name: pixiv + shortcut: pv + engine: pixiv + disabled: true + inactive: true + pixiv_image_proxies: + - https://pximg.example.org + # A proxy is required to load the images. Hosting an image proxy server + # for Pixiv: + # --> https://pixivfe.pages.dev/hosting-image-proxy-server/ + # Proxies from public instances. Ask the public instances owners if they + # agree to receive traffic from SearXNG! + # --> https://codeberg.org/VnPower/PixivFE#instances + # --> https://github.com/searxng/searxng/pull/3192#issuecomment-1941095047 + # image proxy of https://pixiv.cat + # - https://i.pixiv.cat + # image proxy of https://www.pixiv.pics + # - https://pximg.cocomi.eu.org + # image proxy of https://pixivfe.exozy.me + # - https://pximg.exozy.me + # image proxy of https://pixivfe.ducks.party + # - https://pixiv.ducks.party + # image proxy of https://pixiv.perennialte.ch + # - https://pximg.perennialte.ch + + - name: podcastindex + engine: podcastindex + shortcut: podcast + + # Required dependency: psychopg2 + # - name: postgresql + # engine: postgresql + # database: postgres + # username: postgres + # password: postgres + # limit: 10 + # query_str: 'SELECT * from my_table WHERE my_column = %(query)s' + # shortcut : psql + + - name: presearch + engine: presearch + search_type: search + categories: [general, web] + shortcut: ps + timeout: 4.0 + disabled: true + + - name: presearch images + engine: presearch + network: presearch + search_type: images + categories: [images, web] + timeout: 4.0 + shortcut: psimg + disabled: true + + - name: presearch videos + engine: presearch + network: presearch + search_type: videos + categories: [general, web] + timeout: 4.0 + shortcut: psvid + disabled: true + + - name: presearch news + engine: presearch + network: presearch + search_type: news + categories: [news, web] + timeout: 4.0 + shortcut: psnews + disabled: true + + - name: pub.dev + engine: xpath + shortcut: pd + search_url: https://pub.dev/packages?q={query}&page={pageno} + paging: true + results_xpath: //div[contains(@class,"packages-item")] + url_xpath: ./div/h3/a/@href + title_xpath: ./div/h3/a + content_xpath: ./div/div/div[contains(@class,"packages-description")]/span + categories: [packages, it] + timeout: 3.0 + disabled: true + first_page_num: 1 + about: + website: https://pub.dev/ + official_api_documentation: https://pub.dev/help/api + use_official_api: false + require_api_key: false + results: HTML + + - name: public domain image archive + engine: public_domain_image_archive + shortcut: pdia + + - name: pubmed + engine: pubmed + shortcut: pub + timeout: 3.0 + + - name: pypi + shortcut: pypi + engine: pypi + + - name: qwant + qwant_categ: web + engine: qwant + shortcut: qw + categories: [general, web] + additional_tests: + rosebud: *test_rosebud + + - name: qwant news + qwant_categ: news + engine: qwant + shortcut: qwn + categories: news + network: qwant + + - name: qwant images + qwant_categ: images + engine: qwant + shortcut: qwi + categories: [images, web] + network: qwant + + - name: qwant videos + qwant_categ: videos + engine: qwant + shortcut: qwv + categories: [videos, web] + network: qwant + + # - name: library + # engine: recoll + # shortcut: lib + # base_url: 'https://recoll.example.org/' + # search_dir: '' + # mount_prefix: /export + # dl_prefix: 'https://download.example.org' + # timeout: 30.0 + # categories: files + # disabled: true + + # - name: recoll library reference + # engine: recoll + # base_url: 'https://recoll.example.org/' + # search_dir: reference + # mount_prefix: /export + # dl_prefix: 'https://download.example.org' + # shortcut: libr + # timeout: 30.0 + # categories: files + # disabled: true + + - name: radio browser + engine: radio_browser + shortcut: rb + + - name: reddit + engine: reddit + shortcut: re + page_size: 25 + disabled: true + + - name: right dao + engine: xpath + paging: true + page_size: 12 + search_url: https://rightdao.com/search?q={query}&start={pageno} + results_xpath: //div[contains(@class, "description")] + url_xpath: ../div[contains(@class, "title")]/a/@href + title_xpath: ../div[contains(@class, "title")] + content_xpath: . + categories: general + shortcut: rd + disabled: true + about: + website: https://rightdao.com/ + use_official_api: false + require_api_key: false + results: HTML + + - name: rottentomatoes + engine: rottentomatoes + shortcut: rt + disabled: true + + # Required dependency: redis + # - name: myredis + # shortcut : rds + # engine: redis_server + # exact_match_only: false + # host: '127.0.0.1' + # port: 6379 + # enable_http: true + # password: '' + # db: 0 + + # tmp suspended: bad certificate + # - name: scanr structures + # shortcut: scs + # engine: scanr_structures + # disabled: true + + - name: searchmysite + engine: xpath + shortcut: sms + categories: general + paging: true + search_url: https://searchmysite.net/search/?q={query}&page={pageno} + results_xpath: //div[contains(@class,'search-result')] + url_xpath: .//a[contains(@class,'result-link')]/@href + title_xpath: .//span[contains(@class,'result-title-txt')]/text() + content_xpath: ./p[@id='result-hightlight'] + disabled: true + about: + website: https://searchmysite.net + + - name: sepiasearch + engine: sepiasearch + shortcut: sep + + - name: soundcloud + engine: soundcloud + shortcut: sc + + - name: stackoverflow + engine: stackexchange + shortcut: st + api_site: 'stackoverflow' + categories: [it, q&a] + + - name: askubuntu + engine: stackexchange + shortcut: ubuntu + api_site: 'askubuntu' + categories: [it, q&a] + + - name: superuser + engine: stackexchange + shortcut: su + api_site: 'superuser' + categories: [it, q&a] + + - name: discuss.python + engine: discourse + shortcut: dpy + base_url: 'https://discuss.python.org' + categories: [it, q&a] + disabled: true + + - name: caddy.community + engine: discourse + shortcut: caddy + base_url: 'https://caddy.community' + categories: [it, q&a] + disabled: true + + - name: pi-hole.community + engine: discourse + shortcut: pi + categories: [it, q&a] + base_url: 'https://discourse.pi-hole.net' + disabled: true + + - name: searchcode code + engine: searchcode_code + shortcut: scc + disabled: true + + # - name: searx + # engine: searx_engine + # shortcut: se + # instance_urls : + # - http://127.0.0.1:8888/ + # - ... + # disabled: true + + - name: semantic scholar + engine: semantic_scholar + disabled: true + shortcut: se + + # Spotify needs API credentials + # - name: spotify + # engine: spotify + # shortcut: stf + # api_client_id: ******* + # api_client_secret: ******* + + # - name: solr + # engine: solr + # shortcut: slr + # base_url: http://localhost:8983 + # collection: collection_name + # sort: '' # sorting: asc or desc + # field_list: '' # comma separated list of field names to display on the UI + # default_fields: '' # default field to query + # query_fields: '' # query fields + # enable_http: true + + # - name: springer nature + # engine: springer + # # get your API key from: https://dev.springernature.com/signup + # # working API key, for test & debug: "a69685087d07eca9f13db62f65b8f601" + # api_key: 'unset' + # shortcut: springer + # timeout: 15.0 + + - name: startpage + engine: startpage + shortcut: sp + startpage_categ: web + categories: [general, web] + additional_tests: + rosebud: *test_rosebud + + - name: startpage news + engine: startpage + startpage_categ: news + categories: [news, web] + shortcut: spn + + - name: startpage images + engine: startpage + startpage_categ: images + categories: [images, web] + shortcut: spi + + - name: tokyotoshokan + engine: tokyotoshokan + shortcut: tt + timeout: 6.0 + disabled: true + + - name: solidtorrents + engine: solidtorrents + shortcut: solid + timeout: 4.0 + base_url: + - https://solidtorrents.to + - https://bitsearch.to + + # For this demo of the sqlite engine download: + # https://liste.mediathekview.de/filmliste-v2.db.bz2 + # and unpack into searx/data/filmliste-v2.db + # Query to test: "!demo concert" + # + # - name: demo + # engine: sqlite + # shortcut: demo + # categories: general + # result_template: default.html + # database: searx/data/filmliste-v2.db + # query_str: >- + # SELECT title || ' (' || time(duration, 'unixepoch') || ')' AS title, + # COALESCE( NULLIF(url_video_hd,''), NULLIF(url_video_sd,''), url_video) AS url, + # description AS content + # FROM film + # WHERE title LIKE :wildcard OR description LIKE :wildcard + # ORDER BY duration DESC + + - name: tagesschau + engine: tagesschau + # when set to false, display URLs from Tagesschau, and not the actual source + # (e.g. NDR, WDR, SWR, HR, ...) + use_source_url: true + shortcut: ts + disabled: true + + - name: tmdb + engine: xpath + paging: true + categories: movies + search_url: https://www.themoviedb.org/search?page={pageno}&query={query} + results_xpath: //div[contains(@class,"movie") or contains(@class,"tv")]//div[contains(@class,"card")] + url_xpath: .//div[contains(@class,"poster")]/a/@href + thumbnail_xpath: .//img/@src + title_xpath: .//div[contains(@class,"title")]//h2 + content_xpath: .//div[contains(@class,"overview")] + shortcut: tm + disabled: true + + # Requires Tor + - name: torch + engine: xpath + paging: true + search_url: + http://xmh57jrknzkhv6y3ls3ubitzfqnkrwxhopf5aygthi7d6rplyvk3noyd.onion/cgi-bin/omega/omega?P={query}&DEFAULTOP=and + results_xpath: //table//tr + url_xpath: ./td[2]/a + title_xpath: ./td[2]/b + content_xpath: ./td[2]/small + categories: onions + enable_http: true + shortcut: tch + + # torznab engine lets you query any torznab compatible indexer. Using this + # engine in combination with Jackett opens the possibility to query a lot of + # public and private indexers directly from SearXNG. More details at: + # https://docs.searxng.org/dev/engines/online/torznab.html + # + # - name: Torznab EZTV + # engine: torznab + # shortcut: eztv + # base_url: http://localhost:9117/api/v2.0/indexers/eztv/results/torznab + # enable_http: true # if using localhost + # api_key: xxxxxxxxxxxxxxx + # show_magnet_links: true + # show_torrent_files: false + # # https://github.com/Jackett/Jackett/wiki/Jackett-Categories + # torznab_categories: # optional + # - 2000 + # - 5000 + + # tmp suspended - too slow, too many errors + # - name: urbandictionary + # engine : xpath + # search_url : https://www.urbandictionary.com/define.php?term={query} + # url_xpath : //*[@class="word"]/@href + # title_xpath : //*[@class="def-header"] + # content_xpath: //*[@class="meaning"] + # shortcut: ud + + - name: unsplash + engine: unsplash + shortcut: us + + - name: yandex + engine: yandex + categories: general + search_type: web + shortcut: yd + disabled: true + inactive: true + + - name: yandex images + engine: yandex + categories: images + search_type: images + shortcut: ydi + disabled: true + inactive: true + + - name: yandex music + engine: yandex_music + shortcut: ydm + disabled: true + # https://yandex.com/support/music/access.html + inactive: true + + - name: yahoo + engine: yahoo + shortcut: yh + disabled: true + + - name: yahoo news + engine: yahoo_news + shortcut: yhn + + - name: youtube + shortcut: yt + # You can use the engine using the official stable API, but you need an API + # key See: https://console.developers.google.com/project + # + # engine: youtube_api + # api_key: 'apikey' # required! + # + # Or you can use the html non-stable engine, activated by default + engine: youtube_noapi + + - name: dailymotion + engine: dailymotion + shortcut: dm + + - name: vimeo + engine: vimeo + shortcut: vm + + - name: wiby + engine: json_engine + paging: true + search_url: https://wiby.me/json/?q={query}&p={pageno} + url_query: URL + title_query: Title + content_query: Snippet + categories: [general, web] + shortcut: wib + disabled: true + about: + website: https://wiby.me/ + + - name: wikibooks + engine: mediawiki + weight: 0.5 + shortcut: wb + categories: [general, wikimedia] + base_url: "https://{language}.wikibooks.org/" + search_type: text + disabled: true + about: + website: https://www.wikibooks.org/ + wikidata_id: Q367 + + - name: wikinews + engine: mediawiki + shortcut: wn + categories: [news, wikimedia] + base_url: "https://{language}.wikinews.org/" + search_type: text + srsort: create_timestamp_desc + about: + website: https://www.wikinews.org/ + wikidata_id: Q964 + + - name: wikiquote + engine: mediawiki + weight: 0.5 + shortcut: wq + categories: [general, wikimedia] + base_url: "https://{language}.wikiquote.org/" + search_type: text + disabled: true + additional_tests: + rosebud: *test_rosebud + about: + website: https://www.wikiquote.org/ + wikidata_id: Q369 + + - name: wikisource + engine: mediawiki + weight: 0.5 + shortcut: ws + categories: [general, wikimedia] + base_url: "https://{language}.wikisource.org/" + search_type: text + disabled: true + about: + website: https://www.wikisource.org/ + wikidata_id: Q263 + + - name: wikispecies + engine: mediawiki + shortcut: wsp + categories: [general, science, wikimedia] + base_url: "https://species.wikimedia.org/" + search_type: text + disabled: true + about: + website: https://species.wikimedia.org/ + wikidata_id: Q13679 + tests: + wikispecies: + matrix: + query: "Campbell, L.I. et al. 2011: MicroRNAs" + lang: en + result_container: + - not_empty + - ['one_title_contains', 'Tardigrada'] + test: + - unique_results + + - name: wiktionary + engine: mediawiki + shortcut: wt + categories: [dictionaries, wikimedia] + base_url: "https://{language}.wiktionary.org/" + search_type: text + about: + website: https://www.wiktionary.org/ + wikidata_id: Q151 + + - name: wikiversity + engine: mediawiki + weight: 0.5 + shortcut: wv + categories: [general, wikimedia] + base_url: "https://{language}.wikiversity.org/" + search_type: text + disabled: true + about: + website: https://www.wikiversity.org/ + wikidata_id: Q370 + + - name: wikivoyage + engine: mediawiki + weight: 0.5 + shortcut: wy + categories: [general, wikimedia] + base_url: "https://{language}.wikivoyage.org/" + search_type: text + disabled: true + about: + website: https://www.wikivoyage.org/ + wikidata_id: Q373 + + - name: wikicommons.images + engine: wikicommons + shortcut: wc + categories: images + search_type: images + number_of_results: 10 + + - name: wikicommons.videos + engine: wikicommons + shortcut: wcv + categories: videos + search_type: videos + number_of_results: 10 + + - name: wikicommons.audio + engine: wikicommons + shortcut: wca + categories: music + search_type: audio + number_of_results: 10 + + - name: wikicommons.files + engine: wikicommons + shortcut: wcf + categories: files + search_type: files + number_of_results: 10 + + - name: wolframalpha + shortcut: wa + # You can use the engine using the official stable API, but you need an API + # key. See: https://products.wolframalpha.com/api/ + # + # engine: wolframalpha_api + # api_key: '' + # + # Or you can use the html non-stable engine, activated by default + engine: wolframalpha_noapi + timeout: 6.0 + categories: general + disabled: true + + - name: dictzone + engine: dictzone + shortcut: dc + + - name: mymemory translated + engine: translated + shortcut: tl + timeout: 5.0 + # You can use without an API key, but you are limited to 1000 words/day + # See: https://mymemory.translated.net/doc/usagelimits.php + # api_key: '' + + # Required dependency: mysql-connector-python + # - name: mysql + # engine: mysql_server + # database: mydatabase + # username: user + # password: pass + # limit: 10 + # query_str: 'SELECT * from mytable WHERE fieldname=%(query)s' + # shortcut: mysql + + # Required dependency: mariadb + # - name: mariadb + # engine: mariadb_server + # database: mydatabase + # username: user + # password: pass + # limit: 10 + # query_str: 'SELECT * from mytable WHERE fieldname=%(query)s' + # shortcut: mdb + + - name: 1337x + engine: 1337x + shortcut: 1337x + disabled: true + + - name: duden + engine: duden + shortcut: du + disabled: true + + - name: seznam + shortcut: szn + engine: seznam + disabled: true + + # - name: deepl + # engine: deepl + # shortcut: dpl + # # You can use the engine using the official stable API, but you need an API key + # # See: https://www.deepl.com/pro-api?cta=header-pro-api + # api_key: '' # required! + # timeout: 5.0 + # disabled: true + + - name: mojeek + shortcut: mjk + engine: mojeek + categories: [general, web] + disabled: true + + - name: mojeek images + shortcut: mjkimg + engine: mojeek + categories: [images, web] + search_type: images + paging: false + disabled: true + + - name: mojeek news + shortcut: mjknews + engine: mojeek + categories: [news, web] + search_type: news + paging: false + disabled: true + + - name: moviepilot + engine: moviepilot + shortcut: mp + disabled: true + + - name: naver + shortcut: nvr + categories: [general, web] + engine: xpath + paging: true + search_url: https://search.naver.com/search.naver?where=webkr&sm=osp_hty&ie=UTF-8&query={query}&start={pageno} + url_xpath: //a[@class="link_tit"]/@href + title_xpath: //a[@class="link_tit"] + content_xpath: //div[@class="total_dsc_wrap"]/a + first_page_num: 1 + page_size: 10 + disabled: true + about: + website: https://www.naver.com/ + wikidata_id: Q485639 + official_api_documentation: https://developers.naver.com/docs/nmt/examples/ + use_official_api: false + require_api_key: false + results: HTML + language: ko + + - name: rubygems + shortcut: rbg + engine: xpath + paging: true + search_url: https://rubygems.org/search?page={pageno}&query={query} + results_xpath: /html/body/main/div/a[@class="gems__gem"] + url_xpath: ./@href + title_xpath: ./span/h2 + content_xpath: ./span/p + suggestion_xpath: /html/body/main/div/div[@class="search__suggestions"]/p/a + first_page_num: 1 + categories: [it, packages] + disabled: true + about: + website: https://rubygems.org/ + wikidata_id: Q1853420 + official_api_documentation: https://guides.rubygems.org/rubygems-org-api/ + use_official_api: false + require_api_key: false + results: HTML + + - name: peertube + engine: peertube + shortcut: ptb + paging: true + # alternatives see: https://instances.joinpeertube.org/instances + # base_url: https://tube.4aem.com + categories: videos + disabled: true + timeout: 6.0 + + - name: mediathekviewweb + engine: mediathekviewweb + shortcut: mvw + disabled: true + + - name: yacy + # https://docs.searxng.org/dev/engines/online/yacy.html + engine: yacy + categories: general + search_type: text + base_url: + - https://yacy.searchlab.eu + # see https://github.com/searxng/searxng/pull/3631#issuecomment-2240903027 + # - https://search.kyun.li + # - https://yacy.securecomcorp.eu + # - https://yacy.myserv.ca + # - https://yacy.nsupdate.info + # - https://yacy.electroncash.de + shortcut: ya + disabled: true + # if you aren't using HTTPS for your local yacy instance disable https + # enable_http: false + search_mode: 'global' + # timeout can be reduced in 'local' search mode + timeout: 5.0 + + - name: yacy images + engine: yacy + network: yacy + categories: images + search_type: image + shortcut: yai + disabled: true + # timeout can be reduced in 'local' search mode + timeout: 5.0 + + - name: rumble + engine: rumble + shortcut: ru + base_url: https://rumble.com/ + paging: true + categories: videos + disabled: true + + - name: livespace + engine: livespace + shortcut: ls + categories: videos + disabled: true + timeout: 5.0 + + - name: wordnik + engine: wordnik + shortcut: def + categories: [dictionaries] + timeout: 5.0 + + - name: woxikon.de synonyme + engine: xpath + shortcut: woxi + categories: [dictionaries] + timeout: 5.0 + disabled: true + search_url: https://synonyme.woxikon.de/synonyme/{query}.php + url_xpath: //div[@class="upper-synonyms"]/a/@href + content_xpath: //div[@class="synonyms-list-group"] + title_xpath: //div[@class="upper-synonyms"]/a + no_result_for_http_status: [404] + about: + website: https://www.woxikon.de/ + wikidata_id: # No Wikidata ID + use_official_api: false + require_api_key: false + results: HTML + language: de + + - name: seekr news + engine: seekr + shortcut: senews + categories: news + seekr_category: news + disabled: true + + - name: seekr images + engine: seekr + network: seekr news + shortcut: seimg + categories: images + seekr_category: images + disabled: true + + - name: seekr videos + engine: seekr + network: seekr news + shortcut: sevid + categories: videos + seekr_category: videos + disabled: true + + - name: stract + engine: stract + shortcut: str + disabled: true + + - name: svgrepo + engine: svgrepo + shortcut: svg + timeout: 10.0 + disabled: true + + - name: tootfinder + engine: tootfinder + shortcut: toot + + - name: voidlinux + engine: voidlinux + shortcut: void + disabled: true + + - name: wallhaven + engine: wallhaven + # api_key: abcdefghijklmnopqrstuvwxyz + shortcut: wh + + # wikimini: online encyclopedia for children + # The fulltext and title parameter is necessary for Wikimini because + # sometimes it will not show the results and redirect instead + - name: wikimini + engine: xpath + shortcut: wkmn + search_url: https://fr.wikimini.org/w/index.php?search={query}&title=Sp%C3%A9cial%3ASearch&fulltext=Search + url_xpath: //li/div[@class="mw-search-result-heading"]/a/@href + title_xpath: //li//div[@class="mw-search-result-heading"]/a + content_xpath: //li/div[@class="searchresult"] + categories: general + disabled: true + about: + website: https://wikimini.org/ + wikidata_id: Q3568032 + use_official_api: false + require_api_key: false + results: HTML + language: fr + + - name: wttr.in + engine: wttr + shortcut: wttr + timeout: 9.0 + + - name: yummly + engine: yummly + shortcut: yum + disabled: true + + - name: brave + engine: brave + shortcut: br + time_range_support: true + paging: true + categories: [general, web] + brave_category: search + # brave_spellcheck: true + + - name: brave.images + engine: brave + network: brave + shortcut: brimg + categories: [images, web] + brave_category: images + + - name: brave.videos + engine: brave + network: brave + shortcut: brvid + categories: [videos, web] + brave_category: videos + + - name: brave.news + engine: brave + network: brave + shortcut: brnews + categories: news + brave_category: news + + # - name: brave.goggles + # engine: brave + # network: brave + # shortcut: brgog + # time_range_support: true + # paging: true + # categories: [general, web] + # brave_category: goggles + # Goggles: # required! This should be a URL ending in .goggle + + - name: lib.rs + shortcut: lrs + engine: lib_rs + disabled: true + + - name: sourcehut + shortcut: srht + engine: xpath + paging: true + search_url: https://sr.ht/projects?page={pageno}&search={query} + results_xpath: (//div[@class="event-list"])[1]/div[@class="event"] + url_xpath: ./h4/a[2]/@href + title_xpath: ./h4/a[2] + content_xpath: ./p + first_page_num: 1 + categories: [it, repos] + disabled: true + about: + website: https://sr.ht + wikidata_id: Q78514485 + official_api_documentation: https://man.sr.ht/ + use_official_api: false + require_api_key: false + results: HTML + + - name: goo + shortcut: goo + engine: xpath + paging: true + search_url: https://search.goo.ne.jp/web.jsp?MT={query}&FR={pageno}0 + url_xpath: //div[@class="result"]/p[@class='title fsL1']/a/@href + title_xpath: //div[@class="result"]/p[@class='title fsL1']/a + content_xpath: //p[contains(@class,'url fsM')]/following-sibling::p + first_page_num: 0 + categories: [general, web] + disabled: true + timeout: 4.0 + about: + website: https://search.goo.ne.jp + wikidata_id: Q249044 + use_official_api: false + require_api_key: false + results: HTML + language: ja + + - name: bt4g + engine: bt4g + shortcut: bt4g + + - name: pkg.go.dev + engine: pkg_go_dev + shortcut: pgo + disabled: true + +# Doku engine lets you access to any Doku wiki instance: +# A public one or a privete/corporate one. +# - name: ubuntuwiki +# engine: doku +# shortcut: uw +# base_url: 'https://doc.ubuntu-fr.org' + +# Be careful when enabling this engine if you are +# running a public instance. Do not expose any sensitive +# information. You can restrict access by configuring a list +# of access tokens under tokens. +# - name: git grep +# engine: command +# command: ['git', 'grep', '{{QUERY}}'] +# shortcut: gg +# tokens: [] +# disabled: true +# delimiter: +# chars: ':' +# keys: ['filepath', 'code'] + +# Be careful when enabling this engine if you are +# running a public instance. Do not expose any sensitive +# information. You can restrict access by configuring a list +# of access tokens under tokens. +# - name: locate +# engine: command +# command: ['locate', '{{QUERY}}'] +# shortcut: loc +# tokens: [] +# disabled: true +# delimiter: +# chars: ' ' +# keys: ['line'] + +# Be careful when enabling this engine if you are +# running a public instance. Do not expose any sensitive +# information. You can restrict access by configuring a list +# of access tokens under tokens. +# - name: find +# engine: command +# command: ['find', '.', '-name', '{{QUERY}}'] +# query_type: path +# shortcut: fnd +# tokens: [] +# disabled: true +# delimiter: +# chars: ' ' +# keys: ['line'] + +# Be careful when enabling this engine if you are +# running a public instance. Do not expose any sensitive +# information. You can restrict access by configuring a list +# of access tokens under tokens. +# - name: pattern search in files +# engine: command +# command: ['fgrep', '{{QUERY}}'] +# shortcut: fgr +# tokens: [] +# disabled: true +# delimiter: +# chars: ' ' +# keys: ['line'] + +# Be careful when enabling this engine if you are +# running a public instance. Do not expose any sensitive +# information. You can restrict access by configuring a list +# of access tokens under tokens. +# - name: regex search in files +# engine: command +# command: ['grep', '{{QUERY}}'] +# shortcut: gr +# tokens: [] +# disabled: true +# delimiter: +# chars: ' ' +# keys: ['line'] + +doi_resolvers: + oadoi.org: 'https://oadoi.org/' + doi.org: 'https://doi.org/' + doai.io: 'https://dissem.in/' + sci-hub.se: 'https://sci-hub.se/' + sci-hub.st: 'https://sci-hub.st/' + sci-hub.ru: 'https://sci-hub.ru/' + +default_doi_resolver: 'oadoi.org' diff --git a/docker-compose/production/logto/.env.example b/docker-compose/production/logto/.env.example deleted file mode 100644 index 7d3f84ece2..0000000000 --- a/docker-compose/production/logto/.env.example +++ /dev/null @@ -1,52 +0,0 @@ -# Required: LobeChat domain for tRPC calls -# Ensure this domain is whitelisted in your SSO providers and S3 service CORS settings -APP_URL=https://lobe.example.com/ - -# Postgres related environment variables -# Required: Secret key for encrypting sensitive information. Generate with: openssl rand -base64 32 -KEY_VAULTS_SECRET=Kix2wcUONd4CX51E/ZPAd36BqM4wzJgKjPtz2sGztqQ= -# Required: Postgres database connection string -# Format: postgresql://username:password@host:port/dbname -# If using Docker, you can use the container name as the host -DATABASE_URL=postgresql://postgres:uWNZugjBqixf8dxC@postgresql:5432/lobe - -# Authentication related environment variables -# Supports Auth0, Azure AD, GitHub, Authentik, Zitadel, Logto, etc. -# For supported providers, see: https://lobehub.com/docs/self-hosting/auth -# If you have ACCESS_CODE, please remove it. We use Better Auth as the sole authentication source -# Required: Auth secret key. Generate with: openssl rand -base64 32 -AUTH_SECRET=NX2kaPE923dt6BL2U8e9oSre5RfoT7hg -# Required: Specify the authentication provider (e.g., Logto) -AUTH_SSO_PROVIDERS=logto - -# SSO providers configuration (example using Logto) -# For other providers, see: https://lobehub.com/docs/self-hosting/environment-variables/auth -AUTH_LOGTO_ID=YOUR_LOGTO_ID -AUTH_LOGTO_SECRET=YOUR_LOGTO_SECRET -AUTH_LOGTO_ISSUER=https://lobe-auth-api.example.com/oidc - -# Proxy settings (if needed, e.g., when using GitHub as an auth provider) -# HTTP_PROXY=http://localhost:7890 -# HTTPS_PROXY=http://localhost:7890 - -# S3 related environment variables (example using MinIO) -# Required: S3 Access Key ID (for MinIO, invalid until manually created in MinIO UI) -S3_ACCESS_KEY_ID=YOUR_S3_ACCESS_KEY_ID -# Required: S3 Secret Access Key (for MinIO, invalid until manually created in MinIO UI) -S3_SECRET_ACCESS_KEY=YOUR_S3_SECRET_ACCESS_KEY -# Required: S3 Endpoint for server/client connections to S3 API -S3_ENDPOINT=https://lobe-s3-api.example.com -# Required: S3 Bucket (invalid until manually created in MinIO UI) -S3_BUCKET=lobe -# Optional: S3 Enable Path Style -# Use 0 for mainstream S3 cloud providers; use 1 for self-hosted MinIO -# See: https://lobehub.com/docs/self-hosting/advanced/s3#s-3-enable-path-style -S3_ENABLE_PATH_STYLE=1 - -# Other basic environment variables (as needed) -# See: https://lobehub.com/docs/self-hosting/environment-variables/basic -# Note: For server versions, the API must support embedding models (OpenAI text-embedding-3-small) for file processing -# You don't need to specify this model in OPENAI_MODEL_LIST -# OPENAI_API_KEY=sk-xxxx -# OPENAI_PROXY_URL=https://api.openai.com/v1 -# OPENAI_MODEL_LIST=... diff --git a/docker-compose/production/logto/.env.zh-CN.example b/docker-compose/production/logto/.env.zh-CN.example deleted file mode 100644 index 39acf053d6..0000000000 --- a/docker-compose/production/logto/.env.zh-CN.example +++ /dev/null @@ -1,51 +0,0 @@ -# 必填,LobeChat 域名,用于 tRPC 调用 -# 请保证此域名在你的 SSO 鉴权服务提供商、S3 服务商的 CORS 白名单中 -APP_URL=https://lobe.example.com/ - -# Postgres 相关,也即 DB 必需的环境变量 -# 必填,用于加密敏感信息的密钥,可以使用 openssl rand -base64 32 生成 -KEY_VAULTS_SECRET=Kix2wcUONd4CX51E/ZPAd36BqM4wzJgKjPtz2sGztqQ= -# 必填,Postgres 数据库连接字符串,用于连接到数据库 -# 格式:postgresql://username:password@host:port/dbname,如果你的 pg 实例为 Docker 容器且位于同一 docker-compose 文件中,亦可使用容器名作为 host -DATABASE_URL=postgresql://postgres:uWNZugjBqixf8dxC@postgresql:5432/lobe - -# 鉴权服务必需的环境变量 -# 可以使用 Auth0、Azure AD、GitHub、Authentik、Zitadel、Logto 等,如有其他接入诉求欢迎提 PR -# 目前支持的鉴权服务提供商请参考:https://lobehub.com/zh/docs/self-hosting/auth -# 如果你有 ACCESS_CODE,请务必清空,我们以 Better Auth 作为唯一鉴权来源 -# 必填,用于鉴权的密钥,可以使用 openssl rand -base64 32 生成 -AUTH_SECRET=NX2kaPE923dt6BL2U8e9oSre5RfoT7hg -# 必填,指定鉴权服务提供商,这里以 Logto 为例 -AUTH_SSO_PROVIDERS=logto - -# SSO 鉴权服务提供商部分,以 Logto 为例 -# 其他鉴权服务提供商所需的环境变量,请参考:https://lobehub.com/zh/docs/self-hosting/environment-variables/auth -AUTH_LOGTO_ID=YOUR_LOGTO_ID -AUTH_LOGTO_SECRET=YOUR_LOGTO_SECRET -AUTH_LOGTO_ISSUER=https://lobe-auth-api.example.com/oidc - -# 代理相关,如果你需要的话(比如你使用 GitHub 作为鉴权服务提供商) -# HTTP_PROXY=http://localhost:7890 -# HTTPS_PROXY=http://localhost:7890 - -# S3 相关,也即非结构化数据(文件、图片等)存储必需的环境变量 -# 这里以 MinIO 为例 -# 必填,S3 的 Access Key ID,对于 MinIO 来说,直到在 MinIO UI 中手动创建之前都是无效的 -S3_ACCESS_KEY_ID=YOUR_S3_ACCESS_KEY_ID -# 必填,S3 的 Secret Access Key,对于 MinIO 来说,直到在 MinIO UI 中手动创建之前都是无效的 -S3_SECRET_ACCESS_KEY=YOUR_S3_SECRET_ACCESS_KEY -# 必填,S3 的 Endpoint,用于服务端/客户端连接到 S3 API -S3_ENDPOINT=https://lobe-s3-api.example.com -# 必填,S3 的 Bucket,直到在 MinIO UI 中手动创建之前都是无效的 -S3_BUCKET=lobe -# 选填,S3 的 Enable Path Style -# 对于主流 S3 Cloud 服务商,一般填 0 即可;对于自部署的 MinIO,请填 1 -# 请参考:https://lobehub.com/zh/docs/self-hosting/advanced/s3#s-3-enable-path-style -S3_ENABLE_PATH_STYLE=1 - -# 其他基础环境变量,视需求而定。注意不要有 ACCESS_CODE -# 请参考:https://lobehub.com/zh/docs/self-hosting/environment-variables/basic -# 请注意,对于服务端版本,其 API 必须支持嵌入(即 OpenAI text-embedding-3-small)模型,否则无法对上传文件进行处理,但你无需在 OPENAI_MODEL_LIST 中指定此模型 -# OPENAI_API_KEY=sk-xxxx -# OPENAI_PROXY_URL=https://api.openai.com/v1 -# OPENAI_MODEL_LIST=... diff --git a/docker-compose/production/logto/docker-compose.yml b/docker-compose/production/logto/docker-compose.yml deleted file mode 100644 index 41f805dad4..0000000000 --- a/docker-compose/production/logto/docker-compose.yml +++ /dev/null @@ -1,71 +0,0 @@ -name: lobehub -services: - postgresql: - image: pgvector/pgvector:pg16 - container_name: lobe-postgres - ports: - - '5432:5432' - volumes: - - './data:/var/lib/postgresql/data' - environment: - - 'POSTGRES_DB=lobe' - - 'POSTGRES_PASSWORD=uWNZugjBqixf8dxC' - healthcheck: - test: ['CMD-SHELL', 'pg_isready -U postgres'] - interval: 5s - timeout: 5s - retries: 5 - restart: always - - minio: - image: minio/minio:RELEASE.2025-04-22T22-12-26Z - container_name: lobe-minio - ports: - - '9000:9000' - - '9001:9001' - volumes: - - './s3_data:/etc/minio/data' - environment: - - 'MINIO_ROOT_USER=YOUR_MINIO_USER' - - 'MINIO_ROOT_PASSWORD=YOUR_MINIO_PASSWORD' - - 'MINIO_DOMAIN=lobe-s3-api.example.com' - - 'MINIO_API_CORS_ALLOW_ORIGIN=https://lobe.example.com' # Your LobeChat's domain name. - restart: always - command: > - server /etc/minio/data --address ":9000" --console-address ":9001" - - - logto: - image: svhd/logto - container_name: lobe-logto - ports: - - '3001:3001' - - '3002:3002' - depends_on: - postgresql: - condition: service_healthy - environment: - - 'TRUST_PROXY_HEADER=1' - - 'DB_URL=postgresql://postgres:uWNZugjBqixf8dxC@postgresql:5432/logto' - - 'ENDPOINT=https://lobe-auth-api.example.com' - - 'ADMIN_ENDPOINT=https://lobe-auth-ui.example.com' - entrypoint: ['sh', '-c', 'npm run cli db seed -- --swe && npm start'] - - lobe: - image: lobehub/lobehub - container_name: lobehub - ports: - - '3210:3210' - depends_on: - - postgresql - - minio - - logto - env_file: - - .env - restart: always - -volumes: - data: - driver: local - s3_data: - driver: local diff --git a/docker-compose/production/zitadel/.env.example b/docker-compose/production/zitadel/.env.example deleted file mode 100644 index 544fd8c2c1..0000000000 --- a/docker-compose/production/zitadel/.env.example +++ /dev/null @@ -1,49 +0,0 @@ -# Required: LobeChat domain for tRPC calls -# Ensure this domain is whitelisted in your SSO providers and S3 service CORS settings -APP_URL=https://lobe.example.com/ - -# Postgres related environment variables -# Required: Secret key for encrypting sensitive information. Generate with: openssl rand -base64 32 -KEY_VAULTS_SECRET=Kix2wcUONd4CX51E/ZPAd36BqM4wzJgKjPtz2sGztqQ= -# Required: Postgres database connection string -# Format: postgresql://username:password@host:port/dbname -# If using Docker, you can use the container name as the host -DATABASE_URL=postgresql://postgres:uWNZugjBqixf8dxC@postgresql:5432/lobe - -# Authentication related environment variables -# Required: Auth secret key. Generate with: openssl rand -base64 32 -AUTH_SECRET=NX2kaPE923dt6BL2U8e9oSre5RfoT7hg -# Required: Specify the authentication provider -AUTH_SSO_PROVIDERS=zitadel - -# ZiTADEL provider configuration -# Please refer to: https://lobehub.com/docs/self-hosting/auth/providers/zitadel -AUTH_ZITADEL_ID=285934220675723622 -AUTH_ZITADEL_SECRET=pe7Nh3lopXkZkfqh5YEDYI2xsbIz08eZKqInOUZxssd3refRia518Apbv3DZ -AUTH_ZITADEL_ISSUER=https://zitadel.example.com - -# Proxy settings (if needed, e.g., when using GitHub as an auth provider) -# HTTP_PROXY=http://localhost:7890 -# HTTPS_PROXY=http://localhost:7890 - -# S3 related environment variables (example using MinIO) -# Required: S3 Access Key ID (for MinIO, invalid until manually created in MinIO UI) -S3_ACCESS_KEY_ID=YOUR_S3_ACCESS_KEY_ID -# Required: S3 Secret Access Key (for MinIO, invalid until manually created in MinIO UI) -S3_SECRET_ACCESS_KEY=YOUR_S3_SECRET_ACCESS_KEY -# Required: S3 Endpoint for server/client connections to S3 API -S3_ENDPOINT=https://lobe-s3-api.example.com -# Required: S3 Bucket (invalid until manually created in MinIO UI) -S3_BUCKET=lobe -# Optional: S3 Enable Path Style -# Use 0 for mainstream S3 cloud providers; use 1 for self-hosted MinIO -# See: https://lobehub.com/docs/self-hosting/advanced/s3#s-3-enable-path-style -S3_ENABLE_PATH_STYLE=1 - -# Other basic environment variables (as needed) -# See: https://lobehub.com/docs/self-hosting/environment-variables/basic -# Note: For server versions, the API must support embedding models (OpenAI text-embedding-3-small) for file processing -# You don't need to specify this model in OPENAI_MODEL_LIST -# OPENAI_API_KEY=sk-xxxx -# OPENAI_PROXY_URL=https://api.openai.com/v1 -# OPENAI_MODEL_LIST=... diff --git a/docker-compose/production/zitadel/.env.zh-CN.example b/docker-compose/production/zitadel/.env.zh-CN.example deleted file mode 100644 index 3e87bdf173..0000000000 --- a/docker-compose/production/zitadel/.env.zh-CN.example +++ /dev/null @@ -1,44 +0,0 @@ -# 必填,LobeChat 域名,用于 tRPC 调用 -# 请保证此域名在你的 SSO 鉴权服务提供商、S3 服务商的 CORS 白名单中 -APP_URL=https://lobe.example.com/ - -# Postgres 相关,也即 DB 必需的环境变量 -# 必填,用于加密敏感信息的密钥,可以使用 openssl rand -base64 32 生成 -KEY_VAULTS_SECRET=Kix2wcUONd4CX51E/ZPAd36BqM4wzJgKjPtz2sGztqQ= -# 必填,Postgres 数据库连接字符串,用于连接到数据库 -# 格式:postgresql://username:password@host:port/dbname,如果你的 pg 实例为 Docker 容器且位于同一 docker-compose 文件中,亦可使用容器名作为 host -DATABASE_URL=postgresql://postgres:uWNZugjBqixf8dxC@postgresql:5432/lobe - -# 鉴权服务必需的环境变量 -# 必填,用于鉴权的密钥,可以使用 openssl rand -base64 32 生成 -AUTH_SECRET=NX2kaPE923dt6BL2U8e9oSre5RfoT7hg -# 必填,指定鉴权服务提供商 -AUTH_SSO_PROVIDERS=zitadel - -# ZiTADEL 鉴权服务提供商部分 -# 请参考:https://lobehub.com/zh/docs/self-hosting/auth/providers/zitadel -AUTH_ZITADEL_ID=285934220675723622 -AUTH_ZITADEL_SECRET=pe7Nh3lopXkZkfqh5YEDYI2xsbIz08eZKqInOUZxssd3refRia518Apbv3DZ -AUTH_ZITADEL_ISSUER=https://zitadel.example.com - -# S3 相关,也即非结构化数据(文件、图片等)存储必需的环境变量 -# 这里以 MinIO 为例 -# 必填,S3 的 Access Key ID,对于 MinIO 来说,直到在 MinIO UI 中手动创建之前都是无效的 -S3_ACCESS_KEY_ID=YOUR_S3_ACCESS_KEY_ID -# 必填,S3 的 Secret Access Key,对于 MinIO 来说,直到在 MinIO UI 中手动创建之前都是无效的 -S3_SECRET_ACCESS_KEY=YOUR_S3_SECRET_ACCESS_KEY -# 必填,S3 的 Endpoint,用于服务端/客户端连接到 S3 API -S3_ENDPOINT=https://lobe-s3-api.example.com -# 必填,S3 的 Bucket,直到在 MinIO UI 中手动创建之前都是无效的 -S3_BUCKET=lobe -# 选填,S3 的 Enable Path Style -# 对于主流 S3 Cloud 服务商,一般填 0 即可;对于自部署的 MinIO,请填 1 -# 请参考:https://lobehub.com/zh/docs/self-hosting/advanced/s3#s-3-enable-path-style -S3_ENABLE_PATH_STYLE=1 - -# 其他基础环境变量,视需求而定。注意不要有 ACCESS_CODE -# 请参考:https://lobehub.com/zh/docs/self-hosting/environment-variables/basic -# 请注意,对于服务端版本,其 API 必须支持嵌入(即 OpenAI text-embedding-3-small)模型,否则无法对上传文件进行处理,但你无需在 OPENAI_MODEL_LIST 中指定此模型 -# OPENAI_API_KEY=sk-xxxx -# OPENAI_PROXY_URL=https://api.openai.com/v1 -# OPENAI_MODEL_LIST=... diff --git a/docker-compose/production/zitadel/docker-compose.yml b/docker-compose/production/zitadel/docker-compose.yml deleted file mode 100644 index 935cd23e81..0000000000 --- a/docker-compose/production/zitadel/docker-compose.yml +++ /dev/null @@ -1,69 +0,0 @@ -name: lobehub -services: - postgresql: - image: pgvector/pgvector:pg16 - container_name: lobe-postgres - ports: - - '5432:5432' - volumes: - - './data:/var/lib/postgresql/data' - environment: - - 'POSTGRES_DB=lobe' - - 'POSTGRES_PASSWORD=uWNZugjBqixf8dxC' - healthcheck: - test: ['CMD-SHELL', 'pg_isready -U postgres'] - interval: 5s - timeout: 5s - retries: 5 - restart: always - - minio: - image: minio/minio:RELEASE.2025-04-22T22-12-26Z - container_name: lobe-minio - ports: - - '9000:9000' - - '9001:9001' - volumes: - - './s3_data:/etc/minio/data' - environment: - - 'MINIO_ROOT_USER=YOUR_MINIO_USER' - - 'MINIO_ROOT_PASSWORD=YOUR_MINIO_PASSWORD' - - 'MINIO_DOMAIN=lobe-s3-api.example.com' - - 'MINIO_API_CORS_ALLOW_ORIGIN=https://lobe.example.com' # Your LobeChat's domain name. - restart: always - command: > - server /etc/minio/data --address ":9000" --console-address ":9001" - - - zitadel: - restart: always - image: ghcr.io/zitadel/zitadel:latest - container_name: lobe-zitadel - command: start-from-init --config /zitadel-config.yaml --steps /zitadel-init-steps.yaml --masterkey "cft3Tekr/rQBOqwoQSCPoncA9BHbn7QJ" --tlsMode external #MasterkeyNeedsToHave32Characters - ports: - - 8080:8080 - volumes: - - ./zitadel-config.yaml:/zitadel-config.yaml:ro - - ./zitadel-init-steps.yaml:/zitadel-init-steps.yaml:ro - depends_on: - postgresql: - condition: service_healthy - - lobe: - image: lobehub/lobehub - container_name: lobehub - ports: - - '3210:3210' - depends_on: - - postgresql - - minio - - zitadel - env_file: - - .env - restart: always - -volumes: - data: - driver: local - s3_data: - driver: local diff --git a/docker-compose/production/zitadel/zitadel-config.yaml b/docker-compose/production/zitadel/zitadel-config.yaml deleted file mode 100644 index bd7e7a9f18..0000000000 --- a/docker-compose/production/zitadel/zitadel-config.yaml +++ /dev/null @@ -1,25 +0,0 @@ -Log: - Level: 'info' - -ExternalPort: 443 -ExternalDomain: example.com #Your zitadel's domain name -ExternalSecure: true -TLS: - Enabled: false # ZITADEL_TLS_ENABLED - -# If not using the docker compose example, adjust these values for connecting ZITADEL to your PostgreSQL -Database: - postgres: - Host: postgresql - Port: 5432 - Database: zitadel - User: - Username: 'zitadel' - Password: 'zitadel' - SSL: - Mode: 'disable' - Admin: - Username: 'postgres' - Password: 'uWNZugjBqixf8dxC' #postgres password - SSL: - Mode: 'disable' diff --git a/docker-compose/production/zitadel/zitadel-init-steps.yaml b/docker-compose/production/zitadel/zitadel-init-steps.yaml deleted file mode 100644 index 6d72bfb892..0000000000 --- a/docker-compose/production/zitadel/zitadel-init-steps.yaml +++ /dev/null @@ -1,11 +0,0 @@ -# All possible options and their defaults: https://github.com/zitadel/zitadel/blob/main/cmd/setup/steps.yaml -FirstInstance: - Org: - Human: - # use the loginname root@zitadel.localhost, replace localhost with your configured external domain - Username: 'root' - # The password must be 8 characters or more and must contain uppercase letters, lowercase letters, symbols, and numbers. The first login will require a password change. - Password: 'Password1!' - Email: - # Optional, if set, can be used to log in with email. - Address: 'example@zitadel.com' # ZITADEL_FIRSTINSTANCE_ORG_HUMAN_EMAIL_ADDRESS diff --git a/docker-compose/setup.sh b/docker-compose/setup.sh index ea8ec4b03a..5a2ab9f717 100644 --- a/docker-compose/setup.sh +++ b/docker-compose/setup.sh @@ -668,12 +668,33 @@ section_regenerate_secrets() { echo $(show_message "security_secrect_regenerate_failed") "RUSTFS_SECRET_KEY" RUSTFS_SECRET_KEY="YOUR_RUSTFS_PASSWORD" else - # Search and replace the value of S3_SECRET_ACCESS_KEY in .env sed "${SED_INPLACE_ARGS[@]}" "s#^RUSTFS_SECRET_KEY=.*#RUSTFS_SECRET_KEY=${RUSTFS_SECRET_KEY}#" .env if [ $? -ne 0 ]; then echo $(show_message "security_secrect_regenerate_failed") "RUSTFS_SECRET_KEY in \`.env\`" fi fi + + # Generate KEY_VAULTS_SECRET (base64 encoded 32 bytes) + KEY_VAULTS_SECRET=$(openssl rand -base64 32) + if [ $? -ne 0 ]; then + echo $(show_message "security_secrect_regenerate_failed") "KEY_VAULTS_SECRET" + else + sed "${SED_INPLACE_ARGS[@]}" "s#^KEY_VAULTS_SECRET=.*#KEY_VAULTS_SECRET=${KEY_VAULTS_SECRET}#" .env + if [ $? -ne 0 ]; then + echo $(show_message "security_secrect_regenerate_failed") "KEY_VAULTS_SECRET in \`.env\`" + fi + fi + + # Generate AUTH_SECRET (base64 encoded 32 bytes) + AUTH_SECRET=$(openssl rand -base64 32) + if [ $? -ne 0 ]; then + echo $(show_message "security_secrect_regenerate_failed") "AUTH_SECRET" + else + sed "${SED_INPLACE_ARGS[@]}" "s#^AUTH_SECRET=.*#AUTH_SECRET=${AUTH_SECRET}#" .env + if [ $? -ne 0 ]; then + echo $(show_message "security_secrect_regenerate_failed") "AUTH_SECRET in \`.env\`" + fi + fi } show_message "ask_regenerate_secrets" diff --git a/docs/development/basic/setup-development.mdx b/docs/development/basic/setup-development.mdx index b48c9b9629..017f758088 100644 --- a/docs/development/basic/setup-development.mdx +++ b/docs/development/basic/setup-development.mdx @@ -36,7 +36,7 @@ First, you need to install the following software: - PNPM: We use PNPM as the preferred package manager. You can download and install it from the [PNPM official website](https://pnpm.io/installation). - Bun: We use Bun as the npm scripts runner. You can download and install it from the [Bun official website](https://bun.com/docs/installation). - Git: We use Git for version control. You can download and install it from the Git official website. -- Docker: Required for running PostgreSQL, MinIO, and other services. You can download and install it from the [Docker official website](https://www.docker.com/get-started). +- Docker: Required for running PostgreSQL, RustFS, and other services. You can download and install it from the [Docker official website](https://www.docker.com/get-started). - IDE: You can choose your preferred integrated development environment (IDE). We recommend using WebStorm/VSCode. ### VSCode Users @@ -66,38 +66,40 @@ pnpm i #### 3. Configure Environment -Copy the example environment file to create your Docker Compose configuration: +Copy the example environment files: ```bash -cp docker-compose/local/.env.example docker-compose/local/.env +# Docker services configuration +cp docker-compose/dev/.env.example docker-compose/dev/.env + +# Next.js development server configuration +cp .env.example.development .env ``` -Edit `docker-compose/local/.env` as needed for your development setup. This file contains all necessary environment variables for the Docker services and configures: +Edit these files as needed: -- **Database**: PostgreSQL with connection string -- **Authentication**: Better Auth with Casdoor SSO -- **Storage**: MinIO S3-compatible storage -- **Search**: SearXNG search engine +- `docker-compose/dev/.env` - Docker services (PostgreSQL, Redis, RustFS, SearXNG) +- `.env` - Next.js dev server (database connection, S3 storage, auth, etc.) #### 4. Start Docker Services Start all required services using Docker Compose: ```bash -docker-compose -f docker-compose.development.yml up -d +bun run dev:docker ``` This will start the following services: - PostgreSQL database (port 5432) -- MinIO storage (port 9000) -- Casdoor authentication (port 8000) -- SearXNG search (port 8080) +- Redis cache (port 6379) +- RustFS storage (API port 9000, Console port 9001) +- SearXNG search (port 8180) You can check all Docker services are running by running: ```bash -docker-compose -f docker-compose.development.yml ps +docker compose -f docker-compose/dev/docker-compose.yml ps ``` #### 5. Run Database Migrations @@ -122,83 +124,15 @@ Now, you can open `http://localhost:3010` in your browser, and you should see th ![](https://github-production-user-asset-6210df.s3.amazonaws.com/28616219/274655364-414bc31e-8511-47a3-af17-209b530effc7.png) -## Image Generation Development - -When working with image generation features (text-to-image, image-to-image), the Docker Compose setup already includes all necessary storage services for handling generated images and user uploads. - -### Image Generation Configuration - -The existing Docker Compose configuration already includes MinIO storage service and all necessary environment variables in `docker-compose/local/.env.example`. No additional setup is required. - -### Image Generation Architecture - -The image generation feature requires: - -- **PostgreSQL**: Stores metadata about generated images -- **MinIO/S3**: Stores the actual image files - -### Storage Configuration - -The `docker-compose/local/.env.example` file includes all necessary S3 environment variables: - -```bash -# S3 Storage Configuration (MinIO for local development) -S3_ACCESS_KEY_ID=${MINIO_ROOT_USER} -S3_SECRET_ACCESS_KEY=${MINIO_ROOT_PASSWORD} -S3_ENDPOINT=http://localhost:${MINIO_PORT} -S3_BUCKET=${MINIO_LOBE_BUCKET} -S3_ENABLE_PATH_STYLE=1 # Required for MinIO -S3_SET_ACL=0 # MinIO compatibility -``` - -### File Storage Structure - -Generated images and user uploads are organized in the MinIO bucket: - -``` -lobe/ # S3 Bucket (MINIO_LOBE_BUCKET) -├── generated/ # Generated images -│ └── {userId}/ -│ └── {sessionId}/ -│ └── {imageId}.png -└── uploads/ # User uploads for image-to-image - └── {userId}/ - └── {fileId}.{ext} -``` - -### Development Workflow for Images - -When developing image generation features, generated images will be: - -1. Created by the AI model -2. Uploaded to S3/MinIO via presigned URLs -3. Metadata stored in PostgreSQL -4. Served via the public S3 URL - -Example code for testing image upload: - -```typescript -// Example: Upload generated image -const uploadUrl = await trpc.upload.createPresignedUrl.mutate({ - filename: 'generated-image.png', - contentType: 'image/png', -}); - -// Upload to S3 -await fetch(uploadUrl, { - method: 'PUT', - body: imageBlob, - headers: { 'Content-Type': 'image/png' }, -}); -``` - -### Service URLs +## Service URLs When running with Docker Compose development setup: -- **PostgreSQL**: `postgres://postgres@localhost:5432/LobeHub` -- **MinIO API**: `http://localhost:9000` -- **MinIO Console**: `http://localhost:9001` (admin/CHANGE\_THIS\_PASSWORD\_IN\_PRODUCTION) +- **PostgreSQL**: `postgres://postgres@localhost:5432/lobechat` +- **Redis**: `redis://localhost:6379` +- **RustFS API**: `http://localhost:9000` +- **RustFS Console**: `http://localhost:9001` +- **SearXNG**: `http://localhost:8180` - **Application**: `http://localhost:3010` ## Troubleshooting @@ -208,15 +142,8 @@ When running with Docker Compose development setup: If you encounter issues, you can reset the entire stack: ```bash -# Stop and remove all containers -docker-compose -f docker-compose.development.yml down - -# Remove volumes (this will delete all data) -docker-compose -f docker-compose.development.yml down -v - -# Start fresh -docker-compose -f docker-compose.development.yml up -d -pnpm db:migrate +# Completely reset Docker environment (delete all data and restart) +bun run dev:docker:reset ``` ### Port Conflicts @@ -226,20 +153,20 @@ If ports are already in use: ```bash # Check what's using the ports lsof -i :5432 # PostgreSQL -lsof -i :9000 # MinIO API -lsof -i :9001 # MinIO Console +lsof -i :6379 # Redis +lsof -i :9000 # RustFS API +lsof -i :9001 # RustFS Console +lsof -i :8180 # SearXNG ``` ### Database Migrations -The setup script runs migrations automatically. If you need to run them manually: +Run migrations manually when needed: ```bash pnpm db:migrate ``` -Note: In development mode with `pnpm dev:desktop`, migrations also run automatically on startup. - --- During the development process, if you encounter any issues with environment setup or have any questions about LobeHub development, feel free to ask us at any time. We look forward to seeing your contributions! diff --git a/docs/development/basic/setup-development.zh-CN.mdx b/docs/development/basic/setup-development.zh-CN.mdx index e11e41e427..7b3bdd45aa 100644 --- a/docs/development/basic/setup-development.zh-CN.mdx +++ b/docs/development/basic/setup-development.zh-CN.mdx @@ -33,7 +33,7 @@ tags: - PNPM:我们使用 PNPM 作为管理器。你可以从 [pnpm 的官方网站](https://pnpm.io/installation) 上下载并安装。 - Bun:我们使用 Bun 作为 npm scripts runner,你可以从 [Bun 的官方网站](https://bun.com/docs/installation) 上下载并安装。 - Git:我们使用 Git 进行版本控制。你可以从 Git 的官方网站上下载并安装。 -- Docker:用于运行 PostgreSQL、MinIO 等服务。你可以从 [Docker 官方网站](https://www.docker.com/get-started) 下载并安装。 +- Docker:用于运行 PostgreSQL、RustFS 等服务。你可以从 [Docker 官方网站](https://www.docker.com/get-started) 下载并安装。 - IDE:你可以选择你喜欢的集成开发环境(IDE),我们推荐使用 WebStorm/VSCode。 ### VSCode 用户 @@ -63,38 +63,40 @@ pnpm i #### 3. 配置环境 -复制示例环境文件来创建你的 Docker Compose 配置: +复制示例环境文件: ```bash -cp docker-compose/local/.env.example docker-compose/local/.env +# Docker 服务配置 +cp docker-compose/dev/.env.example docker-compose/dev/.env + +# Next.js 开发服务器配置 +cp .env.example.development .env ``` -根据需要编辑 `docker-compose/local/.env` 文件以适应你的开发设置。此文件包含 Docker 服务所需的所有环境变量,配置了: +根据需要编辑这些文件: -- **数据库**:带连接字符串的 PostgreSQL -- **身份验证**:带 Casdoor SSO 的 Better Auth -- **存储**:MinIO S3 兼容存储 -- **搜索**:SearXNG 搜索引擎 +- `docker-compose/dev/.env` - Docker 服务配置(PostgreSQL、Redis、RustFS、SearXNG) +- `.env` - Next.js 开发服务器配置(数据库连接、S3 存储、认证等) #### 4. 启动 Docker 服务 使用 Docker Compose 启动所有必需的服务: ```bash -docker-compose -f docker-compose.development.yml up -d +bun run dev:docker ``` 这将启动以下服务: - PostgreSQL 数据库(端口 5432) -- MinIO 存储(端口 9000) -- Casdoor 身份验证(端口 8000) -- SearXNG 搜索(端口 8080) +- Redis 缓存(端口 6379) +- RustFS 存储(API 端口 9000,控制台端口 9001) +- SearXNG 搜索(端口 8180) 可以通过运行以下命令检查所有 Docker 服务运行状态: ```bash -docker-compose -f docker-compose.development.yml ps +docker compose -f docker-compose/dev/docker-compose.yml ps ``` #### 5. 运行数据库迁移 @@ -119,83 +121,15 @@ bun run dev ![Chat Page](https://hub-apac-1.lobeobjects.space/docs/fc7b157a3bc016bc97719065f80c555c.png) -## 图像生成开发 - -在开发图像生成功能(文生图、图生图)时,Docker Compose 配置已经包含了处理生成图像和用户上传所需的所有存储服务。 - -### 图像生成配置 - -现有的 Docker Compose 配置已经包含了 MinIO 存储服务以及 `docker-compose/local/.env.example` 中的所有必要环境变量。无需额外配置。 - -### 图像生成架构 - -图像生成功能需要: - -- **PostgreSQL**:存储生成图像的元数据 -- **MinIO/S3**:存储实际的图像文件 - -### 存储配置 - -`docker-compose/local/.env.example` 文件包含所有必要的 S3 环境变量: - -```bash -# S3 存储配置(本地开发使用 MinIO) -S3_ACCESS_KEY_ID=${MINIO_ROOT_USER} -S3_SECRET_ACCESS_KEY=${MINIO_ROOT_PASSWORD} -S3_ENDPOINT=http://localhost:${MINIO_PORT} -S3_BUCKET=${MINIO_LOBE_BUCKET} -S3_ENABLE_PATH_STYLE=1 # MinIO 必需 -S3_SET_ACL=0 # MinIO 兼容性 -``` - -### 文件存储结构 - -生成的图像和用户上传在 MinIO 存储桶中按以下方式组织: - -``` -lobe/ # S3 存储桶 (MINIO_LOBE_BUCKET) -├── generated/ # 生成的图像 -│ └── {userId}/ -│ └── {sessionId}/ -│ └── {imageId}.png -└── uploads/ # 用户上传的图像处理文件 - └── {userId}/ - └── {fileId}.{ext} -``` - -### 图像开发工作流 - -在开发图像生成功能时,生成的图像将: - -1. 由 AI 模型创建 -2. 通过预签名 URL 上传到 S3/MinIO -3. 元数据存储在 PostgreSQL 中 -4. 通过公共 S3 URL 提供服务 - -测试图像上传的示例代码: - -```typescript -// 示例:上传生成的图像 -const uploadUrl = await trpc.upload.createPresignedUrl.mutate({ - filename: 'generated-image.png', - contentType: 'image/png', -}); - -// 上传到 S3 -await fetch(uploadUrl, { - method: 'PUT', - body: imageBlob, - headers: { 'Content-Type': 'image/png' }, -}); -``` - -### 服务地址 +## 服务地址 运行 Docker Compose 开发环境时: -- **PostgreSQL**:`postgres://postgres@localhost:5432/LobeHub` -- **MinIO API**:`http://localhost:9000` -- **MinIO 控制台**:`http://localhost:9001` (admin/CHANGE\_THIS\_PASSWORD\_IN\_PRODUCTION) +- **PostgreSQL**:`postgres://postgres@localhost:5432/lobechat` +- **Redis**:`redis://localhost:6379` +- **RustFS API**:`http://localhost:9000` +- **RustFS 控制台**:`http://localhost:9001` +- **SearXNG**:`http://localhost:8180` - **应用程序**:`http://localhost:3010` ## 故障排除 @@ -205,15 +139,8 @@ await fetch(uploadUrl, { 如遇到问题,可以重置整个服务堆栈: ```bash -# 停止并删除所有容器 -docker-compose -f docker-compose.development.yml down - -# 删除卷(这将删除所有数据) -docker-compose -f docker-compose.development.yml down -v - -# 重新启动 -docker-compose -f docker-compose.development.yml up -d -pnpm db:migrate +# 完全重置 Docker 环境(删除所有数据并重新启动) +bun run dev:docker:reset ``` ### 端口冲突 @@ -223,20 +150,20 @@ pnpm db:migrate ```bash # 检查端口使用情况 lsof -i :5432 # PostgreSQL -lsof -i :9000 # MinIO API -lsof -i :9001 # MinIO 控制台 +lsof -i :6379 # Redis +lsof -i :9000 # RustFS API +lsof -i :9001 # RustFS 控制台 +lsof -i :8180 # SearXNG ``` ### 数据库迁移 -配置脚本会自动运行迁移。如需手动运行: +如需手动运行迁移: ```bash pnpm db:migrate ``` -注意:在使用 `pnpm dev:desktop` 的开发模式下,迁移也会在启动时自动运行。 - --- 在开发过程中,如果你在环境设置上遇到任何问题,或者有任何关于 LobeHub 开发的问题,欢迎随时向我们提问。我们期待看到你的贡献! diff --git a/package.json b/package.json index b59b48ae2d..ba1b51ddc8 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,9 @@ "dev:bun": "bun --bun next dev -p 3010", "dev:desktop": "cross-env NEXT_PUBLIC_IS_DESKTOP_APP=1 tsx scripts/runNextDesktop.mts dev -p 3015", "dev:desktop:static": "cross-env DESKTOP_RENDERER_STATIC=1 npm run electron:dev --prefix=./apps/desktop", + "dev:docker": "docker compose -f docker-compose/dev/docker-compose.yml up -d --wait postgresql redis rustfs searxng", + "dev:docker:down": "docker compose -f docker-compose/dev/docker-compose.yml down", + "dev:docker:reset": "docker compose -f docker-compose/dev/docker-compose.yml down -v && rm -rf docker-compose/dev/data && npm run dev:docker && pnpm db:migrate", "dev:mobile": "next dev -p 3018", "docs:cdn": "npm run workflow:docs-cdn && npm run lint:mdx", "docs:i18n": "lobe-i18n md && npm run lint:mdx",