From 4f6654d86480c1e2abfc80ada4cb03a47d0d6b56 Mon Sep 17 00:00:00 2001 From: yuliang_guo Date: Tue, 27 Jan 2026 10:37:55 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E5=B4=94=E6=9B=A6?= =?UTF-8?q?=E6=96=87(cxw)=E7=A7=9F=E6=88=B7=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 Nginx 配置 cxw.conf - 添加 docker-compose 容器配置(frontend/backend/redis) - 添加 .env.cxw 环境配置 - 端口分配: 前端3016, 后端8016, Redis 6396 --- backend/.env.cxw | 52 ++++++++++ deploy/docker/docker-compose.prod-multi.yml | 85 ++++++++++++++++ deploy/nginx/conf.d/cxw.conf | 101 ++++++++++++++++++++ 3 files changed, 238 insertions(+) create mode 100644 backend/.env.cxw create mode 100644 deploy/nginx/conf.d/cxw.conf diff --git a/backend/.env.cxw b/backend/.env.cxw new file mode 100644 index 0000000..4c11538 --- /dev/null +++ b/backend/.env.cxw @@ -0,0 +1,52 @@ +# 崔曦文生产环境配置 +APP_NAME="崔曦文-考培练系统" +APP_VERSION="1.0.0" +DEBUG=false +HOST=0.0.0.0 +PORT=8000 + +# 数据库配置 - 共享MySQL实例 +DATABASE_URL=mysql+aiomysql://root:ProdMySQL2025%21%40%23@prod-mysql:3306/kaopeilian_cxw?charset=utf8mb4 +MYSQL_HOST=prod-mysql +MYSQL_PORT=3306 +MYSQL_USER=root +MYSQL_PASSWORD=ProdMySQL2025!@# +MYSQL_DATABASE=kaopeilian_cxw + +# Redis配置 +REDIS_URL=redis://cxw-redis:6379/0 +REDIS_HOST=cxw-redis +REDIS_PORT=6379 +REDIS_DB=0 + +# 安全配置 +SECRET_KEY=cxw_8f3a2b1c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2 +ALGORITHM=HS256 +ACCESS_TOKEN_EXPIRE_MINUTES=30 +REFRESH_TOKEN_EXPIRE_DAYS=7 + +# CORS配置 +CORS_ORIGINS=["https://cxw.ireborn.com.cn", "http://cxw.ireborn.com.cn"] + +# 公开域名 +PUBLIC_DOMAIN=https://cxw.ireborn.com.cn + +# 租户标识 +TENANT_CODE=cxw + +# 管理库连接配置(用于从管理库加载AI配置) +ADMIN_DB_HOST=prod-mysql +ADMIN_DB_PORT=3306 +ADMIN_DB_USER=root +ADMIN_DB_PASSWORD=ProdMySQL2025!@# +ADMIN_DB_NAME=kaopeilian_admin + +# Coze 平台配置(可在管理后台统一配置) +COZE_API_BASE=https://api.coze.cn +COZE_PRACTICE_BOT_ID=7560643598174683145 +COZE_BROADCAST_WORKFLOW_ID=7577983042284486666 +COZE_BROADCAST_SPACE_ID=7474971491470688296 + +# 日志配置 +LOG_LEVEL=INFO +LOG_FORMAT=json diff --git a/deploy/docker/docker-compose.prod-multi.yml b/deploy/docker/docker-compose.prod-multi.yml index d3c2aea..b427850 100644 --- a/deploy/docker/docker-compose.prod-multi.yml +++ b/deploy/docker/docker-compose.prod-multi.yml @@ -469,6 +469,91 @@ services: timeout: 3s retries: 3 + # ============================================ + # 崔曦文 (cxw.ireborn.com.cn) + # ============================================ + cxw-frontend: + image: kaopeilian-frontend:shared + container_name: cxw-frontend + restart: unless-stopped + environment: + - TZ=Asia/Shanghai + ports: + - "3016:80" + volumes: + - /root/aiedu/kaopeilian-frontend/dist:/usr/share/nginx/html:ro + - /etc/localtime:/etc/localtime:ro + - /etc/timezone:/etc/timezone:ro + networks: + - prod-network + - kaopeilian-network + depends_on: + - cxw-backend + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:80/"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s + + cxw-backend: + build: + context: ./kaopeilian-backend + dockerfile: Dockerfile + image: prod-multi-cxw-backend:latest + container_name: cxw-backend + restart: unless-stopped + env_file: + - ./kaopeilian-backend/.env.cxw + environment: + - TZ=Asia/Shanghai + - PYTHONPATH=/app + ports: + - "8016:8000" + volumes: + - ./kaopeilian-backend/app:/app/app + - /data/prod-envs/uploads-cxw:/app/uploads + - /data/prod-envs/logs-cxw:/app/logs + - /data/prod-envs/secrets:/app/secrets:ro + - /etc/localtime:/etc/localtime:ro + - /etc/timezone:/etc/timezone:ro + command: ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"] + networks: + - prod-network + - kaopeilian-network + depends_on: + prod-mysql: + condition: service_healthy + cxw-redis: + condition: service_healthy + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8000/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + + cxw-redis: + image: redis:7.2-alpine + container_name: cxw-redis + restart: unless-stopped + environment: + - TZ=Asia/Shanghai + ports: + - "6396:6379" + volumes: + - /data/redis-data/cxw:/data + - /etc/localtime:/etc/localtime:ro + - /etc/timezone:/etc/timezone:ro + networks: + - prod-network + command: redis-server --appendonly yes --maxmemory 128mb --maxmemory-policy allkeys-lru + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 10s + timeout: 3s + retries: 3 + # 网络配置 networks: prod-network: diff --git a/deploy/nginx/conf.d/cxw.conf b/deploy/nginx/conf.d/cxw.conf new file mode 100644 index 0000000..8573d15 --- /dev/null +++ b/deploy/nginx/conf.d/cxw.conf @@ -0,0 +1,101 @@ +# 崔曦文 (cxw.ireborn.com.cn) Nginx配置 +# 支持 HTTP 和 HTTPS 访问 + +# HTTP 重定向到 HTTPS +server { + listen 80; + server_name cxw.ireborn.com.cn; + + # Let's Encrypt 验证路径 + location /.well-known/acme-challenge/ { + root /var/www/certbot; + } + + # 其他请求重定向到 HTTPS + location / { + return 301 https://$server_name$request_uri; + } +} + +# HTTPS 配置 +server { + listen 443 ssl http2; + server_name cxw.ireborn.com.cn; + + # SSL 证书配置 + ssl_certificate /etc/letsencrypt/live/cxw.ireborn.com.cn/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/cxw.ireborn.com.cn/privkey.pem; + + # SSL 安全配置 + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384; + ssl_prefer_server_ciphers on; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 10m; + + # 安全头 + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + add_header X-Frame-Options DENY always; + add_header X-Content-Type-Options nosniff always; + add_header X-XSS-Protection "1; mode=block" always; + + # 前端静态资源(带哈希,长期缓存) + location /assets/ { + proxy_pass http://cxw-frontend:80; + 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; + + # 带哈希的文件可以长期缓存 + add_header Cache-Control "public, max-age=31536000, immutable"; + expires 1y; + } + + # 前端服务(HTML 不缓存) + location / { + proxy_pass http://cxw-frontend:80; + 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_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + # HTML 文件不缓存,确保用户获取最新版本 + add_header Cache-Control "no-cache, no-store, must-revalidate"; + add_header Pragma "no-cache"; + expires 0; + } + + # 后端API + location /api/ { + proxy_pass http://cxw-backend:8000; + 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_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_connect_timeout 600s; + proxy_send_timeout 600s; + proxy_read_timeout 600s; + } + + # 健康检查 + location /health { + proxy_pass http://cxw-backend:8000; + proxy_set_header Host $host; + access_log off; + } + + # 静态文件上传 + location /static/uploads/ { + proxy_pass http://cxw-backend:8000; + proxy_set_header Host $host; + expires 1y; + add_header Cache-Control "public"; + } +}