生产环境修正

This commit is contained in:
2025-10-05 13:34:28 +08:00
parent 47576fdb30
commit b0b748f6d1
47 changed files with 1152 additions and 217 deletions

View File

@@ -1,56 +1,117 @@
const { spawn } = require('child_process');
const path = require('path');
const express = require('express');
const fs = require('fs');
// 生产环境配置
// 加载生产环境配置文件
require('dotenv').config({ path: path.join(__dirname, '.env.production') });
// 生产环境配置 - 宝塔面板兼容
const API_PORT = process.env.PORT || 4001;
const FRONTEND_PORT = process.env.FRONTEND_PORT || 4002;
const NODE_ENV = 'production';
const DOMAIN = process.env.DOMAIN || 'ggl.xi.plus';
// 验证端口范围 (4001-4010)
if (API_PORT < 4001 || API_PORT > 4010) {
console.warn(`警告: API端口 ${API_PORT} 不在推荐范围 4001-4010 内`);
}
if (FRONTEND_PORT < 4001 || FRONTEND_PORT > 4010) {
console.warn(`警告: 前端端口 ${FRONTEND_PORT} 不在推荐范围 4001-4010 内`);
}
// 设置环境变量
process.env.NODE_ENV = NODE_ENV;
process.env.PORT = API_PORT;
process.env.DOMAIN = DOMAIN;
console.log(`启动生产环境服务器`);
console.log(`=== 梦回高句丽 - 生产环境启动 ===`);
console.log(`域名: ${DOMAIN}`);
console.log(`后端API端口: ${API_PORT}`);
console.log(`前端静态文件端口: ${FRONTEND_PORT}`);
console.log(`工作目录: ${process.cwd()}`);
console.log(`Node.js版本: ${process.version}`);
console.log(`启动时间: ${new Date().toLocaleString('zh-CN')}`);
// 检查dist目录是否存在
const distPath = path.join(__dirname, 'dist');
if (!fs.existsSync(distPath)) {
console.error(`错误: dist目录不存在 (${distPath})`);
console.log('请先运行 npm run build 构建前端项目');
process.exit(1);
}
// 启动前端静态文件服务
const app = express();
app.use(express.static(path.join(__dirname, 'dist')));
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist', 'index.html'));
// 安全头设置
app.use((req, res, next) => {
res.setHeader('X-Content-Type-Options', 'nosniff');
res.setHeader('X-Frame-Options', 'DENY');
res.setHeader('X-XSS-Protection', '1; mode=block');
next();
});
const frontendServer = app.listen(FRONTEND_PORT, () => {
console.log(`前端静态文件服务已启动,端口: ${FRONTEND_PORT}`);
// 静态文件服务
app.use(express.static(distPath, {
maxAge: '1y',
etag: true,
lastModified: true
}));
// SPA路由处理
app.get('*', (req, res) => {
res.sendFile(path.join(distPath, 'index.html'));
});
const frontendServer = app.listen(FRONTEND_PORT, '0.0.0.0', () => {
console.log(`✅ 前端静态文件服务已启动`);
console.log(` - 端口: ${FRONTEND_PORT}`);
console.log(` - 访问地址: http://${DOMAIN}:${FRONTEND_PORT}`);
});
// 检查API服务器文件是否存在
const apiServerPath = path.join(__dirname, 'api', 'server.ts');
if (!fs.existsSync(apiServerPath)) {
console.error(`错误: API服务器文件不存在 (${apiServerPath})`);
process.exit(1);
}
// 启动后端API服务器
console.log(`🚀 启动后端API服务器...`);
const apiServer = spawn('node', ['--import', 'tsx/esm', 'api/server.ts'], {
stdio: 'inherit',
env: {
...process.env,
NODE_ENV: NODE_ENV,
PORT: API_PORT
}
stdio: 'inherit',
env: {
...process.env,
NODE_ENV: NODE_ENV,
PORT: API_PORT,
DOMAIN: DOMAIN
},
cwd: __dirname
});
// 处理API服务器进程退出
apiServer.on('close', (code) => {
console.log(`API服务器进程退出退出码: ${code}`);
frontendServer.close();
process.exit(code);
console.log(`API服务器进程退出退出码: ${code}`);
frontendServer.close();
process.exit(code);
});
// 处理API服务器错误
apiServer.on('error', (err) => {
console.error('启动API服务器时发生错误:', err);
frontendServer.close();
process.exit(1);
console.error('启动API服务器时发生错误:', err);
frontendServer.close();
process.exit(1);
});
// API服务器启动成功提示
setTimeout(() => {
console.log(`✅ 后端API服务已启动`);
console.log(` - 端口: ${API_PORT}`);
console.log(` - API地址: http://${DOMAIN}:${API_PORT}/api`);
console.log(`\n🌐 服务器已完全启动,可通过宝塔面板管理`);
}, 2000);
// 优雅关闭
process.on('SIGINT', () => {
console.log('\n收到 SIGINT 信号,正在关闭服务器...');