Ember Moth e4996ade03 feat(migration): replace sqlx::migrate with standalone Go migrate tool
Schema is now managed by a separate Go CLI at tools/migrate/, which embeds
the SQL files copied from server/initialize/migrate/database/ and tracks
state in the shared schema_migrations table. Rust no longer owns migrations
at startup.

Rust startup:
  1. Connect to DB
  2. Probe for the `user` table (schema marker)
  3. If missing, fork-exec `ppanel-migrate up` to bring schema to v2131
  4. Create admin if not present
  5. Continue with redis/queue/scheduler

Verified:
  - Empty DB → ppanel-migrate applies all 39 migrations in ~0.4s, admin created
  - Go server's ppanel_go DB → schema detected, migrate skipped, clean start

Changes:
  - Add tools/migrate/ — Go module wrapping golang-migrate
    * migrate/migrate.go: Migrate() + RunUp() (RunUp bypasses the iofs vs
      os.ErrNotExist sentinel mismatch that breaks Up() on already-migrated DBs)
    * migrate/sql/{postgres,mysql}/: SQL files copied from server
    * cmd/migrate/main.go: CLI (up/down/version/force/drop)
  - Widen password column from varchar(100) → varchar(255) in
    00001_init_schema.up.sql to fit Rust's 112-char PBKDF2 hash
    (Rust uses 16-byte salt; Go's 8-byte salt fits in 100 but Rust's doesn't)
  - Rewrite src/migration.rs:
    * Remove sqlx::migrate!, run_migrations()
    * Add ensure_schema(db, cfg): probe + invoke ppanel-migrate subprocess
  - Fix src/db.rs::build_dsn: previously used cfg.config verbatim even when
    the default config string was for the wrong dialect (PG got MySQL's
    charset=utf8mb4 string and crashed on connect)
  - Delete old migrations/{postgres,mysql}/ (no longer used)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-06 02:11:10 +08:00
2026-07-05 20:47:34 +08:00
2026-07-05 22:35:53 +08:00
2026-07-05 22:37:44 +08:00

PPanel Backend (Rust)

License Rust Axum sqlx

PPanel 服务端的 Rust 重写版本 — 基于 Axum + sqlx,同时支持 MySQL / MariaDB 和 PostgreSQL。


📋 概述

ppanel-backendPPanel 服务端 (Go) 的 Rust 移植版本,使用 Axum 0.8 + sqlx 0.9 + Tokio 构建,与 Go 版本保持完整的 API 兼容性。

与 Go 版本的差异与改进

维度 Go 版 Rust 版
HTTP 框架 Hertz Axum 0.8
ORM GORM sqlx 0.9(编译期 SQL 检查)
异步运行时 goroutine Tokio
内存安全 GC 所有权系统,无 GC 暂停

核心特性

  • 多协议支持Shadowsocks、V2Ray、VLESS、Trojan、Hysteria2、TUIC 等
  • 双数据库后端MySQL / MariaDB 和 PostgreSQL 共用一套代码,运行时自动检测方言
  • 完整 API 兼容:与 Go 版本接口一一对应,可无缝替换
  • OpenTelemetry 可观测性stdout / OTLP gRPC / OTLP HTTP 链路追踪
  • Redis 限流:验证码发送间隔(60 秒)+ 每日上限(15 次)
  • Cloudflare Turnstile:登录 / 注册 / 重置密码三处人机验证
  • 异步任务队列:基于 asynq(Redis),兼容 Go 版任务类型键名
  • 定时调度器:订阅检查(60s)、流量重置(00:30)、流量统计(00:00)、汇率更新(01:00)

🚀 快速开始

前提条件

  • Rust 1.75+(推荐使用 rustup 安装)
  • MySQL 8.0+ / MariaDB 10.6+PostgreSQL 14+
  • Redis 6.0+
  • Git

从源码运行

# 1. 克隆仓库
git clone https://github.com/perfect-panel/ppanel-backend.git
cd ppanel-backend

# 2. 复制并编辑配置
cp config.example.yaml config.yaml
# 编辑 config.yaml,填写数据库、Redis、JWT 等配置

# 3. 编译并运行
cargo run --release

服务默认监听 0.0.0.0:8080/health 路由返回 ok

配置文件

配置文件路径默认为 config.yaml,可通过环境变量 PPANEL_CONFIG 覆盖:

PPANEL_CONFIG=/etc/ppanel/config.yaml cargo run --release

最小配置示例(MySQL):

Host: 0.0.0.0
Port: 8080
Model: prod          # prod | devdev 模式跳过 Turnstile 验证)

JwtAuth:
  AccessSecret: "your-secret-here"
  AccessExpire: 86400

Database:
  Driver: mysql
  Addr: "127.0.0.1:3306"
  Username: ppanel
  Password: your-password
  DBName: ppanel

Redis:
  Host: "127.0.0.1:6379"

Administrator:
  Email: admin@example.com
  Password: changeme

PostgreSQL 只需把 Driver 改为 postgresAddr 改为 PG 格式即可。


🗄 数据库迁移

启动时自动执行迁移,无需额外命令。

迁移文件位于:

  • migrations/mysql/ — MySQL / MariaDB
  • migrations/postgres/ — PostgreSQL

每个版本同时提供 *.sql(正向)和 *.down.sql(回滚)。

从 MySQL 迁移到 PostgreSQL

使用内置工具:

cargo build --release -p mysql2postgres
./target/release/mysql2postgres \
  --mysql  "user:pass@tcp(127.0.0.1:3306)/ppanel" \
  --postgres "postgres://user:pass@127.0.0.1/ppanel" \
  --dry-run   # 先预览,确认无误后去掉此参数

📁 目录结构

ppanel-backend/
├── crates/               # 独立库 crate
│   ├── email/            # 邮件发送
│   ├── ip/               # IP 地理位置
│   ├── jwt/              # JWT 签发 / 验证
│   ├── oauth/            # OAuth2Google / Apple / Telegram
│   ├── password/         # 密码哈希(PBKDF2 / bcrypt / MD5 / SHA-256
│   ├── payment/          # 支付平台(Alipay / ePay / Stripe
│   ├── result/           # HTTP 统一响应格式与错误码
│   ├── sms/              # 短信(阿里云 / Twilio / SmsBao / AboSend
│   └── turnstile/        # Cloudflare Turnstile 验证
├── migrations/           # 数据库迁移 SQL
│   ├── mysql/
│   └── postgres/
├── src/
│   ├── adapter/          # 代理协议适配器(生成订阅链接)
│   ├── config/           # 配置结构体
│   ├── handler/          # HTTP 路由与处理器
│   │   ├── admin/        # 管理员 API
│   │   ├── auth/         # 认证 API
│   │   ├── common/       # 公共 API
│   │   ├── notify/       # 支付回调
│   │   ├── public/       # 用户 API
│   │   └── server/       # 节点 API
│   ├── middleware/        # HTTP 中间件
│   ├── model/            # 数据模型(entity + DTO
│   ├── queue/            # 异步任务队列
│   ├── repository/       # 数据访问层(MySQL + PG 双实现)
│   ├── scheduler/        # 定时任务
│   ├── service/          # 业务逻辑
│   │   ├── admin/
│   │   ├── auth/
│   │   ├── common/
│   │   ├── public/
│   │   ├── server/
│   │   └── telegram/
│   ├── exchange_rate.rs  # 汇率换算工具
│   ├── tracing_otel.rs   # OpenTelemetry 初始化
│   └── main.rs
├── tools/
│   └── mysql2postgres/   # MySQL → PostgreSQL 数据迁移工具
├── Cargo.toml
└── config.example.yaml

🔗 API 兼容性

本版本与 Go 服务端 API 完全兼容,可直接对接:


🧪 开发

运行测试

cargo test

代码检查

cargo check
cargo clippy

构建发布版

cargo build --release
# 产物:./target/release/ppanel-backend

OpenTelemetry 链路追踪

在配置文件中添加:

Trace:
  Name: ppanel
  Batcher: stdout          # stdout | otlpgrpc | otlphttp
  Endpoint: ""             # 留空 + stdout 时输出到控制台
  Sampler: 1.0
  Disabled: false

🤝 贡献

欢迎 PR 和 Issue。移植工作参考 Go 原版 (../server)Rust 实现遵循 AGENTS.md 中记录的约定。

📄 许可证

本项目采用 Apache License 2.0 授权。

Star History

Star History Chart
S
Description
PPanel is a pure, professional, and perfect open-source proxy panel tool, designed to be your ideal choice for learning and practical use.
Readme Apache-2.0 19 MiB
Languages
Rust 88.5%
PLpgSQL 11%
Go 0.5%