refactor(env): 重构环境变量加载方式,修复前端无法动态获取环境变量的问题

- 移除 Dockerfile 中的额外依赖安装
- 更新环境变量加载路径,使用统一的 get_root_folder() 函数
- 调整数据库连接、MinIO 访问等配置方式
- 移除 pyproject.toml 和 requirements.txt 中的冗余依赖
- 优化前端 MinIO 访问方式,通过后端 API 获取 MinIO URL
This commit is contained in:
zstar 2025-06-10 00:20:44 +08:00
parent 0640f973aa
commit 16f3e227d5
12 changed files with 79 additions and 48 deletions

View File

@ -11,10 +11,6 @@ COPY rag ./rag
COPY graphrag ./graphrag COPY graphrag ./graphrag
COPY agentic_reasoning ./agentic_reasoning COPY agentic_reasoning ./agentic_reasoning
# 安装额外依赖
RUN uv pip install --no-cache-dir mysql-connector-python==9.2.0 -i https://pypi.tuna.tsinghua.edu.cn/simple
RUN uv pip install --no-cache-dir redis==6.2.0 -i https://pypi.tuna.tsinghua.edu.cn/simple
# 复制前端源代码目录 # 复制前端源代码目录
COPY web ./web COPY web ./web

10
api/apps/minio_app.py Normal file
View File

@ -0,0 +1,10 @@
import os
@manager.route("/endpoint", methods=["GET"]) # noqa: F821
# @login_required
def minio():
"""
Constructs the MinIO endpoint URL based on environment variables.
"""
return os.getenv("MINIO_VISIT_HOST", "localhost") + ":" + os.getenv("MINIO_PORT", "9000") + "/"

View File

@ -1,10 +1,13 @@
import os import os
from minio import Minio
from dotenv import load_dotenv
from pathlib import Path from pathlib import Path
from dotenv import load_dotenv
from minio import Minio
from api.root_path import get_root_folder
# 加载环境变量 # 加载环境变量
env_path = Path(__file__).parent.parent.parent / "docker" / ".env" env_path = Path(get_root_folder()) / "docker" / ".env"
load_dotenv(env_path) load_dotenv(env_path)

View File

@ -2,24 +2,30 @@ import logging
import os import os
import signal import signal
import sys import sys
import threading
import time import time
import traceback import traceback
from concurrent.futures import ThreadPoolExecutor from concurrent.futures import ThreadPoolExecutor
import threading from pathlib import Path
from dotenv import load_dotenv
from werkzeug.serving import run_simple from werkzeug.serving import run_simple
from api import settings
from api import settings, utils
from api.apps import app from api.apps import app
from api.db.db_models import init_database_tables as init_web_db
from api.db.runtime_config import RuntimeConfig from api.db.runtime_config import RuntimeConfig
from api.db.services.document_service import DocumentService from api.db.services.document_service import DocumentService
from api import utils from api.root_path import get_root_folder
from api.db.db_models import init_database_tables as init_web_db
from api.db.init_data import init_web_data
from api.versions import get_ragflow_version
from api.utils import show_configs from api.utils import show_configs
from api.utils.log_utils import initRootLogger
from api.versions import get_ragflow_version
from rag.settings import print_rag_settings from rag.settings import print_rag_settings
from rag.utils.redis_conn import RedisDistributedLock from rag.utils.redis_conn import RedisDistributedLock
from api.utils.log_utils import initRootLogger # 加载环境变量
env_path = Path(get_root_folder()) / "docker" / ".env"
load_dotenv(env_path)
initRootLogger("ragflow_server") initRootLogger("ragflow_server")

5
api/root_path.py Normal file
View File

@ -0,0 +1,5 @@
import os
def get_root_folder():
return os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

View File

@ -25,7 +25,7 @@ from graphrag import search as kg_search
from api.utils import get_base_config, decrypt_database_config from api.utils import get_base_config, decrypt_database_config
from api.constants import RAG_FLOW_SERVICE_NAME from api.constants import RAG_FLOW_SERVICE_NAME
LIGHTEN = int(os.environ.get('LIGHTEN', "0")) LIGHTEN = int(os.environ.get("LIGHTEN", "0"))
LLM = None LLM = None
LLM_FACTORY = None LLM_FACTORY = None
@ -41,7 +41,7 @@ HOST_IP = None
HOST_PORT = None HOST_PORT = None
SECRET_KEY = None SECRET_KEY = None
DATABASE_TYPE = os.getenv("DB_TYPE", 'mysql') DATABASE_TYPE = os.getenv("DB_TYPE", "mysql")
DATABASE = decrypt_database_config(name=DATABASE_TYPE) DATABASE = decrypt_database_config(name=DATABASE_TYPE)
# authentication # authentication
@ -62,8 +62,8 @@ kg_retrievaler = None
def init_settings(): def init_settings():
global LLM, LLM_FACTORY, LLM_BASE_URL, LIGHTEN, DATABASE_TYPE, DATABASE global LLM, LLM_FACTORY, LLM_BASE_URL, LIGHTEN, DATABASE_TYPE, DATABASE
LIGHTEN = int(os.environ.get('LIGHTEN', "0")) LIGHTEN = int(os.environ.get("LIGHTEN", "0"))
DATABASE_TYPE = os.getenv("DB_TYPE", 'mysql') DATABASE_TYPE = os.getenv("DB_TYPE", "mysql")
DATABASE = decrypt_database_config(name=DATABASE_TYPE) DATABASE = decrypt_database_config(name=DATABASE_TYPE)
LLM = get_base_config("user_default_llm", {}) LLM = get_base_config("user_default_llm", {})
LLM_DEFAULT_MODELS = LLM.get("default_models", {}) LLM_DEFAULT_MODELS = LLM.get("default_models", {})
@ -86,36 +86,32 @@ def init_settings():
EMBEDDING_MDL = EMBEDDING_MDL + (f"@{LLM_FACTORY}" if "@" not in EMBEDDING_MDL and EMBEDDING_MDL != "" else "") EMBEDDING_MDL = EMBEDDING_MDL + (f"@{LLM_FACTORY}" if "@" not in EMBEDDING_MDL and EMBEDDING_MDL != "" else "")
RERANK_MDL = RERANK_MDL + (f"@{LLM_FACTORY}" if "@" not in RERANK_MDL and RERANK_MDL != "" else "") RERANK_MDL = RERANK_MDL + (f"@{LLM_FACTORY}" if "@" not in RERANK_MDL and RERANK_MDL != "" else "")
ASR_MDL = ASR_MDL + (f"@{LLM_FACTORY}" if "@" not in ASR_MDL and ASR_MDL != "" else "") ASR_MDL = ASR_MDL + (f"@{LLM_FACTORY}" if "@" not in ASR_MDL and ASR_MDL != "" else "")
IMAGE2TEXT_MDL = IMAGE2TEXT_MDL + ( IMAGE2TEXT_MDL = IMAGE2TEXT_MDL + (f"@{LLM_FACTORY}" if "@" not in IMAGE2TEXT_MDL and IMAGE2TEXT_MDL != "" else "")
f"@{LLM_FACTORY}" if "@" not in IMAGE2TEXT_MDL and IMAGE2TEXT_MDL != "" else "")
global API_KEY, PARSERS, HOST_IP, HOST_PORT, SECRET_KEY global API_KEY, PARSERS, HOST_IP, HOST_PORT, SECRET_KEY
API_KEY = LLM.get("api_key", "") API_KEY = LLM.get("api_key", "")
PARSERS = LLM.get( PARSERS = LLM.get(
"parsers", "parsers",
"naive:General,qa:Q&A,resume:Resume,manual:Manual,table:Table,paper:Paper,book:Book,laws:Laws,presentation:Presentation,picture:Picture,one:One,audio:Audio,knowledge_graph:Knowledge Graph,email:Email,tag:Tag") "naive:General,qa:Q&A,resume:Resume,manual:Manual,table:Table,paper:Paper,book:Book,laws:Laws,presentation:Presentation,picture:Picture,one:One,audio:Audio,knowledge_graph:Knowledge Graph,email:Email,tag:Tag",
)
HOST_IP = get_base_config(RAG_FLOW_SERVICE_NAME, {}).get("host", "127.0.0.1") HOST_IP = get_base_config(RAG_FLOW_SERVICE_NAME, {}).get("host", "127.0.0.1")
HOST_PORT = get_base_config(RAG_FLOW_SERVICE_NAME, {}).get("http_port") HOST_PORT = get_base_config(RAG_FLOW_SERVICE_NAME, {}).get("http_port")
SECRET_KEY = get_base_config( SECRET_KEY = get_base_config(RAG_FLOW_SERVICE_NAME, {}).get("secret_key", str(date.today()))
RAG_FLOW_SERVICE_NAME,
{}).get("secret_key", str(date.today()))
global AUTHENTICATION_CONF, CLIENT_AUTHENTICATION, HTTP_APP_KEY, GITHUB_OAUTH, FEISHU_OAUTH global AUTHENTICATION_CONF, CLIENT_AUTHENTICATION, HTTP_APP_KEY, GITHUB_OAUTH, FEISHU_OAUTH
# authentication # authentication
AUTHENTICATION_CONF = get_base_config("authentication", {}) AUTHENTICATION_CONF = get_base_config("authentication", {})
# client # client
CLIENT_AUTHENTICATION = AUTHENTICATION_CONF.get( CLIENT_AUTHENTICATION = AUTHENTICATION_CONF.get("client", {}).get("switch", False)
"client", {}).get(
"switch", False)
HTTP_APP_KEY = AUTHENTICATION_CONF.get("client", {}).get("http_app_key") HTTP_APP_KEY = AUTHENTICATION_CONF.get("client", {}).get("http_app_key")
GITHUB_OAUTH = get_base_config("oauth", {}).get("github") GITHUB_OAUTH = get_base_config("oauth", {}).get("github")
FEISHU_OAUTH = get_base_config("oauth", {}).get("feishu") FEISHU_OAUTH = get_base_config("oauth", {}).get("feishu")
global DOC_ENGINE, docStoreConn, retrievaler, kg_retrievaler global DOC_ENGINE, docStoreConn, retrievaler, kg_retrievaler
DOC_ENGINE = os.environ.get('DOC_ENGINE', "elasticsearch") DOC_ENGINE = os.environ.get("DOC_ENGINE", "elasticsearch")
lower_case_doc_engine = DOC_ENGINE.lower() lower_case_doc_engine = DOC_ENGINE.lower()
if lower_case_doc_engine == "elasticsearch": if lower_case_doc_engine == "elasticsearch":
docStoreConn = rag.utils.es_conn.ESConnection() docStoreConn = rag.utils.es_conn.ESConnection()

View File

@ -1,13 +1,16 @@
import mysql.connector
import os import os
import redis
from minio import Minio
from dotenv import load_dotenv
from elasticsearch import Elasticsearch
from pathlib import Path from pathlib import Path
import mysql.connector
import redis
from dotenv import load_dotenv
from elasticsearch import Elasticsearch
from minio import Minio
from .root_path import get_root_folder
# 加载环境变量 # 加载环境变量
env_path = Path(__file__).parent.parent.parent / "docker" / ".env" env_path = Path(get_root_folder()) / "docker" / ".env"
load_dotenv(env_path) load_dotenv(env_path)

View File

@ -0,0 +1,5 @@
import os
def get_root_folder():
return os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

View File

@ -126,9 +126,7 @@ dependencies = [
"trio>=0.29.0", "trio>=0.29.0",
"langfuse>=2.60.0", "langfuse>=2.60.0",
"debugpy>=1.8.13", "debugpy>=1.8.13",
"mcp>=1.6.0", "mcp>=1.6.0"
"mysql-connector-python==9.2.0",
"redis==6.2.0"
] ]
[project.optional-dependencies] [project.optional-dependencies]

View File

@ -111,6 +111,4 @@ mini-racer>=0.12.4,<0.13.0
pyodbc>=5.2.0,<6.0.0 pyodbc>=5.2.0,<6.0.0
flasgger>=0.9.7.1,<0.10.0 flasgger>=0.9.7.1,<0.10.0
xxhash>=3.5.0,<4.0.0 xxhash>=3.5.0,<4.0.0
trio>=0.29.0 trio>=0.29.0
mysql-connector-python==9.2.0
redis==6.2.0

View File

@ -1,6 +1,8 @@
import { Popover } from 'antd'; import { Popover } from 'antd';
import classNames from 'classnames'; import classNames from 'classnames';
import api from '@/utils/api';
import { useEffect, useState } from 'react';
import styles from './index.less'; import styles from './index.less';
interface IImage { interface IImage {
@ -9,14 +11,20 @@ interface IImage {
} }
const ChunkImage = ({ id, className, ...props }: IImage) => { const ChunkImage = ({ id, className, ...props }: IImage) => {
const host = process.env.MINIO_VISIT_HOST || 'localhost'; // const host = process.env.MINIO_VISIT_HOST || 'localhost';
const port = process.env.MINIO_PORT || '9000'; // const port = process.env.MINIO_PORT || '9000';
const imgSrc = `http://${host}:${port}/${id}`; // const imgSrc = `http://${host}:${port}/${id}`;
// 检查环境变量是否被正确读取 const [imgSrc, setImgSrc] = useState<string>('');
console.log('MinIO Config:', {
host: process.env.MINIO_VISIT_HOST, useEffect(() => {
port: process.env.MINIO_PORT, fetch(api.minio_endpoint)
}); .then((res) => res.text())
.catch(() => 'http://localhost:9000')
.then((minioUrl) => {
console.log('Minio URL:', minioUrl);
setImgSrc(`${minioUrl}/${id}`);
});
}, [setImgSrc, id]);
return ( return (
<img <img

View File

@ -3,6 +3,9 @@ let api_host = `/v1`;
export { api_host }; export { api_host };
export default { export default {
// Minio
minio_endpoint: `${api_host}/minio/endpoint`,
// user // user
login: `${api_host}/user/login`, login: `${api_host}/user/login`,
logout: `${api_host}/user/logout`, logout: `${api_host}/user/logout`,