chore: 重组项目文件结构,文档和部署文件归档
文件结构优化: - docs/ 归档所有项目文档(PROJECT.md, PROJECT_ISSUES.md 等) - deploy/ 归档所有部署相关文件(docker-compose.prod.yml, nginx 配置等) - scripts/ 归档脚本文件(deploy.sh, rollback.sh) - tests/ 归档测试文件(test_data.php) 更新引用路径: - CLAUDE.md 更新文档路径引用 - 部署文档更新配置文件路径引用 清理文件: - 移除非必要的测试文件(TestController, 测试脚本等) - 移除重复/错误的目录 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
# X-Server Mobile 生产环境变量模板
|
||||
# 使用方法: cp .env.production.template .env.production
|
||||
# 然后填写实际值,不要将 .env.production 提交到代码仓库
|
||||
|
||||
# ============================================
|
||||
# 数据库配置
|
||||
# ============================================
|
||||
DB_HOST=1Panel-mysql-xxxx
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=xserver
|
||||
DB_USERNAME=xserver
|
||||
DB_PASSWORD=your_strong_password_here
|
||||
|
||||
# ============================================
|
||||
# Redis 配置
|
||||
# ============================================
|
||||
REDIS_HOST=1Panel-redis-xxxx
|
||||
REDIS_PORT=6379
|
||||
REDIS_PASSWORD=your_redis_password_here
|
||||
REDIS_DATABASE=0
|
||||
|
||||
# ============================================
|
||||
# 飞书配置
|
||||
# ============================================
|
||||
FEISHU_APP_ID=cli_xxxxxxxxxxxxx
|
||||
FEISHU_APP_SECRET=xxxxxxxxxxxxxxxxxxxx
|
||||
FEISHU_ENCRYPT_KEY=xxxxxxxxxxxxxxxxxxxx
|
||||
FEISHU_VERIFICATION_TOKEN=xxxxxxxxxxxxxxxxxxxx
|
||||
FEISHU_TENANT_KEY=14e7bc0fe5985740
|
||||
|
||||
# 飞书应用 URL(获取方式:飞书开放平台 -> 应用详情)
|
||||
FEISHU_APP_URL=https://open.feishu.cn
|
||||
|
||||
# ============================================
|
||||
# 应用配置
|
||||
# ============================================
|
||||
APP_ENV=production
|
||||
APP_DEBUG=false
|
||||
APP_URL=https://xsm.hnxinyouhe.com
|
||||
|
||||
# ============================================
|
||||
# 日志配置
|
||||
# ============================================
|
||||
LOG_LEVEL=info
|
||||
|
||||
# ============================================
|
||||
# 部署配置
|
||||
# ============================================
|
||||
DEPLOY_USER=root
|
||||
DEPLOY_SERVER=your-server-ip
|
||||
DEPLOY_PATH=/opt/x-server-mobile
|
||||
@@ -0,0 +1,61 @@
|
||||
# X-Server Mobile 生产环境 Dockerfile
|
||||
# 基于官方 PHP 8.5 CLI 镜像
|
||||
|
||||
FROM php:8.5-cli
|
||||
|
||||
# 安装系统依赖
|
||||
RUN apt-get update && apt-get install -y \
|
||||
unzip \
|
||||
git \
|
||||
libzip-dev \
|
||||
libpng-dev \
|
||||
libonig-dev \
|
||||
curl \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# 安装 PHP 扩展
|
||||
RUN docker-php-ext-install \
|
||||
zip \
|
||||
pdo \
|
||||
pdo_mysql \
|
||||
bcmath \
|
||||
pcntl \
|
||||
opcache \
|
||||
mbstring
|
||||
|
||||
# 安装 Composer
|
||||
COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /app
|
||||
|
||||
# 复制 composer 文件
|
||||
COPY composer.json composer.lock* ./
|
||||
|
||||
# 安装依赖(生产环境)
|
||||
RUN composer install \
|
||||
--no-dev \
|
||||
--optimize-autoloader \
|
||||
--no-interaction \
|
||||
--no-progress
|
||||
|
||||
# 复制应用文件
|
||||
COPY . .
|
||||
|
||||
# 复制 PHP 生产环境配置
|
||||
COPY php-prod.ini /usr/local/etc/php/conf.d/99-production.ini
|
||||
|
||||
# 创建运行时目录
|
||||
RUN mkdir -p /app/runtime/logs \
|
||||
&& mkdir -p /app/runtime/cache \
|
||||
&& chmod -R 755 /app/runtime
|
||||
|
||||
# 暴露端口
|
||||
EXPOSE 8787
|
||||
|
||||
# 健康检查
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
|
||||
CMD php -r "exit(0);" || exit 1
|
||||
|
||||
# 启动 Webman(前台运行)
|
||||
CMD ["php", "start.php", "start"]
|
||||
Executable
+169
@@ -0,0 +1,169 @@
|
||||
#!/bin/bash
|
||||
# X-Server Mobile 生产部署脚本
|
||||
# 使用方法: ./deploy.sh [server]
|
||||
|
||||
set -e
|
||||
|
||||
# 配置
|
||||
SERVER=${1:-"your-server.com"} # 默认服务器,可以通过参数指定
|
||||
DEPLOY_USER="root"
|
||||
DEPLOY_PATH="/opt/x-server-mobile"
|
||||
FRONTEND_BUILD_DIR="./frontend/dist"
|
||||
BACKEND_SOURCE_DIR="./backend"
|
||||
|
||||
# 颜色输出
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# 检查环境
|
||||
check_env() {
|
||||
log_info "检查部署环境..."
|
||||
|
||||
if ! command -v rsync &> /dev/null; then
|
||||
log_error "rsync 未安装,请先安装: apt-get install rsync"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d "$FRONTEND_BUILD_DIR" ]; then
|
||||
log_error "前端构建目录不存在: $FRONTEND_BUILD_DIR"
|
||||
log_info "请先运行: cd frontend && npm install && npm run build"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "环境检查通过"
|
||||
}
|
||||
|
||||
# 备份远程服务器
|
||||
backup_remote() {
|
||||
log_info "备份远程服务器..."
|
||||
|
||||
BACKUP_NAME="$(date +%Y%m%d_%H%M%S)"
|
||||
|
||||
ssh ${DEPLOY_USER}@${SERVER} << EOF
|
||||
mkdir -p ${DEPLOY_PATH}/backup/${BACKUP_NAME}
|
||||
cp -r ${DEPLOY_PATH}/frontend ${DEPLOY_PATH}/backup/${BACKUP_NAME}/ 2>/dev/null || true
|
||||
cp -r ${DEPLOY_PATH}/backend ${DEPLOY_PATH}/backup/${BACKUP_NAME}/ 2>/dev/null || true
|
||||
echo "备份完成: ${BACKUP_NAME}"
|
||||
EOF
|
||||
|
||||
log_info "备份完成: ${BACKUP_NAME}"
|
||||
}
|
||||
|
||||
# 部署前端
|
||||
deploy_frontend() {
|
||||
log_info "部署前端..."
|
||||
|
||||
rsync -avz --delete \
|
||||
--exclude='*.map' \
|
||||
${FRONTEND_BUILD_DIR}/ \
|
||||
${DEPLOY_USER}@${SERVER}:${DEPLOY_PATH}/frontend/
|
||||
|
||||
log_info "前端部署完成"
|
||||
}
|
||||
|
||||
# 部署后端
|
||||
deploy_backend() {
|
||||
log_info "部署后端..."
|
||||
|
||||
rsync -avz \
|
||||
--exclude='vendor/' \
|
||||
--exclude='runtime/' \
|
||||
--exclude='.git/' \
|
||||
--exclude='*.log' \
|
||||
${BACKEND_SOURCE_DIR}/ \
|
||||
${DEPLOY_USER}@${SERVER}:${DEPLOY_PATH}/backend/
|
||||
|
||||
log_info "后端部署完成"
|
||||
}
|
||||
|
||||
# 重启服务
|
||||
restart_services() {
|
||||
log_info "重启服务..."
|
||||
|
||||
ssh ${DEPLOY_USER}@${SERVER} << 'EOF'
|
||||
cd /opt/x-server-mobile
|
||||
|
||||
# 重启后端容器
|
||||
docker-compose -f docker-compose.prod.yml restart backend
|
||||
|
||||
# 等待后端启动
|
||||
sleep 5
|
||||
|
||||
# 检查容器状态
|
||||
docker ps | grep x-server-backend-prod
|
||||
|
||||
# 重载 OpenResty
|
||||
openresty -s reload || nginx -s reload
|
||||
|
||||
echo "服务重启完成"
|
||||
EOF
|
||||
|
||||
log_info "服务重启完成"
|
||||
}
|
||||
|
||||
# 健康检查
|
||||
health_check() {
|
||||
log_info "健康检查..."
|
||||
|
||||
sleep 3
|
||||
|
||||
# 检查前端
|
||||
if curl -s -o /dev/null -w "%{http_code}" http://${SERVER}/ | grep -q "200\|301\|302"; then
|
||||
log_info "前端检查通过"
|
||||
else
|
||||
log_warn "前端检查失败"
|
||||
fi
|
||||
|
||||
# 检查 API
|
||||
if curl -s http://${SERVER}/api/v1/health 2>/dev/null | grep -q "ok\|success"; then
|
||||
log_info "API 检查通过"
|
||||
else
|
||||
log_warn "API 检查失败(可能需要登录)"
|
||||
fi
|
||||
}
|
||||
|
||||
# 主流程
|
||||
main() {
|
||||
echo "========================================="
|
||||
echo " X-Server Mobile 生产部署脚本"
|
||||
echo "========================================="
|
||||
echo "服务器: ${SERVER}"
|
||||
echo "部署路径: ${DEPLOY_PATH}"
|
||||
echo ""
|
||||
|
||||
# 确认部署
|
||||
read -p "确认部署到 ${SERVER}? (y/N) " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
log_info "部署已取消"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
check_env
|
||||
backup_remote
|
||||
deploy_frontend
|
||||
deploy_backend
|
||||
restart_services
|
||||
health_check
|
||||
|
||||
echo ""
|
||||
log_info "部署完成!"
|
||||
echo "查看日志: ssh ${DEPLOY_USER}@${SERVER} 'docker logs -f x-server-backend-prod'"
|
||||
}
|
||||
|
||||
# 执行主流程
|
||||
main
|
||||
@@ -0,0 +1,58 @@
|
||||
# X-Server Mobile 生产环境 Docker Compose
|
||||
# 使用方法: docker-compose -f docker-compose.prod.yml up -d
|
||||
|
||||
services:
|
||||
# PHP 后端服务
|
||||
backend:
|
||||
build:
|
||||
context: ./backend
|
||||
dockerfile: Dockerfile.prod
|
||||
container_name: x-server-backend-prod
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8787:8787"
|
||||
environment:
|
||||
# 应用环境
|
||||
- APP_ENV=production
|
||||
- APP_DEBUG=false
|
||||
|
||||
# 数据库配置(使用 1Panel 的 MySQL)
|
||||
# 注意:请替换为实际的容器名和密码
|
||||
- DB_HOST=1Panel-mysql-409s
|
||||
- DB_PORT=3306
|
||||
- DB_DATABASE=xserver
|
||||
- DB_USERNAME=xserver
|
||||
- DB_PASSWORD=${DB_PASSWORD:-change_me_in_production}
|
||||
|
||||
# Redis 配置(使用 1Panel 的 Redis)
|
||||
# 注意:请替换为实际的容器名和密码
|
||||
- REDIS_HOST=1Panel-redis-xxxx
|
||||
- REDIS_PORT=6379
|
||||
- REDIS_PASSWORD=${REDIS_PASSWORD:-change_me_in_production}
|
||||
|
||||
# 飞书配置(请替换为实际值)
|
||||
- FEISHU_APP_ID=${FEISHU_APP_ID}
|
||||
- FEISHU_APP_SECRET=${FEISHU_APP_SECRET}
|
||||
- FEISHU_ENCRYPT_KEY=${FEISHU_ENCRYPT_KEY}
|
||||
- FEISHU_VERIFICATION_TOKEN=${FEISHU_VERIFICATION_TOKEN}
|
||||
- FEISHU_TENANT_KEY=${FEISHU_TENANT_KEY:-14e7bc0fe5985740}
|
||||
volumes:
|
||||
- ./backend:/app
|
||||
- ./logs/backend:/app/runtime/logs
|
||||
networks:
|
||||
- 1panel-network
|
||||
healthcheck:
|
||||
test: ["CMD", "php", "-r", "exit(0);"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
networks:
|
||||
1panel-network:
|
||||
external: true
|
||||
@@ -0,0 +1,58 @@
|
||||
; X-Server Mobile 生产环境 PHP 配置
|
||||
; 文件位置: backend/php-prod.ini
|
||||
; 用途: Docker 容器内的 PHP 生产环境配置
|
||||
|
||||
; ============================================
|
||||
; OPcache 配置
|
||||
; ============================================
|
||||
opcache.enable=1
|
||||
opcache.enable_cli=1
|
||||
opcache.memory_consumption=128
|
||||
opcache.interned_strings_buffer=8
|
||||
opcache.max_accelerated_files=10000
|
||||
opcache.revalidate_freq=60
|
||||
opcache.fast_shutdown=1
|
||||
opcache.save_comments=1
|
||||
|
||||
; ============================================
|
||||
; 错误处理
|
||||
; ============================================
|
||||
display_errors=0
|
||||
display_startup_errors=0
|
||||
log_errors=1
|
||||
error_log=/app/runtime/logs/php_errors.log
|
||||
error_reporting=E_ALL & ~E_DEPRECATED & ~E_STRICT
|
||||
|
||||
; ============================================
|
||||
; 安全配置
|
||||
; ============================================
|
||||
expose_php=Off
|
||||
allow_url_fopen=On
|
||||
allow_url_include=Off
|
||||
|
||||
; 禁用危险函数(根据实际需求调整)
|
||||
; disable_functions=exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source
|
||||
|
||||
; ============================================
|
||||
; 性能配置
|
||||
; ============================================
|
||||
max_execution_time=60
|
||||
max_input_time=60
|
||||
memory_limit=256M
|
||||
post_max_size=50M
|
||||
upload_max_filesize=50M
|
||||
max_file_uploads=20
|
||||
|
||||
; ============================================
|
||||
; 会话配置
|
||||
; ============================================
|
||||
session.cookie_httponly=1
|
||||
session.cookie_secure=1
|
||||
session.use_strict_mode=1
|
||||
session.cookie_samesite="Lax"
|
||||
|
||||
; ============================================
|
||||
; 其他配置
|
||||
; ============================================
|
||||
date.timezone=Asia/Shanghai
|
||||
default_charset="UTF-8"
|
||||
Executable
+159
@@ -0,0 +1,159 @@
|
||||
#!/bin/bash
|
||||
# X-Server Mobile 回滚脚本
|
||||
# 使用方法: ./rollback.sh [backup_name]
|
||||
|
||||
set -e
|
||||
|
||||
# 配置
|
||||
SERVER="your-server.com"
|
||||
DEPLOY_USER="root"
|
||||
DEPLOY_PATH="/opt/x-server-mobile"
|
||||
BACKUP_NAME=$1
|
||||
|
||||
# 颜色输出
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# 列出可用备份
|
||||
list_backups() {
|
||||
log_info "可用备份列表:"
|
||||
|
||||
ssh ${DEPLOY_USER}@${SERVER} << 'EOF'
|
||||
cd /opt/x-server-mobile/backup
|
||||
ls -1t | head -10
|
||||
EOF
|
||||
}
|
||||
|
||||
# 确认备份存在
|
||||
check_backup() {
|
||||
log_info "检查备份 ${BACKUP_NAME}..."
|
||||
|
||||
EXISTS=$(ssh ${DEPLOY_USER}@${SERVER} "
|
||||
if [ -d ${DEPLOY_PATH}/backup/${BACKUP_NAME} ]; then
|
||||
echo 'exists'
|
||||
else
|
||||
echo 'not_found'
|
||||
fi
|
||||
")
|
||||
|
||||
if [ "$EXISTS" != "exists" ]; then
|
||||
log_error "备份不存在: ${BACKUP_NAME}"
|
||||
list_backups
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "备份检查通过"
|
||||
}
|
||||
|
||||
# 回滚前端
|
||||
rollback_frontend() {
|
||||
log_info "回滚前端..."
|
||||
|
||||
ssh ${DEPLOY_USER}@${SERVER} << EOF
|
||||
rm -rf ${DEPLOY_PATH}/frontend/*
|
||||
cp -r ${DEPLOY_PATH}/backup/${BACKUP_NAME}/frontend/* ${DEPLOY_PATH}/frontend/
|
||||
EOF
|
||||
|
||||
log_info "前端回滚完成"
|
||||
}
|
||||
|
||||
# 回滚后端(可选)
|
||||
rollback_backend() {
|
||||
read -p "是否回滚后端代码? (y/N) " -n 1 -r
|
||||
echo
|
||||
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
log_info "跳过后端回滚"
|
||||
return
|
||||
fi
|
||||
|
||||
log_info "回滚后端..."
|
||||
|
||||
ssh ${DEPLOY_USER}@${SERVER} << EOF
|
||||
# 保留 vendor 目录
|
||||
mv ${DEPLOY_PATH}/backend/vendor /tmp/backend_vendor_backup 2>/dev/null || true
|
||||
|
||||
rm -rf ${DEPLOY_PATH}/backend/*
|
||||
cp -r ${DEPLOY_PATH}/backup/${BACKUP_NAME}/backend/* ${DEPLOY_PATH}/backend/
|
||||
|
||||
# 恢复 vendor 目录
|
||||
mv /tmp/backend_vendor_backup ${DEPLOY_PATH}/backend/vendor 2>/dev/null || true
|
||||
EOF
|
||||
|
||||
log_info "后端回滚完成"
|
||||
}
|
||||
|
||||
# 重启服务
|
||||
restart_services() {
|
||||
log_info "重启服务..."
|
||||
|
||||
ssh ${DEPLOY_USER}@${SERVER} << 'EOF'
|
||||
cd /opt/x-server-mobile
|
||||
|
||||
# 重启后端容器
|
||||
docker-compose -f docker-compose.prod.yml restart backend
|
||||
|
||||
# 等待后端启动
|
||||
sleep 5
|
||||
|
||||
# 重载 OpenResty
|
||||
openresty -s reload || nginx -s reload
|
||||
|
||||
echo "服务重启完成"
|
||||
EOF
|
||||
|
||||
log_info "服务重启完成"
|
||||
}
|
||||
|
||||
# 主流程
|
||||
main() {
|
||||
echo "========================================="
|
||||
echo " X-Server Mobile 回滚脚本"
|
||||
echo "========================================="
|
||||
echo "服务器: ${SERVER}"
|
||||
|
||||
if [ -z "$BACKUP_NAME" ]; then
|
||||
log_error "请指定备份名称"
|
||||
echo ""
|
||||
list_backups
|
||||
echo ""
|
||||
echo "使用方法: ./rollback.sh <backup_name>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "备份名称: ${BACKUP_NAME}"
|
||||
echo ""
|
||||
|
||||
# 确认回滚
|
||||
read -p "确认回滚到 ${BACKUP_NAME}? (y/N) " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
log_info "回滚已取消"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
check_backup
|
||||
rollback_frontend
|
||||
rollback_backend
|
||||
restart_services
|
||||
|
||||
echo ""
|
||||
log_info "回滚完成!"
|
||||
}
|
||||
|
||||
# 执行主流程
|
||||
main
|
||||
@@ -0,0 +1,183 @@
|
||||
# X-Server Mobile 线上环境 OpenResty 配置
|
||||
# 文件位置: /usr/local/openresty/nginx/conf/conf.d/x-server-mobile.conf
|
||||
|
||||
# HTTP 重定向到 HTTPS
|
||||
server {
|
||||
listen 80;
|
||||
server_name xsm.hnxinyouhe.com;
|
||||
|
||||
# Let's Encrypt ACME 挑战
|
||||
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 xsm.hnxinyouhe.com;
|
||||
|
||||
# ============================================
|
||||
# SSL 证书配置
|
||||
# ============================================
|
||||
|
||||
# Let's Encrypt 证书路径
|
||||
ssl_certificate /etc/letsencrypt/live/xsm.hnxinyouhe.com/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/xsm.hnxinyouhe.com/privkey.pem;
|
||||
|
||||
# 如果使用自签名证书,取消下面的注释并注释上面的 Let's Encrypt 配置
|
||||
# ssl_certificate /etc/nginx/ssl/xsm.hnxinyouhe.com.crt;
|
||||
# ssl_certificate_key /etc/nginx/ssl/xsm.hnxinyouhe.com.key;
|
||||
|
||||
# SSL 协议和加密套件
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
|
||||
ssl_prefer_server_ciphers off;
|
||||
|
||||
# SSL 会话缓存
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_timeout 10m;
|
||||
ssl_session_tickets off;
|
||||
|
||||
# OCSP Stapling
|
||||
ssl_stapling on;
|
||||
ssl_stapling_verify on;
|
||||
ssl_trusted_certificate /etc/letsencrypt/live/xsm.hnxinyouhe.com/chain.pem;
|
||||
resolver 8.8.8.8 8.8.4.4 valid=300s;
|
||||
resolver_timeout 5s;
|
||||
|
||||
# ============================================
|
||||
# 日志配置
|
||||
# ============================================
|
||||
|
||||
access_log /opt/x-server-mobile/logs/nginx_access.log combined;
|
||||
error_log /opt/x-server-mobile/logs/nginx_error.log warn;
|
||||
|
||||
# ============================================
|
||||
# 安全头
|
||||
# ============================================
|
||||
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header Referrer-Policy "no-referrer-when-downgrade" always;
|
||||
|
||||
# ============================================
|
||||
# Gzip 压缩
|
||||
# ============================================
|
||||
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_min_length 1024;
|
||||
gzip_comp_level 6;
|
||||
gzip_types
|
||||
text/plain
|
||||
text/css
|
||||
text/xml
|
||||
text/javascript
|
||||
application/json
|
||||
application/javascript
|
||||
application/xml+rss
|
||||
application/rss+xml
|
||||
font/truetype
|
||||
font/opentype
|
||||
application/vnd.ms-fontobject
|
||||
image/svg+xml;
|
||||
|
||||
# ============================================
|
||||
# 静态资源(长期缓存)
|
||||
# ============================================
|
||||
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|webp|svg|ico|woff|woff2|ttf|eot)$ {
|
||||
root /opt/x-server-mobile/frontend;
|
||||
expires 7d;
|
||||
add_header Cache-Control "public, immutable";
|
||||
access_log off;
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# 飞书回调路由(必须在 API 之前)
|
||||
# ============================================
|
||||
|
||||
location /login {
|
||||
proxy_pass http://127.0.0.1:8787;
|
||||
proxy_http_version 1.1;
|
||||
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_set_header Host $host;
|
||||
}
|
||||
|
||||
location /login/callback {
|
||||
proxy_pass http://127.0.0.1:8787;
|
||||
proxy_http_version 1.1;
|
||||
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_set_header Host $host;
|
||||
}
|
||||
|
||||
location /login/qrcode {
|
||||
proxy_pass http://127.0.0.1:8787;
|
||||
proxy_http_version 1.1;
|
||||
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_set_header Host $host;
|
||||
}
|
||||
|
||||
# 飞书卡片回调
|
||||
location /feishu/card/callback {
|
||||
proxy_pass http://127.0.0.1:8787;
|
||||
proxy_http_version 1.1;
|
||||
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_set_header Host $host;
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# API 代理
|
||||
# ============================================
|
||||
|
||||
location /api/ {
|
||||
proxy_pass http://127.0.0.1:8787;
|
||||
proxy_http_version 1.1;
|
||||
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_set_header Host $host;
|
||||
|
||||
# 超时配置
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
|
||||
# 缓冲配置
|
||||
proxy_buffering on;
|
||||
proxy_buffer_size 4k;
|
||||
proxy_buffers 8 4k;
|
||||
proxy_busy_buffers_size 8k;
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# 前端 SPA(所有其他请求返回 index.html)
|
||||
# ============================================
|
||||
|
||||
location / {
|
||||
root /opt/x-server-mobile/frontend;
|
||||
|
||||
# SPA 路由支持
|
||||
try_files $uri $uri/ /index.html;
|
||||
|
||||
# 禁用 HTML 缓存
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
add_header Pragma "no-cache";
|
||||
add_header Expires "0";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user