本指南帮助您将项目从 coze.site 平台迁移到自己的服务器(如阿里云、腾讯云)。


# 呆鸟修仙项目迁移指南

image.png

本指南帮助您将项目从 coze.site 平台迁移到自己的服务器(如阿里云、腾讯云)。

## 目录

- [迁移前准备](#迁移前准备)
- [服务器环境配置](#服务器环境配置)
- [数据库迁移](#数据库迁移)
- [项目部署](#项目部署)
- [域名与SSL配置](#域名与ssl配置)
- [支付接入准备](#支付接入准备)
- [监控与维护](#监控与维护)

---

## 迁移前准备

### 1. 服务器要求

**推荐配置:**
- CPU:2核及以上
- 内存:4GB及以上
- 硬盘:40GB SSD及以上
- 带宽:3Mbps及以上(根据用户量调整)
- 操作系统:Ubuntu 20.04 / 22.04 LTS 或 CentOS 7/8

**必需软件:**
- Node.js 18.x 或 20.x
- PostgreSQL 14 或更高版本
- Nginx(作为反向代理)
- PM2(进程管理)
- Git
- pnpm(包管理器)

### 2. 域名准备

- 购买域名(如:dainiaoxiuxian.com)
- 准备备案(如需要接入微信支付)
- 准备DNS服务商

### 3. 第三方服务账号

#### 必需服务:
- **PostgreSQL 数据库**(云数据库或自建)
- **对象存储(S3兼容)**:阿里云OSS、腾讯云COS或AWS S3
- **天气API**:和风天气(推荐)或 wttr.in

#### 支付服务(可选):
- **Stripe**:适合国际用户
- **微信支付**:适合国内用户(需要企业资质)
- **支付宝**:适合国内用户(需要企业资质)

---

## 服务器环境配置

### 步骤1:基础环境安装

```bash
# 更新系统
sudo apt update && sudo apt upgrade -y

# 安装基础工具
sudo apt install -y curl wget git vim build-essential

# 安装 Node.js 20.x
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs

# 验证安装
node -v  # 应显示 v20.x.x
npm -v   # 应显示 10.x.x

# 安装 pnpm
npm install -g pnpm

# 验证安装
pnpm -v
```

### 步骤2:安装 PostgreSQL

```bash
# 安装 PostgreSQL
sudo apt install -y postgresql postgresql-contrib

# 启动服务
sudo systemctl start postgresql
sudo systemctl enable postgresql

# 切换到 postgres 用户
sudo -u postgres psql

# 在 psql 中执行:
CREATE USER dainiao WITH PASSWORD 'your_strong_password';
CREATE DATABASE dainiao OWNER dainiao;
GRANT ALL PRIVILEGES ON DATABASE dainiao TO dainiao;
\q

# 修改 PostgreSQL 认证方式
sudo vim /etc/postgresql/14/main/pg_hba.conf

# 找到 IPv4 local connections 部分,修改为:
# host    all             all             127.0.0.1/32            md5

# 重启 PostgreSQL
sudo systemctl restart postgresql
```

### 步骤3:安装 PM2

```bash
npm install -g pm2

# 验证安装
pm2 -v
```

### 步骤4:安装 Nginx

```bash
sudo apt install -y nginx

# 启动服务
sudo systemctl start nginx
sudo systemctl enable nginx

# 验证安装
curl localhost  # 应显示 Nginx 欢迎页面
```

---

## 数据库迁移

### 方案1:从 coze.site 导出数据(推荐)

```bash
# 1. 在 coze.site 服务器上导出数据
pg_dump -h your_host -U your_user -d your_database > dump.sql

# 2. 将 dump.sql 传输到新服务器
scp dump.sql user@your-server:/tmp/

# 3. 在新服务器上导入数据
psql -U dainiao -d dainiao < /tmp/dump.sql
```

### 方案2:重新初始化数据库

```bash
# 1. 克隆项目到服务器
git clone <your-repo-url> /var/www/dainiao
cd /var/www/dainiao

# 2. 安装依赖
pnpm install

# 3. 配置环境变量
cp .env.example .env
vim .env
```

#### 环境变量配置(.env)

```env
# 数据库配置
DATABASE_URL="postgresql://dainiao:your_password@localhost:5432/dainiao"

# 对象存储配置(以阿里云OSS为例)
S3_ENDPOINT="https://oss-cn-hangzhou.aliyuncs.com"
S3_ACCESS_KEY_ID="your_access_key"
S3_SECRET_ACCESS_KEY="your_secret_key"
S3_BUCKET="your-bucket-name"
S3_REGION="oss-cn-hangzhou"

# 天气API配置(和风天气)
QWEATHER_API_KEY="your_qweather_key"

# 端口配置
PORT=3000
NODE_ENV=production

# JWT密钥(自行生成随机字符串)
JWT_SECRET="your_jwt_secret_here"

# 管理员信息(用于初始化)
ADMIN_USERNAME="李邦华"
ADMIN_PASSWORD="admin123"
ADMIN_INVITE_CODE="LIBANGHUA"
```

```bash
# 4. 运行数据库迁移
pnpm drizzle-kit push

# 5. 初始化数据
curl -X POST http://localhost:3000/api/admin/init-libanghua-v2
```

---

## 项目部署

### 步骤1:部署项目代码

```bash
# 1. 克隆项目(或上传代码)
cd /var/www
git clone <your-repo-url> dainiao
cd dainiao

# 2. 安装依赖
pnpm install

# 3. 构建项目
pnpm build
```

### 步骤2:使用 PM2 启动服务

创建 PM2 配置文件 `ecosystem.config.js`:

```javascript
module.exports = {
  apps: [{
    name: 'dainiao',
    script: 'node_modules/next/dist/bin/next',
    args: 'start',
    cwd: '/var/www/dainiao',
    instances: 2,
    exec_mode: 'cluster',
    env: {
      NODE_ENV: 'production',
      PORT: 3000
    },
    error_file: '/var/log/dainiao/error.log',
    out_file: '/var/log/dainiao/out.log',
    log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
    merge_logs: true,
    autorestart: true,
    max_restarts: 10,
    min_uptime: '10s',
    max_memory_restart: '1G'
  }]
};
```

启动服务:

```bash
# 创建日志目录
sudo mkdir -p /var/log/dainiao
sudo chown -R $USER:$USER /var/log/dainiao

# 启动服务
pm2 start ecosystem.config.js

# 查看服务状态
pm2 status
pm2 logs dainiao

# 设置开机自启
pm2 startup
pm2 save
```

### 步骤3:配置 Nginx 反向代理

创建 Nginx 配置文件 `/etc/nginx/sites-available/dainiao`:

```nginx
upstream dainiao_backend {
    server 127.0.0.1:3000;
    keepalive 64;
}

# HTTP 重定向到 HTTPS
server {
    listen 80;
    listen [::]:80;
    server_name dainiaoxiuxian.com www.dainiaoxiuxian.com;

    # Let's Encrypt 验证路径
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        return 301 https://$server_name$request_uri;
    }
}

# HTTPS 配置
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name dainiaoxiuxian.com www.dainiaoxiuxian.com;

    # SSL 证书配置(稍后配置)
    ssl_certificate /etc/letsencrypt/live/dainiaoxiuxian.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/dainiaoxiuxian.com/privkey.pem;

    # 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';
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    # 日志
    access_log /var/log/nginx/dainiao_access.log;
    error_log /var/log/nginx/dainiao_error.log;

    # 客户端最大上传大小
    client_max_body_size 10M;

    # 代理到 Next.js
    location / {
        proxy_pass http://dainiao_backend;
        proxy_http_version 1.1;
        
        # WebSocket 支持
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        
        # 代理头
        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_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
        
        # 缓存设置
        proxy_cache_bypass $http_upgrade;
        proxy_redirect off;
    }

    # 静态资源缓存
    location /_next/static {
        proxy_pass http://dainiao_backend;
        proxy_cache_valid 200 365d;
        add_header Cache-Control "public, immutable";
    }

    location /static {
        proxy_pass http://dainiao_backend;
        proxy_cache_valid 200 365d;
        add_header Cache-Control "public, immutable";
    }
}
```

启用配置:

```bash
# 创建软链接
sudo ln -s /etc/nginx/sites-available/dainiao /etc/nginx/sites-enabled/

# 测试配置
sudo nginx -t

# 重启 Nginx
sudo systemctl restart nginx
```

---

## 域名与SSL配置

### 步骤1:DNS解析

在您的域名DNS管理中添加记录:

```
类型    主机记录            记录值
A       @                  您的服务器公网IP
A       www                您的服务器公网IP
```

### 步骤2:配置SSL证书(使用 Let's Encrypt)

```bash
# 安装 Certbot
sudo apt install -y certbot python3-certbot-nginx

# 获取证书(自动配置 Nginx)
sudo certbot --nginx -d dainiaoxiuxian.com -d www.dainiaoxiuxian.com

# 按提示输入邮箱,同意条款,选择是否重定向到 HTTPS

# 设置自动续期
sudo certbot renew --dry-run

# 添加 cron 任务
sudo crontab -e
# 添加以下行(每天凌晨2点检查续期)
0 2 * * * /usr/bin/certbot renew --quiet --post-hook "systemctl reload nginx"
```

### 步骤3:防火墙配置

```bash
# 启用 UFW
sudo ufw enable

# 允许必要端口
sudo ufw allow 22/tcp    # SSH
sudo ufw allow 80/tcp    # HTTP
sudo ufw allow 443/tcp   # HTTPS

# 查看状态
sudo ufw status
```

---

## 支付接入准备

### 选项1:Stripe(推荐,适合国际用户)

#### 优势:
- 无需企业资质,个人账号即可申请
- 支持全球支付
- API 简单易用
- 不需要域名备案

#### 申请流程:
1. 访问 [Stripe](https://stripe.com) 注册账号
2. 完成个人验证(护照/身份证)
3. 添加银行账户(用于提现)
4. 获取 API Keys(Publishable Key 和 Secret Key)

#### 集成步骤:

1. 安装 Stripe SDK:
```bash
pnpm add stripe
```

2. 创建支付 API `src/app/api/payment/stripe/create-checkout-session/route.ts`:

```typescript
import { NextRequest, NextResponse } from "next/server";
import Stripe from "stripe";

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
  apiVersion: "2024-12-18.acacia",
});

export async function POST(request: NextRequest) {
  try {
    const body = await request.json();
    const { membershipType } = body;

    // 定义价格
    const prices = {
      monthly: "price_xxx",      // 月度会员价格ID
      quarterly: "price_xxx",    // 季度会员价格ID
      annual: "price_xxx",       // 年度会员价格ID
    };

    const priceId = prices[membershipType as keyof typeof prices];
    if (!priceId) {
      return NextResponse.json({ error: "无效的会员类型" }, { status: 400 });
    }

    // 创建 Checkout Session
    const session = await stripe.checkout.sessions.create({
      mode: "subscription",
      payment_method_types: ["card"],
      line_items: [
        {
          price: priceId,
          quantity: 1,
        },
      ],
      success_url: `${process.env.NEXT_PUBLIC_BASE_URL}/payment/success?session_id={CHECKOUT_SESSION_ID}`,
      cancel_url: `${process.env.NEXT_PUBLIC_BASE_URL}/payment/cancel`,
      metadata: {
        userId: body.userId,
        membershipType: membershipType,
      },
    });

    return NextResponse.json({ url: session.url });
  } catch (error) {
    console.error("创建支付会话失败:", error);
    return NextResponse.json(
      { error: "创建支付会话失败" },
      { status: 500 }
    );
  }
}
```

3. 创建 Webhook API `src/app/api/payment/stripe/webhook/route.ts`:

```typescript
import { NextRequest, NextResponse } from "next/server";
import Stripe from "stripe";
import { getDb } from "coze-coding-dev-sdk";
import { sql } from "drizzle-orm";

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
  apiVersion: "2024-12-18.acacia",
});

export async function POST(request: NextRequest) {
  const body = await request.text();
  const signature = request.headers.get("stripe-signature")!;

  try {
    const event = stripe.webhooks.constructEvent(
      body,
      signature,
      process.env.STRIPE_WEBHOOK_SECRET!
    );

    if (event.type === "checkout.session.completed") {
      const session = event.data.object as Stripe.Checkout.Session;
      const userId = session.metadata?.userId;
      const membershipType = session.metadata?.membershipType;

      // 更新用户权限
      const db = await getDb();
      const dailyLimits = {
        monthly: 10,
        quarterly: 20,
        annual: 50,
      };

      await db.execute(
        sql`UPDATE user_permissions
            SET sign_max_daily = ${dailyLimits[membershipType as keyof typeof dailyLimits] || 3},
                membership_type = ${membershipType},
                updated_at = NOW()
            WHERE user_id = ${userId}`
      );
    }

    return NextResponse.json({ received: true });
  } catch (error) {
    console.error("Webhook 处理失败:", error);
    return NextResponse.json({ error: "Webhook 处理失败" }, { status: 400 });
  }
}
```

4. 在 Stripe Dashboard 配置 Webhook:
   - URL: `https://dainiaoxiuxian.com/api/payment/stripe/webhook`
   - 事件: `checkout.session.completed`
   - 获取 Webhook Secret 并添加到环境变量

### 选项2:微信支付(适合国内用户)

#### 前置条件:
- 企业营业执照
- 域名备案(ICP)
- 企业银行账户

#### 申请流程:
1. 访问 [微信支付商户平台](https://pay.weixin.qq.com)
2. 注册商户账号
3. 提交企业资质审核
4. 审核通过后获取 API 证书和密钥

#### 注意事项:
- 开发流程复杂,需要对接微信支付 SDK
- 需要配置回调地址(必须是 HTTPS)
- 建议使用第三方支付服务商(如 Ping++)简化集成

### 选项3:支付宝(适合国内用户)

#### 前置条件:
- 企业营业执照
- 域名备案(ICP)
- 企业银行账户

#### 申请流程:
1. 访问 [支付宝开放平台](https://open.alipay.com)
2. 创建应用并提交审核
3. 签约支付产品
4. 获取 APPID 和密钥

#### 集成步骤:
1. 安装支付宝 SDK:`pnpm add alipay-sdk`
2. 创建支付订单 API
3. 配置异步通知回调
4. 处理支付结果

---

## 监控与维护

### 1. 日志管理

```bash
# PM2 日志
pm2 logs dainiao --lines 100

# Nginx 日志
sudo tail -f /var/log/nginx/dainiao_access.log
sudo tail -f /var/log/nginx/dainiao_error.log

# 应用日志
tail -f /var/log/dainiao/out.log
tail -f /var/log/dainiao/error.log
```

### 2. 自动备份脚本

创建 `/home/scripts/backup.sh`:

```bash
#!/bin/bash

# 配置
BACKUP_DIR="/backup/dainiao"
DATE=$(date +%Y%m%d_%H%M%S)
DB_NAME="dainiao"
DB_USER="dainiao"
RETENTION_DAYS=7

# 创建备份目录
mkdir -p $BACKUP_DIR

# 备份数据库
pg_dump -U $DB_USER -h localhost $DB_NAME > $BACKUP_DIR/db_$DATE.sql

# 备份上传文件(如果有本地存储)
tar -czf $BACKUP_DIR/uploads_$DATE.tar.gz /var/www/dainiao/public/uploads

# 压缩数据库备份
gzip $BACKUP_DIR/db_$DATE.sql

# 删除旧备份(保留最近7天)
find $BACKUP_DIR -name "*.sql.gz" -mtime +$RETENTION_DAYS -delete
find $BACKUP_DIR -name "*.tar.gz" -mtime +$RETENTION_DAYS -delete

echo "备份完成: $DATE"
```

设置定时任务:

```bash
chmod +x /home/scripts/backup.sh

# 每天凌晨3点执行备份
sudo crontab -e
# 添加:
0 3 * * * /home/scripts/backup.sh >> /var/log/backup.log 2>&1
```

### 3. 监控服务

#### 方案1:使用 PM2 Plus(推荐)
```bash
pm2 link <your_public_key> <your_secret_key>
```

#### 方案2:使用监控工具(如 UptimeRobot)
- 免费监控服务可用性
- 配置邮件/短信告警

### 4. 性能优化

#### Nginx 缓存配置:

```nginx
# 在 http 块中添加
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=dainiao_cache:10m max_size=1g inactive=60m use_temp_path=off;

# 在 server 块中添加
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
    proxy_pass http://dainiao_backend;
    proxy_cache dainiao_cache;
    proxy_cache_valid 200 30d;
    proxy_cache_use_stale error timeout invalid_header updating;
    add_header X-Cache-Status $upstream_cache_status;
}
```

#### 数据库优化:

```sql
-- 创建索引
CREATE INDEX idx_users_invite_code ON users(invite_code);
CREATE INDEX idx_game_records_user_id ON game_records(user_id);
CREATE INDEX idx_daily_signs_user_id ON daily_signs(user_id);
```

### 5. 安全加固

```bash
# 禁止 root 远程登录
sudo vim /etc/ssh/sshd_config
# 修改:PermitRootLogin no

# 修改 SSH 端口
# Port 2222

# 重启 SSH
sudo systemctl restart sshd

# 安装 fail2ban 防止暴力破解
sudo apt install -y fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

# 定期更新系统
sudo apt update && sudo apt upgrade -y
```

---

## 迁移检查清单

### 部署前:
- [ ] 服务器已购买并配置完成
- [ ] 域名已购买并解析
- [ ] SSL 证书已申请
- [ ] 数据库已创建
- [ ] 对象存储已配置
- [ ] 环境变量已配置

### 部署后:
- [ ] 项目代码已部署
- [ ] PM2 服务正常运行
- [ ] Nginx 配置正确
- [ ] HTTPS 访问正常
- [ ] 数据库连接正常
- [ ] 用户注册/登录功能正常
- [ ] 游戏功能正常
- [ ] 日签功能正常
- [ ] 备份脚本已配置
- [ ] 监控已配置

### 支付接入(可选):
- [ ] 支付账号已申请
- [ ] API Keys 已配置
- [ ] Webhook 已配置
- [ ] 支付流程测试通过
- [ ] 退款流程已配置

---

## 常见问题

### Q1: PM2 启动失败怎么办?
```bash
# 查看详细错误
pm2 logs dainiao --err

# 检查端口占用
sudo lsof -i :3000

# 检查环境变量
pm2 env dainiao
```

### Q2: Nginx 502 错误?
```bash
# 检查后端服务状态
pm2 status

# 检查 Nginx 配置
sudo nginx -t

# 重启服务
pm2 restart dainiao
sudo systemctl restart nginx
```

### Q3: 数据库连接失败?
```bash
# 检查数据库服务
sudo systemctl status postgresql

# 测试连接
psql -U dainiao -d dainiao -h localhost

# 检查防火墙
sudo ufw status
```

### Q4: 如何升级项目?
```bash
cd /var/www/dainiao
git pull
pnpm install
pnpm build
pm2 restart dainiao
```

### Q5: 如何查看数据库大小?
```sql
SELECT pg_size_pretty(pg_database_size('dainiao'));
```

---

## 技术支持

如遇到问题,请提供以下信息:
1. 服务器配置(CPU、内存、操作系统)
2. 错误日志(PM2、Nginx、数据库)
3. 操作步骤
4. 预期结果和实际结果

---

## 附录:完整部署脚本

如需一键部署脚本,请联系技术团队获取定制化部署方案。

---

**祝您迁移顺利!**


收藏

扫描二维码,在手机上阅读
文章目录


    # 呆鸟修仙项目 - 支付接入可行性分析

    修复游戏崩溃问题:小鸟卡住、敌人未出现

    评 论
    评论已关闭