悟空 AI CRM 部署指南,与宝塔共存解决端口占用,重置管理密码
本文档介绍如何在服务器上快速部署悟空 AI CRM,支持 Docker 一键启动,也可与宝塔面板共存。
一、环境要求
- Docker ≥ 20.10
- Docker Compose ≥ 2.0
- 最少 2C4G 内存,10G 磁盘空间
- 国内服务器推荐搭配华为云 SWR 镜像源(已内置)
二、克隆仓库并启动
git clone https://github.com/WuKongOpenSource/Wukong-AICRM.git
cd Wukong-AICRM/docker
docker-compose up -d启动完成后访问 http://localhost 即可。
三、初始密码重置
首次登录后请立即修改默认密码。
方式一:动态生成 BCrypt Hash(推荐)
HASH=$(docker run --rm httpd:2.4 htpasswd -bnBC 10 "" admin123 | tr -d ':\n' | sed 's/\$2y/\$2a/')
echo "Generated hash: $HASH"
docker exec -it WeKnora-postgres psql -U postgres -d WeKnora \
-c "UPDATE manager_user SET password='$HASH' WHERE username='admin';"方式二:硬编码固定 Hash
如果上面的命令因 $ 转义问题执行失败,可直接使用以下命令:
docker exec -it WeKnora-postgres psql -U postgres -d WeKnora \
-c "UPDATE manager_user SET password='\$2a\$10\$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy' WHERE username='admin';"验证密码是否更新成功
docker exec -it WeKnora-postgres psql -U postgres -d WeKnora \
-c "SELECT username, password FROM manager_user WHERE username='admin';"看到新的 $2a$10$... 格式的 hash 即表示成功。无需重启容器。
| 用户名 | 密码 |
|---|---|
| admin | admin123 |
四、Docker Compose 配置
以下为与宝塔面板共存的完整 docker-compose.yaml。
services:
frontend:
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/wechatopenai/weknora-ui:v0.3.6
container_name: WeKnora-frontend
volumes:
- ./nginx/default.conf.template:/etc/nginx/templates/default.conf.template
- ./nginx/cert:/etc/nginx/cert
ports:
- "${FRONTEND_PORT:-80}:80"
environment:
- MAX_FILE_SIZE_MB=${MAX_FILE_SIZE_MB:-50}
- BASE_PATH=${CRM_BASE_PATH:-/}
depends_on:
app:
condition: service_healthy
crm:
condition: service_healthy
networks:
- crm-network
restart: unless-stopped
app:
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/wechatopenai/weknora-app:v0.3.6
container_name: WeKnora-app
ports:
- "${APP_PORT:-8080}:8080"
volumes:
- data-files:/data/files
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
environment:
- COS_SECRET_ID=${COS_SECRET_ID:-}
- COS_SECRET_KEY=${COS_SECRET_KEY:-}
- COS_REGION=${COS_REGION:-}
- COS_BUCKET_NAME=${COS_BUCKET_NAME:-}
- COS_APP_ID=${COS_APP_ID:-}
- COS_PATH_PREFIX=${COS_PATH_PREFIX:-}
- COS_ENABLE_OLD_DOMAIN=${COS_ENABLE_OLD_DOMAIN:-}
- GIN_MODE=${GIN_MODE:-release}
- DISABLE_REGISTRATION=${DISABLE_REGISTRATION:-false}
- DB_DRIVER=postgres
- DB_HOST=postgres
- DB_PORT=5432
- DB_USER=${DB_USER:-}
- DB_PASSWORD=${DB_PASSWORD:-}
- DB_NAME=${DB_NAME:-}
- TZ=Asia/Shanghai
- OTEL_EXPORTER_OTLP_ENDPOINT=jaeger:4317
- OTEL_SERVICE_NAME=WeKnora
- OTEL_TRACES_EXPORTER=otlp
- OTEL_METRICS_EXPORTER=none
- OTEL_LOGS_EXPORTER=none
- OTEL_PROPAGATORS=tracecontext,baggage
- RETRIEVE_DRIVER=${RETRIEVE_DRIVER:-}
- DOCREADER_ADDR=docreader:50051
- STORAGE_TYPE=${STORAGE_TYPE:-}
- LOCAL_STORAGE_BASE_DIR=${LOCAL_STORAGE_BASE_DIR:-}
- AUTO_RECOVER_DIRTY=${AUTO_RECOVER_DIRTY:-true}
- MINIO_ENDPOINT=minio:9000
- MINIO_ACCESS_KEY_ID=${MINIO_ACCESS_KEY_ID:-minioadmin}
- MINIO_SECRET_ACCESS_KEY=${MINIO_SECRET_ACCESS_KEY:-minioadmin}
- MINIO_BUCKET_NAME=${MINIO_BUCKET_NAME:-}
- OLLAMA_BASE_URL=${OLLAMA_BASE_URL:-http://host.docker.internal:11434}
- STREAM_MANAGER_TYPE=${STREAM_MANAGER_TYPE:-}
- REDIS_ADDR=redis:6379
- REDIS_PASSWORD=${REDIS_PASSWORD:-}
- REDIS_DB=${REDIS_DB:-}
- REDIS_PREFIX=${REDIS_PREFIX:-}
- ENABLE_GRAPH_RAG=${ENABLE_GRAPH_RAG:-}
- CONCURRENCY_POOL_SIZE=${CONCURRENCY_POOL_SIZE:-5}
- JWT_SECRET=${JWT_SECRET:-}
- INIT_LLM_MODEL_NAME=${INIT_LLM_MODEL_NAME:-}
- INIT_LLM_MODEL_BASE_URL=${INIT_LLM_MODEL_BASE_URL:-}
- INIT_LLM_MODEL_API_KEY=${INIT_LLM_MODEL_API_KEY:-}
- INIT_EMBEDDING_MODEL_NAME=${INIT_EMBEDDING_MODEL_NAME:-}
- INIT_EMBEDDING_MODEL_BASE_URL=${INIT_EMBEDDING_MODEL_BASE_URL:-}
- INIT_EMBEDDING_MODEL_API_KEY=${INIT_EMBEDDING_MODEL_API_KEY:-}
- INIT_EMBEDDING_MODEL_DIMENSION=${INIT_EMBEDDING_MODEL_DIMENSION:-}
- INIT_EMBEDDING_MODEL_ID=${INIT_EMBEDDING_MODEL_ID:-}
- INIT_RERANK_MODEL_NAME=${INIT_RERANK_MODEL_NAME:-}
- INIT_RERANK_MODEL_BASE_URL=${INIT_RERANK_MODEL_BASE_URL:-}
- INIT_RERANK_MODEL_API_KEY=${INIT_RERANK_MODEL_API_KEY:-}
- MAX_FILE_SIZE_MB=${MAX_FILE_SIZE_MB:-50}
depends_on:
redis:
condition: service_started
postgres:
condition: service_healthy
docreader:
condition: service_healthy
networks:
- crm-network
restart: unless-stopped
extra_hosts:
- "host.docker.internal:host-gateway"
docreader:
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/wechatopenai/weknora-docreader:v0.3.6
build:
context: .
dockerfile: docker/Dockerfile.docreader
container_name: WeKnora-docreader
ports:
- "${DOCREADER_PORT:-50051}:50051"
environment:
- MINIO_ENDPOINT=minio:9000
- MINIO_PUBLIC_ENDPOINT=http://${HOST_IP}:${MINIO_PORT:-9000}
- MINERU_ENDPOINT=${MINERU_ENDPOINT:-}
- MAX_FILE_SIZE_MB=${MAX_FILE_SIZE_MB:-}
healthcheck:
test: ["CMD", "grpc_health_probe", "-addr=:50051"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
networks:
- crm-network
restart: unless-stopped
extra_hosts:
- "host.docker.internal:host-gateway"
postgres:
image: paradedb/paradedb:v0.21.4-pg17
container_name: WeKnora-postgres
environment:
- POSTGRES_USER=${DB_USER}
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_DB=${DB_NAME}
ports:
- "15432:5432"
volumes:
- postgres-data:/var/lib/postgresql/data
- ./db/init.sql:/docker-entrypoint-initdb.d/init.sql
networks:
- crm-network
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USER}"]
interval: 10s
timeout: 10s
retries: 3
start_period: 30s
restart: unless-stopped
stop_grace_period: 1m
redis:
image: redis:7.0-alpine
container_name: WeKnora-redis
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
restart: always
healthcheck:
test:
[
"CMD-SHELL",
"redis-cli -a ${REDIS_PASSWORD} ping | grep -q PONG",
]
interval: 10s
timeout: 30s
retries: 5
start_period: 10s
networks:
- crm-network
minio:
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/minio/minio:RELEASE.2024-10-02T17-50-41Z
container_name: WeKnora-minio
ports:
- "${MINIO_PORT:-9000}:9000"
- "${MINIO_CONSOLE_PORT:-9001}:9001"
environment:
- MINIO_ROOT_USER=${MINIO_ACCESS_KEY_ID:-minioadmin}
- MINIO_ROOT_PASSWORD=${MINIO_SECRET_ACCESS_KEY:-minioadmin}
- MINIO_IDENTITY_OPENID_CONFIG_URL=http://${HOST_IP}/.well-known/openid-configuration
- MINIO_IDENTITY_OPENID_CLIENT_ID=minio-console
- MINIO_IDENTITY_OPENID_CLIENT_SECRET=minio-console-secret-key-2024
- MINIO_IDENTITY_OPENID_CLAIM_NAME=policy
- MINIO_IDENTITY_OPENID_SCOPES=openid,profile,email
- MINIO_IDENTITY_OPENID_REDIRECT_URI=http://${HOST_IP}:9001/oauth_callback
- MINIO_IDENTITY_OPENID_DISPLAY_NAME=AI CRM Login
command: server --console-address ":9001" /data
volumes:
- minio_data:/data
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
depends_on:
crm:
condition: service_healthy
frontend:
condition: service_started
networks:
- crm-network
crm:
build:
context: ..
dockerfile: Dockerfile.crm
image: wk_ai_crm:local
container_name: crm
platform: linux/amd64
ports:
- "8088:8088"
restart: always
volumes:
- ./aicrm/logs:/opt/wk_ai_crm/logs
- ./aicrm/config:/opt/wk_ai_crm/config
depends_on:
redis:
condition: service_healthy
postgres:
condition: service_healthy
environment:
- LANG=zh_CN.UTF-8
- LANGUAGE=zh_CN:zh
- LC_ALL=zh_CN.UTF-8
- HOST_IP=${HOST_IP}
- BASE_PATH=${CRM_BASE_PATH:-/}
- MAIL_CREDENTIAL_ENCRYPTION_KEY=${MAIL_CREDENTIAL_ENCRYPTION_KEY:-aicrm-single-mail-key-change-me}
- MAIL_PROXY_ENABLED=${MAIL_PROXY_ENABLED:-false}
- MAIL_PROXY_URL=${MAIL_PROXY_URL:-}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8088/"]
interval: 30s
timeout: 60s
retries: 3
networks:
- crm-network
networks:
crm-network:
driver: bridge
volumes:
postgres-data:
data-files:
minio_data:五、环境变量配置 (.env)
在 docker/ 目录下创建 .env 文件:
# ========== 基础配置 ==========
GIN_MODE=debug # debug(开发) / release(生产)
DISABLE_REGISTRATION=false # 生产环境建议设为 true
# Ollama(可选,本地大模型)
OLLAMA_BASE_URL=http://host.docker.internal:11434
# ========== 存储配置 ==========
DB_DRIVER=postgres
RETRIEVE_DRIVER=postgres # 向量存储:postgres / elasticsearch_v7 / qdrant
STORAGE_TYPE=local # 文件存储:local / minio / cos
STREAM_MANAGER_TYPE=redis
# ========== 端口配置 ==========
APP_PORT=8080
FRONTEND_PORT=8082
DOCREADER_PORT=50051
# ========== 数据库 ==========
DB_USER=postgres
DB_PASSWORD=postgres123!@#
DB_NAME=WeKnora
# ========== Redis ==========
REDIS_PASSWORD=redis123!@#
REDIS_DB=0
REDIS_PREFIX=stream:
# ========== 存储路径 ==========
LOCAL_STORAGE_BASE_DIR=/data/files
AUTO_RECOVER_DIRTY=true
TENANT_AES_KEY=weknorarag-api-key-secret-secret
# ========== 功能开关 ==========
ENABLE_GRAPH_RAG=false # 知识图谱(构建耗时较长,需调用大模型)
# ========== 安全配置 ==========
JWT_SECRET=weknora-jwt-secret
CONCURRENCY_POOL_SIZE=5 # Embedding 并发(429 错误时调小)
HOST_IP=127.0.0.1
CRM_BASE_PATH=/六、与宝塔面板共存(Nginx 反向代理配置)
若服务器已部署宝塔,将以下配置加入站点 Nginx 配置即可。
server
{
listen 80;
server_name abc.dxw123.top abc.dacaishen.eu.cc;
index index.html index.htm;
root /www/wwwroot/abc.dxw123.top;
#CERT-APPLY-CHECK--START
include /www/server/panel/vhost/nginx/well-known/abc.dxw123.top.conf;
#CERT-APPLY-CHECK--END
include /www/server/panel/vhost/nginx/extension/abc.dxw123.top/*.conf;
error_page 404 /404.html;
#REWRITE-START
include /www/server/panel/vhost/rewrite/abc.dxw123.top.conf;
#REWRITE-END
# ========== 悟空 AI CRM 反向代理 START ==========
# AI CRM 后端 API
location ^~ /api/ {
proxy_pass http://127.0.0.1:8088;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
client_max_body_size 100m;
}
# WeKnora App API
location ^~ /weknora/ {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 300s;
client_max_body_size 100m;
}
# 全局上传限制(配合 MAX_FILE_SIZE_MB=50)
client_max_body_size 60m;
# AI CRM 前端
location / {
proxy_pass http://127.0.0.1:8082;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# ========== 悟空 AI CRM 反向代理 END ==========
# 禁止访问敏感文件
location ~* (\.user.ini|\.htaccess|\.htpasswd|\.env.*|\.gitignore|\.DS_Store|\.bashrc|README\.md|Dockerfile|docker-compose\.yml|\.sql(\.gz)?)$
{
return 404;
}
# 禁止访问敏感目录
location ~* /(\.git|\.svn|\.vscode|\.idea|\.ssh|\.github|node_modules|runtime)/ {
return 404;
}
# SSL 证书验证
location ~ \.well-known {
allow all;
}
if ( $uri ~ "^/\.well-known/.*\.(php|jsp|py|js|css|lua|ts|go|zip|tar\.gz|rar|7z|sql|bak)$" ) {
return 403;
}
access_log /www/wwwlogs/abc.dxw123.top.log;
error_log /www/wwwlogs/abc.dxw123.top.error.log;
}代理路径说明
| 路径 | 代理目标 | 说明 |
|---|---|---|
/api/ | 127.0.0.1:8088 | AI CRM 后端 API |
/weknora/ | 127.0.0.1:8080 | WeKnora App API |
/ | 127.0.0.1:8082 | AI CRM 前端 |
七、登录
| 用户名 | 密码 |
|---|---|
| admin | admin123 |
直接访问绑定的域名或 IP 即可登录管理系统。
评论 (0)