From 3e7120a339e430c894bd8bf77c60dd6801fd1282 Mon Sep 17 00:00:00 2001 From: patdelphi Date: Tue, 19 Aug 2025 16:05:39 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0Koyeb=E9=83=A8=E7=BD=B2?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E5=92=8C=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 8 +- .koyeb/koyeb.yaml | 31 ++++++++ Dockerfile | 27 +++++++ KOYEB_DEPLOYMENT.md | 161 ++++++++++++++++++++++++++++++++++++++ Procfile | 1 - railway.json | 13 --- server/database/index.cjs | 5 +- server/index.cjs | 17 ++-- src/lib/localApi.ts | 3 +- 9 files changed, 237 insertions(+), 29 deletions(-) create mode 100644 .koyeb/koyeb.yaml create mode 100644 Dockerfile create mode 100644 KOYEB_DEPLOYMENT.md delete mode 100644 Procfile delete mode 100644 railway.json diff --git a/.gitignore b/.gitignore index 8512bf0..6b621b6 100644 --- a/.gitignore +++ b/.gitignore @@ -47,10 +47,4 @@ temp/ *.ntvs* *.njsproj *.sln -*.sw? - -# Database files (SQLite) -*.db -*.db-shm -*.db-wal -numerology.db* \ No newline at end of file +*.sw? \ No newline at end of file diff --git a/.koyeb/koyeb.yaml b/.koyeb/koyeb.yaml new file mode 100644 index 0000000..7d018a2 --- /dev/null +++ b/.koyeb/koyeb.yaml @@ -0,0 +1,31 @@ +# Koyeb部署配置文件 +name: suanming-app + +services: + - name: suanming-backend + type: web + git: + branch: master + build_command: npm ci + run_command: npm start + instance_type: nano + ports: + - port: 8000 + protocol: http + env: + - key: NODE_ENV + value: production + - key: PORT + value: "8000" + volumes: + - name: sqlite-data + mount_path: /app/data + size: 1GB + health_check: + http: + path: /api/health + port: 8000 + initial_delay_seconds: 30 + period_seconds: 10 + timeout_seconds: 5 + failure_threshold: 3 \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..5bcf6d1 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,27 @@ +# 使用官方Node.js运行时作为基础镜像 +FROM node:18-alpine + +# 设置工作目录 +WORKDIR /app + +# 复制package.json和package-lock.json +COPY package*.json ./ + +# 安装依赖 +RUN npm ci --only=production + +# 复制应用代码 +COPY . . + +# 创建数据目录用于SQLite数据库 +RUN mkdir -p /app/data + +# 设置环境变量 +ENV NODE_ENV=production +ENV PORT=8000 + +# 暴露端口 +EXPOSE 8000 + +# 初始化数据库并启动应用 +CMD ["sh", "-c", "npm run db:init && npm start"] \ No newline at end of file diff --git a/KOYEB_DEPLOYMENT.md b/KOYEB_DEPLOYMENT.md new file mode 100644 index 0000000..a13905c --- /dev/null +++ b/KOYEB_DEPLOYMENT.md @@ -0,0 +1,161 @@ +# Koyeb 部署指南 + +本指南将帮助您将三算命项目部署到 Koyeb 平台。 + +## 🚀 部署步骤 + +### 1. 准备工作 + +确保您的代码已推送到 GitHub 仓库的 `master` 分支。 + +### 2. 注册 Koyeb 账号 + +1. 访问 [Koyeb官网](https://www.koyeb.com/) +2. 注册免费账号 +3. 验证邮箱 + +### 3. 创建新应用 + +1. 登录 Koyeb 控制台 +2. 点击 "Create App" +3. 选择 "GitHub" 作为部署源 +4. 授权 Koyeb 访问您的 GitHub 仓库 +5. 选择您的项目仓库 +6. 选择 `master` 分支 + +### 4. 配置部署设置 + +#### 基本设置 +- **App Name**: `suanming-app`(或您喜欢的名称) +- **Service Name**: `suanming-backend` +- **Instance Type**: `Nano` (免费套餐) +- **Port**: `8000` + +#### 构建设置 +- **Build Command**: `npm ci` +- **Run Command**: `npm start` + +#### 环境变量 +在 Koyeb 控制台中添加以下环境变量: + +``` +NODE_ENV=production +PORT=8000 +JWT_SECRET=your-super-secret-jwt-key-here +``` + +**重要**: 请将 `JWT_SECRET` 替换为一个安全的随机字符串! + +#### 持久化存储 +1. 在 "Volumes" 部分添加存储卷 +2. **Name**: `sqlite-data` +3. **Mount Path**: `/app/data` +4. **Size**: `1GB` + +### 5. 部署应用 + +1. 检查所有配置 +2. 点击 "Deploy" +3. 等待部署完成(通常需要 3-5 分钟) + +### 6. 获取应用URL + +部署完成后,Koyeb 会提供一个类似这样的URL: +``` +https://your-app-name-your-org.koyeb.app +``` + +### 7. 更新前端配置 + +1. 复制您的 Koyeb 应用 URL +2. 更新 `src/lib/localApi.ts` 中的 API URL: + +```typescript +const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || + (import.meta.env.PROD ? 'https://your-actual-app-url.koyeb.app/api' : 'http://localhost:3001/api'); +``` + +3. 提交并推送更改 + +### 8. 验证部署 + +访问以下端点验证部署是否成功: + +- **健康检查**: `https://your-app-url.koyeb.app/api/health` +- **API根路径**: `https://your-app-url.koyeb.app/api` + +## 🔧 故障排除 + +### 常见问题 + +#### 1. 应用启动失败 +- 检查环境变量是否正确设置 +- 查看 Koyeb 日志中的错误信息 +- 确保 `package.json` 中的 `start` 脚本正确 + +#### 2. 数据库连接问题 +- 确保持久化存储卷已正确配置 +- 检查 `/app/data` 目录权限 +- 查看数据库初始化日志 + +#### 3. CORS 错误 +- 在服务器配置中添加您的前端域名到 CORS 白名单 +- 更新 `server/index.cjs` 中的 CORS 配置 + +### 查看日志 + +在 Koyeb 控制台中: +1. 进入您的应用 +2. 点击 "Logs" 标签 +3. 查看实时日志输出 + +## 📊 监控和维护 + +### 健康检查 + +Koyeb 会自动监控您的应用健康状态: +- **端点**: `/api/health` +- **检查间隔**: 10秒 +- **超时时间**: 5秒 + +### 数据备份 + +定期备份您的 SQLite 数据库: +1. 在 Koyeb 控制台中访问您的应用 +2. 使用 "Terminal" 功能连接到容器 +3. 复制 `/app/data/numerology.db` 文件 + +### 扩展和升级 + +如需更多资源: +1. 在 Koyeb 控制台中选择更大的实例类型 +2. 增加存储卷大小 +3. 配置自动扩展规则 + +## 💰 费用说明 + +**免费套餐包含**: +- 512MB RAM +- 100GB 带宽/月 +- 1个应用 +- 基础支持 + +**注意**: 超出免费额度后会产生费用,请监控使用情况。 + +## 🔗 有用链接 + +- [Koyeb 文档](https://www.koyeb.com/docs) +- [Koyeb 定价](https://www.koyeb.com/pricing) +- [Koyeb 支持](https://www.koyeb.com/support) + +## 🆘 获取帮助 + +如果遇到问题: +1. 查看 Koyeb 官方文档 +2. 检查应用日志 +3. 联系 Koyeb 支持团队 +4. 在项目 GitHub 仓库中创建 Issue + +--- + +**部署成功后,您的三算命应用就可以在全球范围内访问了!** 🎉 \ No newline at end of file diff --git a/Procfile b/Procfile deleted file mode 100644 index e8f79ea..0000000 --- a/Procfile +++ /dev/null @@ -1 +0,0 @@ -web: npm start \ No newline at end of file diff --git a/railway.json b/railway.json deleted file mode 100644 index 3fa6500..0000000 --- a/railway.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "$schema": "https://railway.app/railway.schema.json", - "build": { - "builder": "NIXPACKS" - }, - "deploy": { - "startCommand": "npm start", - "healthcheckPath": "/health", - "healthcheckTimeout": 100, - "restartPolicyType": "ON_FAILURE", - "restartPolicyMaxRetries": 10 - } -} \ No newline at end of file diff --git a/server/database/index.cjs b/server/database/index.cjs index 8a080e6..d27e5cb 100644 --- a/server/database/index.cjs +++ b/server/database/index.cjs @@ -5,7 +5,10 @@ const fs = require('fs'); class DatabaseManager { constructor() { this.db = null; - this.dbPath = path.join(__dirname, '../../numerology.db'); + // 生产环境使用持久化存储路径,开发环境使用本地路径 + this.dbPath = process.env.NODE_ENV === 'production' + ? '/app/data/numerology.db' + : path.join(__dirname, '../../numerology.db'); this.schemaPath = path.join(__dirname, 'schema.sql'); } diff --git a/server/index.cjs b/server/index.cjs index d2c738d..6c9f1d0 100644 --- a/server/index.cjs +++ b/server/index.cjs @@ -42,12 +42,7 @@ app.use(helmet({ // CORS配置 app.use(cors({ origin: process.env.NODE_ENV === 'production' - ? [ - 'http://localhost:5173', - 'http://localhost:4173', - /\.railway\.app$/, // Railway域名 - /\.up\.railway\.app$/ // Railway新域名格式 - ] + ? ['http://localhost:5173', 'http://localhost:4173'] // 生产环境允许的域名 : true, // 开发环境允许所有域名 credentials: true, methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], @@ -68,6 +63,16 @@ app.get('/health', (req, res) => { }); }); +// API健康检查端点(用于Koyeb监控) +app.get('/api/health', (req, res) => { + res.status(200).json({ + status: 'healthy', + timestamp: new Date().toISOString(), + uptime: process.uptime(), + database: 'connected' + }); +}); + // API路由 app.use('/api/auth', authRoutes); app.use('/api/analysis', analysisRoutes); diff --git a/src/lib/localApi.ts b/src/lib/localApi.ts index 2b5f62b..cf1b980 100644 --- a/src/lib/localApi.ts +++ b/src/lib/localApi.ts @@ -1,7 +1,8 @@ // 本地API客户端 // 替代Supabase客户端,提供相同的接口 -const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:3001/api'; +const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || + (import.meta.env.PROD ? 'https://your-app.koyeb.app/api' : 'http://localhost:3001/api'); interface ApiResponse { data?: T;