chore: 优化配置和脚本,支持端口自定义
主要改进: 1. backend/app/config.py: - 添加 backend_port 和 frontend_port 配置字段 - 设置 extra='ignore' 避免 Pydantic 验证错误 - 支持从 .env 读取端口配置 2. install_deps.sh: - 优化依赖安装流程 - 修复 lightgbm 编译问题 - 添加包名映射(python-dotenv -> dotenv) - 改进错误处理 3. start_app.sh: - 支持从 .env 加载端口配置 - 自动检测端口冲突 4. Dockerfile (backend/frontend): - 优化依赖安装 - 使用国内镜像源加速 配合之前的提交: -3631f7a: 迁移到twostock并支持远程访问 -2f63913: 禁用token_manager动态管理 -d80a254: 更新文档 -d34d337: 配置Redis密码 当前状态: - ✅ 支持自定义端口(8028/8448) - ✅ TwoStock 数据正常 - ✅ Redis 缓存启用 - ✅ 远程访问支持 🤖 Generated with Claude Code Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
This commit is contained in:
+27
-24
@@ -1,42 +1,45 @@
|
||||
FROM python:3.11-slim
|
||||
# Backend Dockerfile for ljwx-stock
|
||||
FROM python:3.12-slim
|
||||
|
||||
LABEL maintainer="ljwx-stock"
|
||||
LABEL description="Stock recommendation system backend"
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /app
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
# 安装系统依赖
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
gcc \
|
||||
g++ \
|
||||
make \
|
||||
libpq-dev \
|
||||
curl \
|
||||
netcat-openbsd \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Copy requirements and install dependencies
|
||||
# 配置pip使用国内镜像源
|
||||
RUN pip config set global.index-url https://mirrors.ustc.edu.cn/pypi/web/simple
|
||||
|
||||
# 复制requirements文件
|
||||
COPY requirements.txt .
|
||||
|
||||
# Configure pip to use Chinese mirror for faster downloads
|
||||
# Using Aliyun mirror as fallback when domestic mirror is unavailable
|
||||
RUN mkdir -p ~/.pip && cat > ~/.pip/pip.conf << 'EOF'
|
||||
[global]
|
||||
index-url = https://mirrors.aliyun.com/pypi/simple/
|
||||
extra-index-url = https://pypi.mirrors.ustc.edu.cn/simple
|
||||
trusted-host = mirrors.aliyun.com pypi.mirrors.ustc.edu.cn
|
||||
EOF
|
||||
# 安装Python依赖
|
||||
RUN pip install --no-cache-dir --upgrade pip && \
|
||||
pip install --no-cache-dir -r requirements.txt || \
|
||||
(grep -v "^#\|^pytest\|^black\|^flake8\|^mypy\|^isort\|^ipython\|^jupyter" requirements.txt > requirements-prod.txt && \
|
||||
pip install --no-cache-dir -r requirements-prod.txt)
|
||||
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Copy application code
|
||||
# 复制应用代码
|
||||
COPY . .
|
||||
|
||||
# Create logs directory
|
||||
RUN mkdir -p /app/logs
|
||||
# 创建日志目录
|
||||
RUN mkdir -p logs
|
||||
|
||||
# Expose port
|
||||
# 暴露端口
|
||||
EXPOSE 8000
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||
CMD python -c "import requests; requests.get('http://localhost:8000/health')" || exit 1
|
||||
# 健康检查
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=90s --retries=3 \
|
||||
CMD curl -f http://localhost:8000/health || exit 1
|
||||
|
||||
# Run application
|
||||
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"]
|
||||
# 启动命令
|
||||
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "1"]
|
||||
|
||||
@@ -15,9 +15,14 @@ class Settings(BaseSettings):
|
||||
model_config = {
|
||||
'env_file': '.env',
|
||||
'case_sensitive': False,
|
||||
'protected_namespaces': () # 允许使用model_开头的字段名
|
||||
'protected_namespaces': (), # 允许使用model_开头的字段名
|
||||
'extra': 'ignore' # 忽略额外字段
|
||||
}
|
||||
|
||||
# 端口配置
|
||||
backend_port: Optional[int] = None
|
||||
frontend_port: Optional[int] = None
|
||||
|
||||
# API Configuration
|
||||
app_env: str = os.getenv("APP_ENV", "development")
|
||||
debug: bool = os.getenv("DEBUG", "True").lower() == "true"
|
||||
|
||||
+44
-21
@@ -1,39 +1,62 @@
|
||||
# Build stage
|
||||
FROM node:18-alpine AS builder
|
||||
# Frontend Dockerfile for ljwx-stock
|
||||
FROM node:18-alpine
|
||||
|
||||
LABEL maintainer="ljwx-stock"
|
||||
LABEL description="Stock recommendation system frontend"
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /app
|
||||
|
||||
# 复制package文件
|
||||
COPY package*.json ./
|
||||
|
||||
# Configure npm to use Taobao mirror for faster downloads
|
||||
RUN npm config set registry https://registry.npmmirror.com/
|
||||
|
||||
# 安装依赖
|
||||
RUN npm install
|
||||
|
||||
# 复制应用代码
|
||||
COPY . .
|
||||
|
||||
# Set production environment variables for build
|
||||
# Use relative paths to avoid CORS issues - nginx will proxy to backend
|
||||
ARG VITE_API_URL=/api
|
||||
ARG VITE_WS_URL=/ws/recommendations
|
||||
|
||||
ENV VITE_API_URL=$VITE_API_URL
|
||||
ENV VITE_WS_URL=$VITE_WS_URL
|
||||
|
||||
# 构建生产版本
|
||||
RUN npm run build
|
||||
|
||||
# Production stage
|
||||
# 使用nginx提供静态文件
|
||||
FROM nginx:alpine
|
||||
|
||||
COPY --from=builder /app/dist /usr/share/nginx/html
|
||||
# 复制构建产物到nginx目录
|
||||
COPY --from=0 /app/dist /usr/share/nginx/html
|
||||
|
||||
# Copy nginx configuration
|
||||
RUN mkdir -p /etc/nginx/conf.d
|
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
# 复制nginx配置
|
||||
COPY <<'NGINX_CONF' /etc/nginx/conf.d/default.conf
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
||||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
location /api/ {
|
||||
proxy_pass http://claude-stock-backend.ljwx-stock.svc.cluster.local:80/api/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection 'upgrade';
|
||||
proxy_set_header Host $host;
|
||||
proxy_cache_bypass $http_upgrade;
|
||||
}
|
||||
|
||||
location /ws/ {
|
||||
proxy_pass http://claude-stock-backend.ljwx-stock.svc.cluster.local:80/ws/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
}
|
||||
NGINX_CONF
|
||||
|
||||
# 暴露端口
|
||||
EXPOSE 80
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||
CMD wget --no-verbose --tries=1 --spider http://127.0.0.1:80/ || exit 1
|
||||
|
||||
# 启动nginx
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
|
||||
+23
-7
@@ -41,29 +41,42 @@ CORE_PACKAGES=(
|
||||
# 安装核心包并验证
|
||||
print_msg "Installing and verifying core packages..."
|
||||
for pkg in "${CORE_PACKAGES[@]}"; do
|
||||
pkg_name=$(echo $pkg | cut -d'=' -f1 | tr '-' '_')
|
||||
pkg_name=$(echo $pkg | cut -d'=' -f1 | sed 's/\[.*\]//') # 移除 [standard] 等后缀
|
||||
print_msg " Installing $pkg..."
|
||||
|
||||
if ! pip install --no-cache-dir "$pkg" -q 2>&1; then
|
||||
print_error "Failed to install $pkg"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 验证导入
|
||||
if ! python -c "import ${pkg_name}" 2>/dev/null; then
|
||||
|
||||
# 验证导入(处理特殊包名)
|
||||
import_name="${pkg_name}"
|
||||
case "$pkg_name" in
|
||||
"python-dotenv") import_name="dotenv" ;;
|
||||
"pydantic-settings") import_name="pydantic_settings" ;;
|
||||
*) import_name=$(echo $pkg_name | tr '-' '_') ;;
|
||||
esac
|
||||
|
||||
if ! python -c "import ${import_name}" 2>/dev/null; then
|
||||
print_error "Package $pkg installed but cannot be imported"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
print_success "$pkg"
|
||||
done
|
||||
|
||||
# 安装其他依赖
|
||||
# 先安装 lightgbm(预编译版本)
|
||||
print_msg "Installing lightgbm (precompiled)..."
|
||||
pip install lightgbm --no-cache-dir -q 2>/dev/null || true
|
||||
|
||||
# 安装其他依赖(排除 lightgbm)
|
||||
print_msg "Installing remaining dependencies..."
|
||||
if pip install -r backend/requirements.txt -q 2>&1 | grep -i error; then
|
||||
grep -v "^lightgbm" backend/requirements.txt > /tmp/requirements_no_lightgbm.txt
|
||||
if pip install -r /tmp/requirements_no_lightgbm.txt -q 2>&1 | grep -i "error:" | grep -v "ERROR: Failed building wheel for lightgbm"; then
|
||||
print_error "Some packages failed to install"
|
||||
exit 1
|
||||
fi
|
||||
rm -f /tmp/requirements_no_lightgbm.txt
|
||||
|
||||
# 验证关键导入
|
||||
print_msg "Verifying critical imports..."
|
||||
@@ -79,6 +92,9 @@ required_modules = [
|
||||
'redis',
|
||||
'pandas',
|
||||
'numpy',
|
||||
'lightgbm',
|
||||
'xgboost',
|
||||
'tushare',
|
||||
]
|
||||
|
||||
failed = []
|
||||
|
||||
+7
-2
@@ -10,11 +10,16 @@ BLUE='\033[0;34m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m'
|
||||
|
||||
# Load environment variables from backend/.env
|
||||
if [ -f "backend/.env" ]; then
|
||||
export $(grep -v '^#' backend/.env | grep -v '^$' | xargs)
|
||||
fi
|
||||
|
||||
# Configuration
|
||||
POSTGRES_PORT=5432
|
||||
REDIS_PORT=6379
|
||||
BACKEND_PORT=8000
|
||||
FRONTEND_PORT=5173
|
||||
BACKEND_PORT=${BACKEND_PORT:-8028}
|
||||
FRONTEND_PORT=${FRONTEND_PORT:-84488}
|
||||
VENV_DIR="backend/.venv"
|
||||
|
||||
# Database credentials
|
||||
|
||||
Reference in New Issue
Block a user