fix:修复docker镜像构建问题

This commit is contained in:
xiamuceer
2025-11-04 17:27:39 +08:00
parent ad95105417
commit 29d8d5fb94
7 changed files with 40 additions and 10 deletions
+6
View File
@@ -40,6 +40,12 @@ Thumbs.db
data/*.db data/*.db
backend/data/*.db backend/data/*.db
# ChromaDB数据库(不包含在镜像中,会在运行时生成)
backend/data/chroma_db/
# 注意:backend/data/models/ 目录需要打包(包含预下载的Embedding模型)
# 所以不要添加到 .dockerignore 中
# 日志文件 # 日志文件
logs/ logs/
*.log *.log
+14 -1
View File
@@ -40,7 +40,10 @@ RUN apt-get update && apt-get install -y \
# 复制后端依赖文件 # 复制后端依赖文件
COPY backend/requirements.txt ./ COPY backend/requirements.txt ./
# 安装Python依赖 # 先从PyTorch官方源安装CPU版本的torch(避免GPU依赖
RUN pip install --no-cache-dir torch==2.7.0 --index-url https://download.pytorch.org/whl/cpu
# 再安装其他Python依赖(使用阿里云镜像加速)
RUN pip install --no-cache-dir -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/ RUN pip install --no-cache-dir -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
# 复制后端代码 # 复制后端代码
@@ -52,6 +55,10 @@ COPY --from=frontend-builder /frontend/dist ./static
# 创建必要的目录 # 创建必要的目录
RUN mkdir -p /app/data /app/logs RUN mkdir -p /app/data /app/logs
# 复制预下载的Embedding模型(如果存在)
# 这样可以避免首次运行时联网下载约420MB的模型文件
COPY backend/data/models /app/data/models
# 复制环境变量示例文件 # 复制环境变量示例文件
COPY backend/.env.example ./.env.example COPY backend/.env.example ./.env.example
@@ -63,6 +70,12 @@ ENV PYTHONUNBUFFERED=1
ENV APP_HOST=0.0.0.0 ENV APP_HOST=0.0.0.0
ENV APP_PORT=8000 ENV APP_PORT=8000
# 设置Transformers和Sentence-Transformers离线模式
ENV TRANSFORMERS_OFFLINE=1
ENV HF_DATASETS_OFFLINE=1
ENV HF_HUB_OFFLINE=1
ENV SENTENCE_TRANSFORMERS_HOME=/app/data/models
# 健康检查 # 健康检查
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')" || exit 1 CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')" || exit 1
+2
View File
@@ -13,6 +13,8 @@ logger = get_logger(__name__)
# 配置离线模式,避免联网检查 # 配置离线模式,避免联网检查
os.environ['TRANSFORMERS_OFFLINE'] = '1' os.environ['TRANSFORMERS_OFFLINE'] = '1'
os.environ['HF_DATASETS_OFFLINE'] = '1' os.environ['HF_DATASETS_OFFLINE'] = '1'
os.environ['HF_HUB_OFFLINE'] = '1' # 禁用HuggingFace Hub联网
os.environ['SENTENCE_TRANSFORMERS_HOME'] = 'data/models' # 设置模型缓存目录
class MemoryService: class MemoryService:
+10 -1
View File
@@ -19,6 +19,15 @@ anthropic==0.72.0
httpx==0.28.1 httpx==0.28.1
python-dotenv==1.0.0 python-dotenv==1.0.0
# NumPy版本锁定(兼容性要求)
numpy==1.26.4
# 向量数据库和Embedding (长期记忆系统) # 向量数据库和Embedding (长期记忆系统)
chromadb==1.3.2 chromadb==1.3.2
sentence-transformers>=2.3.1
# Transformers(锁定兼容版本)
transformers==4.35.2
# Sentence Transformers(基于PyTorch的文本embedding库)
sentence-transformers==2.3.1
+5 -5
View File
@@ -59,7 +59,7 @@ export default function SettingsPage() {
form.setFieldsValue({ form.setFieldsValue({
api_provider: 'openai', api_provider: 'openai',
api_base_url: 'https://api.openai.com/v1', api_base_url: 'https://api.openai.com/v1',
model_name: 'gpt-4', llm_model: 'gpt-4',
temperature: 0.7, temperature: 0.7,
max_tokens: 2000, max_tokens: 2000,
}); });
@@ -96,7 +96,7 @@ export default function SettingsPage() {
api_provider: 'openai', api_provider: 'openai',
api_key: '', api_key: '',
api_base_url: 'https://api.openai.com/v1', api_base_url: 'https://api.openai.com/v1',
model_name: 'gpt-4', llm_model: 'gpt-4',
temperature: 0.7, temperature: 0.7,
max_tokens: 2000, max_tokens: 2000,
}); });
@@ -193,7 +193,7 @@ export default function SettingsPage() {
const apiKey = form.getFieldValue('api_key'); const apiKey = form.getFieldValue('api_key');
const apiBaseUrl = form.getFieldValue('api_base_url'); const apiBaseUrl = form.getFieldValue('api_base_url');
const provider = form.getFieldValue('api_provider'); const provider = form.getFieldValue('api_provider');
const modelName = form.getFieldValue('model_name'); const modelName = form.getFieldValue('llm_model');
if (!apiKey || !apiBaseUrl || !provider || !modelName) { if (!apiKey || !apiBaseUrl || !provider || !modelName) {
message.warning('请先填写完整的配置信息'); message.warning('请先填写完整的配置信息');
@@ -208,7 +208,7 @@ export default function SettingsPage() {
api_key: apiKey, api_key: apiKey,
api_base_url: apiBaseUrl, api_base_url: apiBaseUrl,
provider: provider, provider: provider,
model_name: modelName llm_model: modelName
}); });
setTestResult(result); setTestResult(result);
@@ -406,7 +406,7 @@ export default function SettingsPage() {
</Tooltip> </Tooltip>
</Space> </Space>
} }
name="model_name" name="llm_model"
rules={[{ required: true, message: '请输入或选择模型名称' }]} rules={[{ required: true, message: '请输入或选择模型名称' }]}
> >
<Select <Select
+1 -1
View File
@@ -147,7 +147,7 @@ export const settingsApi = {
getAvailableModels: (params: { api_key: string; api_base_url: string; provider: string }) => getAvailableModels: (params: { api_key: string; api_base_url: string; provider: string }) =>
api.get<unknown, { provider: string; models: Array<{ value: string; label: string; description: string }>; count?: number }>('/settings/models', { params }), api.get<unknown, { provider: string; models: Array<{ value: string; label: string; description: string }>; count?: number }>('/settings/models', { params }),
testApiConnection: (params: { api_key: string; api_base_url: string; provider: string; model_name: string }) => testApiConnection: (params: { api_key: string; api_base_url: string; provider: string; llm_model: string }) =>
api.post<unknown, { api.post<unknown, {
success: boolean; success: boolean;
message: string; message: string;
+2 -2
View File
@@ -18,7 +18,7 @@ export interface Settings {
api_provider: string; api_provider: string;
api_key: string; api_key: string;
api_base_url: string; api_base_url: string;
model_name: string; llm_model: string;
temperature: number; temperature: number;
max_tokens: number; max_tokens: number;
preferences?: string; preferences?: string;
@@ -30,7 +30,7 @@ export interface SettingsUpdate {
api_provider?: string; api_provider?: string;
api_key?: string; api_key?: string;
api_base_url?: string; api_base_url?: string;
model_name?: string; llm_model?: string;
temperature?: number; temperature?: number;
max_tokens?: number; max_tokens?: number;
preferences?: string; preferences?: string;