first commit

This commit is contained in:
CN-JS-HuiBai
2026-04-07 16:54:24 +08:00
commit 2c6a38c80d
399 changed files with 42205 additions and 0 deletions

View File

@@ -0,0 +1,176 @@
# Online Device Limit Design
## Overview
This document describes the design and implementation of the online device limit feature in Xboard.
## Design Goals
1. Accurate Control
- Precise counting of online devices
- Real-time monitoring of device status
- Accurate device identification
2. Performance Optimization
- Minimal impact on system performance
- Efficient device tracking
- Optimized resource usage
3. User Experience
- Smooth connection experience
- Clear error messages
- Graceful handling of limit exceeded cases
## Implementation Details
### 1. Device Identification
#### Device ID Generation
```php
public function generateDeviceId($user, $request) {
return md5(
$user->id .
$request->header('User-Agent') .
$request->ip()
);
}
```
#### Device Information Storage
```php
[
'device_id' => 'unique_device_hash',
'user_id' => 123,
'ip' => '192.168.1.1',
'user_agent' => 'Mozilla/5.0...',
'last_active' => '2024-03-21 10:00:00'
]
```
### 2. Connection Management
#### Connection Check
```php
public function checkDeviceLimit($user, $deviceId) {
$onlineDevices = $this->getOnlineDevices($user->id);
if (count($onlineDevices) >= $user->device_limit) {
if (!in_array($deviceId, $onlineDevices)) {
throw new DeviceLimitExceededException();
}
}
return true;
}
```
#### Device Status Update
```php
public function updateDeviceStatus($userId, $deviceId) {
Redis::hset(
"user:{$userId}:devices",
$deviceId,
json_encode([
'last_active' => now(),
'status' => 'online'
])
);
}
```
### 3. Cleanup Mechanism
#### Inactive Device Cleanup
```php
public function cleanupInactiveDevices() {
$inactiveThreshold = now()->subMinutes(30);
foreach ($this->getUsers() as $user) {
$devices = $this->getOnlineDevices($user->id);
foreach ($devices as $deviceId => $info) {
if ($info['last_active'] < $inactiveThreshold) {
$this->removeDevice($user->id, $deviceId);
}
}
}
}
```
## Error Handling
### Error Types
1. Device Limit Exceeded
```php
class DeviceLimitExceededException extends Exception {
protected $message = 'Device limit exceeded';
protected $code = 4001;
}
```
2. Invalid Device
```php
class InvalidDeviceException extends Exception {
protected $message = 'Invalid device';
protected $code = 4002;
}
```
### Error Messages
```php
return [
'device_limit_exceeded' => 'Maximum number of devices reached',
'invalid_device' => 'Device not recognized',
'device_expired' => 'Device session expired'
];
```
## Performance Considerations
1. Cache Strategy
- Use Redis for device tracking
- Implement cache expiration
- Optimize cache structure
2. Database Operations
- Minimize database queries
- Use batch operations
- Implement query optimization
3. Memory Management
- Efficient data structure
- Regular cleanup of expired data
- Memory usage monitoring
## Security Measures
1. Device Verification
- Validate device information
- Check for suspicious patterns
- Implement rate limiting
2. Data Protection
- Encrypt sensitive information
- Implement access control
- Regular security audits
## Future Improvements
1. Enhanced Features
- Device management interface
- Device activity history
- Custom device names
2. Performance Optimization
- Improved caching strategy
- Better cleanup mechanism
- Reduced memory usage
3. Security Enhancements
- Advanced device fingerprinting
- Fraud detection
- Improved encryption
## Conclusion
This design provides a robust and efficient solution for managing online device limits while maintaining good performance and user experience. Regular monitoring and updates will ensure the system remains effective and secure.

View File

@@ -0,0 +1,100 @@
# Performance Comparison Report
## Test Environment
### Hardware Configuration
- CPU: AMD EPYC 7K62 48-Core Processor
- Memory: 4GB
- Disk: NVMe SSD
- Network: 1Gbps
### Software Environment
- OS: Ubuntu 22.04 LTS
- PHP: 8.2
- MySQL: 5.7
- Redis: 7.0
- Docker: Latest stable version
## Test Scenarios
### 1. User Login Performance
- Concurrent users: 100
- Test duration: 60 seconds
- Request type: POST
- Target endpoint: `/api/v1/passport/auth/login`
Results:
- Average response time: 156ms
- 95th percentile: 245ms
- Maximum response time: 412ms
- Requests per second: 642
### 2. User Dashboard Loading
- Concurrent users: 100
- Test duration: 60 seconds
- Request type: GET
- Target endpoint: `/api/v1/user/dashboard`
Results:
- Average response time: 89ms
- 95th percentile: 167ms
- Maximum response time: 289ms
- Requests per second: 1121
### 3. Node List Query
- Concurrent users: 100
- Test duration: 60 seconds
- Request type: GET
- Target endpoint: `/api/v1/user/server/nodes`
Results:
- Average response time: 134ms
- 95th percentile: 223ms
- Maximum response time: 378ms
- Requests per second: 745
## Performance Optimization Measures
1. Database Optimization
- Added indexes for frequently queried fields
- Optimized slow queries
- Implemented query caching
2. Cache Strategy
- Using Redis for session storage
- Caching frequently accessed data
- Implementing cache warming
3. Code Optimization
- Reduced database queries
- Optimized database connection pool
- Improved error handling
## Comparison with Previous Version
| Metric | Previous Version | Current Version | Improvement |
|--------|-----------------|-----------------|-------------|
| Login Response | 289ms | 156ms | 46% |
| Dashboard Loading | 178ms | 89ms | 50% |
| Node List Query | 256ms | 134ms | 48% |
## Future Optimization Plans
1. Infrastructure Level
- Implement horizontal scaling
- Add load balancing
- Optimize network configuration
2. Application Level
- Further optimize database queries
- Implement more efficient caching strategies
- Reduce memory usage
3. Monitoring and Maintenance
- Add performance monitoring
- Implement automatic scaling
- Regular performance testing
## Conclusion
The current version shows significant performance improvements compared to the previous version, with an average improvement of 48% in response times. The optimization measures implemented have effectively enhanced the system's performance and stability.

View File

@@ -0,0 +1,691 @@
# XBoard Plugin Development Guide
## 📦 Plugin Structure
Each plugin is an independent directory with the following structure:
```
plugins/
└── YourPlugin/ # Plugin directory (PascalCase naming)
├── Plugin.php # Main plugin class (required)
├── config.json # Plugin configuration (required)
├── routes/
│ └── api.php # API routes
├── Controllers/ # Controllers directory
│ └── YourController.php
├── Commands/ # Artisan commands directory
│ └── YourCommand.php
└── README.md # Documentation
```
## 🚀 Quick Start
### 1. Create Configuration File `config.json`
```json
{
"name": "My Plugin",
"code": "my_plugin", // Corresponds to plugin directory (lowercase + underscore)
"version": "1.0.0",
"description": "Plugin functionality description",
"author": "Author Name",
"require": {
"xboard": ">=1.0.0" // Version not fully implemented yet
},
"config": {
"api_key": {
"type": "string",
"default": "",
"label": "API Key",
"description": "API Key"
},
"timeout": {
"type": "number",
"default": 300,
"label": "Timeout (seconds)",
"description": "Timeout in seconds"
}
}
}
```
### 2. Create Main Plugin Class `Plugin.php`
```php
<?php
namespace Plugin\YourPlugin;
use App\Services\Plugin\AbstractPlugin;
class Plugin extends AbstractPlugin
{
/**
* Called when plugin starts
*/
public function boot(): void
{
// Register frontend configuration hook
$this->filter('guest_comm_config', function ($config) {
$config['my_plugin_enable'] = true;
$config['my_plugin_setting'] = $this->getConfig('api_key', '');
return $config;
});
}
}
```
### 3. Create Controller
**Recommended approach: Extend PluginController**
```php
<?php
namespace Plugin\YourPlugin\Controllers;
use App\Http\Controllers\PluginController;
use Illuminate\Http\Request;
class YourController extends PluginController
{
public function handle(Request $request)
{
// Get plugin configuration
$apiKey = $this->getConfig('api_key');
$timeout = $this->getConfig('timeout', 300);
// Your business logic...
return $this->success(['message' => 'Success']);
}
}
```
### 4. Create Routes `routes/api.php`
```php
<?php
use Illuminate\Support\Facades\Route;
use Plugin\YourPlugin\Controllers\YourController;
Route::group([
'prefix' => 'api/v1/your-plugin'
], function () {
Route::post('/handle', [YourController::class, 'handle']);
});
```
## 🔧 Configuration Access
In controllers, you can easily access plugin configuration:
```php
// Get single configuration
$value = $this->getConfig('key', 'default_value');
// Get all configurations
$allConfig = $this->getConfig();
// Check if plugin is enabled
$enabled = $this->isPluginEnabled();
```
## 🎣 Hook System
### Popular Hooks (Recommended to follow)
XBoard has built-in hooks for many business-critical nodes. Plugin developers can flexibly extend through `filter` or `listen` methods. Here are the most commonly used and valuable hooks:
| Hook Name | Type | Typical Parameters | Description |
| ------------------------- | ------ | ----------------------- | ---------------- |
| user.register.before | action | Request | Before user registration |
| user.register.after | action | User | After user registration |
| user.login.after | action | User | After user login |
| user.password.reset.after | action | User | After password reset |
| order.cancel.before | action | Order | Before order cancellation |
| order.cancel.after | action | Order | After order cancellation |
| payment.notify.before | action | method, uuid, request | Before payment callback |
| payment.notify.verified | action | array | Payment callback verification successful |
| payment.notify.failed | action | method, uuid, request | Payment callback verification failed |
| traffic.reset.after | action | User | After traffic reset |
| ticket.create.after | action | Ticket | After ticket creation |
| ticket.reply.user.after | action | Ticket | After user replies to ticket |
| ticket.close.after | action | Ticket | After ticket closure |
> ⚡️ The hook system will continue to expand. Developers can always follow this documentation and the `php artisan hook:list` command to get the latest supported hooks.
### Filter Hooks
Used to modify data:
```php
// In Plugin.php boot() method
$this->filter('guest_comm_config', function ($config) {
// Add configuration for frontend
$config['my_setting'] = $this->getConfig('setting');
return $config;
});
```
### Action Hooks
Used to execute operations:
```php
$this->listen('user.created', function ($user) {
// Operations after user creation
$this->doSomething($user);
});
```
## 📝 Real Example: Telegram Login Plugin
Using TelegramLogin plugin as an example to demonstrate complete implementation:
**Main Plugin Class** (23 lines):
```php
<?php
namespace Plugin\TelegramLogin;
use App\Services\Plugin\AbstractPlugin;
class Plugin extends AbstractPlugin
{
public function boot(): void
{
$this->filter('guest_comm_config', function ($config) {
$config['telegram_login_enable'] = true;
$config['telegram_login_domain'] = $this->getConfig('domain', '');
$config['telegram_bot_username'] = $this->getConfig('bot_username', '');
return $config;
});
}
}
```
**Controller** (extends PluginController):
```php
class TelegramLoginController extends PluginController
{
public function telegramLogin(Request $request)
{
// Check plugin status
if ($error = $this->beforePluginAction()) {
return $error[1];
}
// Get configuration
$botToken = $this->getConfig('bot_token');
$timeout = $this->getConfig('auth_timeout', 300);
// Business logic...
return $this->success($result);
}
}
```
## ⏰ Plugin Scheduled Tasks (Scheduler)
Plugins can register their own scheduled tasks by implementing the `schedule(Schedule $schedule)` method in the main class.
**Example:**
```php
use Illuminate\Console\Scheduling\Schedule;
class Plugin extends AbstractPlugin
{
public function schedule(Schedule $schedule): void
{
// Execute every hour
$schedule->call(function () {
// Your scheduled task logic
\Log::info('Plugin scheduled task executed');
})->hourly();
}
}
```
- Just implement the `schedule()` method in Plugin.php.
- All plugin scheduled tasks will be automatically scheduled by the main program.
- Supports all Laravel scheduler usage.
## 🖥️ Plugin Artisan Commands
Plugins can automatically register Artisan commands by creating command classes in the `Commands/` directory.
### Command Directory Structure
```
plugins/YourPlugin/
├── Commands/
│ ├── TestCommand.php # Test command
│ ├── BackupCommand.php # Backup command
│ └── CleanupCommand.php # Cleanup command
```
### Create Command Class
**Example: TestCommand.php**
```php
<?php
namespace Plugin\YourPlugin\Commands;
use Illuminate\Console\Command;
class TestCommand extends Command
{
protected $signature = 'your-plugin:test {action=ping} {--message=Hello}';
protected $description = 'Test plugin functionality';
public function handle(): int
{
$action = $this->argument('action');
$message = $this->option('message');
try {
return match ($action) {
'ping' => $this->ping($message),
'info' => $this->showInfo(),
default => $this->showHelp()
};
} catch (\Exception $e) {
$this->error('Operation failed: ' . $e->getMessage());
return 1;
}
}
protected function ping(string $message): int
{
$this->info("{$message}");
return 0;
}
protected function showInfo(): int
{
$this->info('Plugin Information:');
$this->table(
['Property', 'Value'],
[
['Plugin Name', 'YourPlugin'],
['Version', '1.0.0'],
['Status', 'Enabled'],
]
);
return 0;
}
protected function showHelp(): int
{
$this->info('Usage:');
$this->line(' php artisan your-plugin:test ping --message="Hello" # Test');
$this->line(' php artisan your-plugin:test info # Show info');
return 0;
}
}
```
### Automatic Command Registration
- ✅ Automatically register all commands in `Commands/` directory when plugin is enabled
- ✅ Command namespace automatically set to `Plugin\YourPlugin\Commands`
- ✅ Supports all Laravel command features (arguments, options, interaction, etc.)
### Usage Examples
```bash
# Test command
php artisan your-plugin:test ping --message="Hello World"
# Show information
php artisan your-plugin:test info
# View help
php artisan your-plugin:test --help
```
### Best Practices
1. **Command Naming**: Use `plugin-name:action` format, e.g., `telegram:test`
2. **Error Handling**: Wrap main logic with try-catch
3. **Return Values**: Return 0 for success, 1 for failure
4. **User Friendly**: Provide clear help information and error messages
5. **Type Declarations**: Use PHP 8.2 type declarations
## 🛠️ Development Tools
### Controller Base Class Selection
**Method 1: Extend PluginController (Recommended)**
- Automatic configuration access: `$this->getConfig()`
- Automatic status checking: `$this->beforePluginAction()`
- Unified error handling
**Method 2: Use HasPluginConfig Trait**
```php
use App\Http\Controllers\Controller;
use App\Traits\HasPluginConfig;
class YourController extends Controller
{
use HasPluginConfig;
public function handle()
{
$config = $this->getConfig('key');
// ...
}
}
```
### Configuration Types
Supported configuration types:
- `string` - String
- `number` - Number
- `boolean` - Boolean
- `json` - Array
- `yaml`
## 🎯 Best Practices
### 1. Concise Main Class
- Plugin main class should be as concise as possible
- Mainly used for registering hooks and routes
- Complex logic should be placed in controllers or services
### 2. Configuration Management
- Define all configuration items in `config.json`
- Use `$this->getConfig()` to access configuration
- Provide default values for all configurations
### 3. Route Design
- Use semantic route prefixes
- Place API routes in `routes/api.php`
- Place Web routes in `routes/web.php`
### 4. Error Handling
```php
public function handle(Request $request)
{
// Check plugin status
if ($error = $this->beforePluginAction()) {
return $error[1];
}
try {
// Business logic
return $this->success($result);
} catch (\Exception $e) {
return $this->fail([500, $e->getMessage()]);
}
}
```
## 🔍 Debugging Tips
### 1. Logging
```php
\Log::info('Plugin operation', ['data' => $data]);
\Log::error('Plugin error', ['error' => $e->getMessage()]);
```
### 2. Configuration Checking
```php
// Check required configuration
if (!$this->getConfig('required_key')) {
return $this->fail([400, 'Missing configuration']);
}
```
### 3. Development Mode
```php
if (config('app.debug')) {
// Detailed debug information for development environment
}
```
## 📋 Plugin Lifecycle
1. **Installation**: Validate configuration, register to database
2. **Enable**: Load plugin, register hooks and routes
3. **Running**: Handle requests, execute business logic
## 🎉 Summary
Based on TelegramLogin plugin practical experience:
- **Simplicity**: Main class only 23 lines, focused on core functionality
- **Practicality**: Extends PluginController, convenient configuration access
- **Maintainability**: Clear directory structure, standard development patterns
- **Extensibility**: Hook-based architecture, easy to extend functionality
Following this guide, you can quickly develop plugins with complete functionality and concise code! 🚀
## 🖥️ Complete Plugin Artisan Commands Guide
### Feature Highlights
**Auto Registration**: Automatically register all commands in `Commands/` directory when plugin is enabled
**Namespace Isolation**: Each plugin's commands use independent namespaces
**Type Safety**: Support PHP 8.2 type declarations
**Error Handling**: Comprehensive exception handling and error messages
**Configuration Integration**: Commands can access plugin configuration
**Interaction Support**: Support user input and confirmation operations
### Real Case Demonstrations
#### 1. Telegram Plugin Commands
```bash
# Test Bot connection
php artisan telegram:test ping
# Send message
php artisan telegram:test send --message="Hello World"
# Get Bot information
php artisan telegram:test info
```
#### 2. TelegramExtra Plugin Commands
```bash
# Show all statistics
php artisan telegram-extra:stats all
# User statistics
php artisan telegram-extra:stats users
# JSON format output
php artisan telegram-extra:stats users --format=json
```
#### 3. Example Plugin Commands
```bash
# Basic usage
php artisan example:hello
# With arguments and options
php artisan example:hello Bear --message="Welcome!"
```
### Development Best Practices
#### 1. Command Naming Conventions
```php
// ✅ Recommended: Use plugin name as prefix
protected $signature = 'telegram:test {action}';
protected $signature = 'telegram-extra:stats {type}';
protected $signature = 'example:hello {name}';
// ❌ Avoid: Use generic names
protected $signature = 'test {action}';
protected $signature = 'stats {type}';
```
#### 2. Error Handling Pattern
```php
public function handle(): int
{
try {
// Main logic
return $this->executeAction();
} catch (\Exception $e) {
$this->error('Operation failed: ' . $e->getMessage());
return 1;
}
}
```
#### 3. User Interaction
```php
// Get user input
$chatId = $this->ask('Please enter chat ID');
// Confirm operation
if (!$this->confirm('Are you sure you want to execute this operation?')) {
$this->info('Operation cancelled');
return 0;
}
// Choose operation
$action = $this->choice('Choose operation', ['ping', 'send', 'info']);
```
#### 4. Configuration Access
```php
// Access plugin configuration in commands
protected function getConfig(string $key, $default = null): mixed
{
// Get plugin instance through PluginManager
$plugin = app(\App\Services\Plugin\PluginManager::class)
->getEnabledPlugins()['example_plugin'] ?? null;
return $plugin ? $plugin->getConfig($key, $default) : $default;
}
```
### Advanced Usage
#### 1. Multi-Command Plugins
```php
// One plugin can have multiple commands
plugins/YourPlugin/Commands/
├── BackupCommand.php # Backup command
├── CleanupCommand.php # Cleanup command
├── StatsCommand.php # Statistics command
└── TestCommand.php # Test command
```
#### 2. Inter-Command Communication
```php
// Share data between commands through cache or database
Cache::put('plugin:backup:progress', $progress, 3600);
$progress = Cache::get('plugin:backup:progress');
```
#### 3. Scheduled Task Integration
```php
// Call commands in plugin's schedule method
public function schedule(Schedule $schedule): void
{
$schedule->command('your-plugin:backup')->daily();
$schedule->command('your-plugin:cleanup')->weekly();
}
```
### Debugging Tips
#### 1. Command Testing
```bash
# View command help
php artisan your-plugin:command --help
# Verbose output
php artisan your-plugin:command --verbose
# Debug mode
php artisan your-plugin:command --debug
```
#### 2. Logging
```php
// Log in commands
Log::info('Plugin command executed', [
'command' => $this->signature,
'arguments' => $this->arguments(),
'options' => $this->options()
]);
```
#### 3. Performance Monitoring
```php
// Record command execution time
$startTime = microtime(true);
// ... execution logic
$endTime = microtime(true);
$this->info("Execution time: " . round(($endTime - $startTime) * 1000, 2) . "ms");
```
### Common Issues
#### Q: Commands not showing in list?
A: Check if plugin is enabled and ensure `Commands/` directory exists and contains valid command classes.
#### Q: Command execution failed?
A: Check if command class namespace is correct and ensure it extends `Illuminate\Console\Command`.
#### Q: How to access plugin configuration?
A: Get plugin instance through `PluginManager`, then call `getConfig()` method.
#### Q: Can commands call other commands?
A: Yes, use `Artisan::call()` method to call other commands.
```php
Artisan::call('other-plugin:command', ['arg' => 'value']);
```
### Summary
The plugin command system provides powerful extension capabilities for XBoard:
- 🚀 **Development Efficiency**: Quickly create management commands
- 🔧 **Operational Convenience**: Automate daily operations
- 📊 **Monitoring Capability**: Real-time system status viewing
- 🛠️ **Debug Support**: Convenient problem troubleshooting tools
By properly using plugin commands, you can greatly improve system maintainability and user experience! 🎉

View File

@@ -0,0 +1,210 @@
# Quick Deployment Guide for 1Panel
This guide explains how to deploy Xboard using 1Panel.
## 1. Environment Preparation
Install 1Panel:
```bash
curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && \
sudo bash quick_start.sh
```
## 2. Environment Configuration
1. Install from App Store:
- OpenResty (any version)
- ⚠️ Check "External Port Access" to open firewall
- MySQL 5.7 (Use MariaDB for ARM architecture)
2. Create Database:
- Database name: `xboard`
- Username: `xboard`
- Access rights: All hosts (%)
- Save the database password for installation
## 3. Deployment Steps
1. Add Website:
- Go to "Website" > "Create Website" > "Reverse Proxy"
- Domain: Enter your domain
- Code: `xboard`
- Proxy address: `127.0.0.1:7001`
2. Configure Reverse Proxy:
```nginx
location /ws/ {
proxy_pass http://127.0.0.1:8076;
proxy_http_version 1.1;
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_read_timeout 60s;
}
location ^~ / {
proxy_pass http://127.0.0.1:7001;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Real-PORT $remote_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header Scheme $scheme;
proxy_set_header Server-Protocol $server_protocol;
proxy_set_header Server-Name $server_name;
proxy_set_header Server-Addr $server_addr;
proxy_set_header Server-Port $server_port;
proxy_cache off;
}
```
> The `/ws/` location enables WebSocket real-time node synchronization via `ws-server`. This service is enabled by default and can be toggled in Admin Panel > System Settings > Server.
3. Install Xboard:
```bash
# Enter site directory
cd /opt/1panel/apps/openresty/openresty/www/sites/xboard/index
# Install Git (if not installed)
## Ubuntu/Debian
apt update && apt install -y git
## CentOS/RHEL
yum update && yum install -y git
# Clone repository
git clone -b compose --depth 1 https://github.com/cedar2025/Xboard ./
# Configure Docker Compose
```
4. Edit compose.yaml:
```yaml
services:
web:
image: ghcr.io/cedar2025/xboard:new
volumes:
- redis-data:/data
- ./.env:/www/.env
- ./.docker/.data/:/www/.docker/.data
- ./storage/logs:/www/storage/logs
- ./storage/theme:/www/storage/theme
- ./plugins:/www/plugins
environment:
- docker=true
depends_on:
- redis
command: php artisan octane:start --host=0.0.0.0 --port=7001
restart: on-failure
ports:
- 7001:7001
networks:
- 1panel-network
horizon:
image: ghcr.io/cedar2025/xboard:new
volumes:
- redis-data:/data
- ./.env:/www/.env
- ./.docker/.data/:/www/.docker/.data
- ./storage/logs:/www/storage/logs
- ./plugins:/www/plugins
restart: on-failure
command: php artisan horizon
networks:
- 1panel-network
depends_on:
- redis
ws-server:
image: ghcr.io/cedar2025/xboard:new
volumes:
- redis-data:/data
- ./.env:/www/.env
- ./.docker/.data/:/www/.docker/.data
- ./storage/logs:/www/storage/logs
- ./plugins:/www/plugins
restart: on-failure
ports:
- 8076:8076
networks:
- 1panel-network
command: php artisan ws-server start
depends_on:
- redis
redis:
image: redis:7-alpine
command: redis-server --unixsocket /data/redis.sock --unixsocketperm 777
restart: unless-stopped
networks:
- 1panel-network
volumes:
- redis-data:/data
volumes:
redis-data:
networks:
1panel-network:
external: true
```
5. Initialize Installation:
```bash
# Install dependencies and initialize
docker compose run -it --rm web php artisan xboard:install
```
⚠️ Important Configuration Notes:
1. Database Configuration
- Database Host: Choose based on your deployment:
1. If database and Xboard are in the same network, use `mysql`
2. If connection fails, go to: Database -> Select Database -> Connection Info -> Container Connection, and use the "Host" value
3. If using external database, enter your actual database host
- Database Port: `3306` (default port unless configured otherwise)
- Database Name: `xboard` (the database created earlier)
- Database User: `xboard` (the user created earlier)
- Database Password: Enter the password saved earlier
2. Redis Configuration
- Choose to use built-in Redis
- No additional configuration needed
3. Administrator Information
- Save the admin credentials displayed after installation
- Note down the admin panel access URL
After configuration, start the services:
```bash
docker compose up -d
```
6. Start Services:
```bash
docker compose up -d
```
## 4. Version Update
> 💡 Important Note: The update command varies depending on your installation version:
> - If you installed recently (new version), use this command:
```bash
docker compose pull && \
docker compose run -it --rm web php artisan xboard:update && \
docker compose up -d
```
> - If you installed earlier (old version), replace `web` with `xboard`:
```bash
docker compose pull && \
docker compose run -it --rm xboard php artisan xboard:update && \
docker compose up -d
```
> 🤔 Not sure which to use? Try the new version command first, if it fails, use the old version command.
## Important Notes
- ⚠️ Ensure firewall is enabled to prevent port 7001 exposure to public
- Service restart is required after code modifications
- SSL certificate configuration is recommended for secure access
> The node will automatically detect WebSocket availability during handshake. No extra configuration is needed on the node side.

View File

@@ -0,0 +1,151 @@
# Xboard Deployment Guide for aaPanel + Docker Environment
## Table of Contents
1. [Requirements](#requirements)
2. [Quick Deployment](#quick-deployment)
3. [Detailed Configuration](#detailed-configuration)
4. [Maintenance Guide](#maintenance-guide)
5. [Troubleshooting](#troubleshooting)
## Requirements
### Hardware Requirements
- CPU: 1 core or above
- Memory: 2GB or above
- Storage: 10GB+ available space
### Software Requirements
- Operating System: Ubuntu 20.04+ / CentOS 7+ / Debian 10+
- Latest version of aaPanel
- Docker and Docker Compose
- Nginx (any version)
- MySQL 5.7+
## Quick Deployment
### 1. Install aaPanel
```bash
curl -sSL https://www.aapanel.com/script/install_6.0_en.sh -o install_6.0_en.sh && \
bash install_6.0_en.sh aapanel
```
### 2. Basic Environment Setup
#### 2.1 Install Docker
```bash
# Install Docker
curl -sSL https://get.docker.com | bash
# For CentOS systems, also run:
systemctl enable docker
systemctl start docker
```
#### 2.2 Install Required Components
In the aaPanel dashboard, install:
- Nginx (any version)
- MySQL 5.7
- ⚠️ PHP and Redis are not required
### 3. Site Configuration
#### 3.1 Create Website
1. Navigate to: aaPanel > Website > Add site
2. Fill in the information:
- Domain: Enter your site domain
- Database: Select MySQL
- PHP Version: Select Pure Static
#### 3.2 Deploy Xboard
```bash
# Enter site directory
cd /www/wwwroot/your-domain
# Clean directory
chattr -i .user.ini
rm -rf .htaccess 404.html 502.html index.html .user.ini
# Clone repository
git clone https://github.com/cedar2025/Xboard.git ./
# Prepare configuration file
cp compose.sample.yaml compose.yaml
# Install dependencies and initialize
docker compose run -it --rm web sh init.sh
```
> ⚠️ Please save the admin dashboard URL, username, and password shown after installation
#### 3.3 Start Services
```bash
docker compose up -d
```
#### 3.4 Configure Reverse Proxy
Add the following content to your site configuration:
```nginx
location /ws/ {
proxy_pass http://127.0.0.1:8076;
proxy_http_version 1.1;
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_read_timeout 60s;
}
location ^~ / {
proxy_pass http://127.0.0.1:7001;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Real-PORT $remote_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header Scheme $scheme;
proxy_set_header Server-Protocol $server_protocol;
proxy_set_header Server-Name $server_name;
proxy_set_header Server-Addr $server_addr;
proxy_set_header Server-Port $server_port;
proxy_cache off;
}
```
> The `/ws/` location enables real-time node synchronization via `ws-server`. This service is enabled by default and can be toggled in Admin Panel > System Settings > Server.
## Maintenance Guide
### Version Updates
> 💡 Important Note: Update commands may vary depending on your installed version:
> - For recent installations (new version), use:
```bash
docker compose pull && \
docker compose run -it --rm web sh update.sh && \
docker compose up -d
```
> - For older installations, replace `web` with `xboard`:
```bash
git config --global --add safe.directory $(pwd)
git fetch --all && git reset --hard origin/master && git pull origin master
docker compose pull && \
docker compose run -it --rm xboard sh update.sh && \
docker compose up -d
```
> 🤔 Not sure which to use? Try the new version command first, if it fails, use the old version command.
### Routine Maintenance
- Regular log checking: `docker compose logs`
- Monitor system resource usage
- Regular backup of database and configuration files
## Troubleshooting
If you encounter any issues during installation or operation, please check:
1. **Empty Admin Dashboard**: If the admin panel is blank, run `git submodule update --init --recursive --force` to restore the theme files.
2. System requirements are met
3. All required ports are available
3. Docker services are running properly
4. Nginx configuration is correct
5. Check logs for detailed error messages
> The node will automatically detect WebSocket availability during handshake. No extra configuration is needed on the node side.

View File

@@ -0,0 +1,210 @@
# Xboard Deployment Guide for aaPanel Environment
## Table of Contents
1. [Requirements](#requirements)
2. [Quick Deployment](#quick-deployment)
3. [Detailed Configuration](#detailed-configuration)
4. [Maintenance Guide](#maintenance-guide)
5. [Troubleshooting](#troubleshooting)
## Requirements
### Hardware Requirements
- CPU: 1 core or above
- Memory: 2GB or above
- Storage: 10GB+ available space
### Software Requirements
- Operating System: Ubuntu 20.04+ / Debian 10+ (⚠️ CentOS 7 is not recommended)
- Latest version of aaPanel
- PHP 8.2
- MySQL 5.7+
- Redis
- Nginx (any version)
## Quick Deployment
### 1. Install aaPanel
```bash
URL=https://www.aapanel.com/script/install_6.0_en.sh && \
if [ -f /usr/bin/curl ];then curl -ksSO "$URL" ;else wget --no-check-certificate -O install_6.0_en.sh "$URL";fi && \
bash install_6.0_en.sh aapanel
```
### 2. Basic Environment Setup
#### 2.1 Install LNMP Environment
In the aaPanel dashboard, install:
- Nginx (any version)
- MySQL 5.7
- PHP 8.2
#### 2.2 Install PHP Extensions
Required PHP extensions:
- redis
- fileinfo
- swoole
- readline
- event
- mbstring
#### 2.3 Enable Required PHP Functions
Functions that need to be enabled:
- putenv
- proc_open
- pcntl_alarm
- pcntl_signal
### 3. Site Configuration
#### 3.1 Create Website
1. Navigate to: aaPanel > Website > Add site
2. Fill in the information:
- Domain: Enter your site domain
- Database: Select MySQL
- PHP Version: Select 8.2
#### 3.2 Deploy Xboard
```bash
# Enter site directory
cd /www/wwwroot/your-domain
# Clean directory
chattr -i .user.ini
rm -rf .htaccess 404.html 502.html index.html .user.ini
# Clone repository
git clone https://github.com/cedar2025/Xboard.git ./
# Install dependencies
sh init.sh
```
#### 3.3 Configure Site
1. Set running directory to `/public`
2. Add rewrite rules:
```nginx
location /downloads {
}
location / {
try_files $uri $uri/ /index.php$is_args$query_string;
}
location ~ .*\.(js|css)?$
{
expires 1h;
error_log off;
access_log /dev/null;
}
```
## Detailed Configuration
### 1. Configure Daemon Process
1. Install Supervisor
2. Add queue daemon process:
- Name: `Xboard`
- Run User: `www`
- Running Directory: Site directory
- Start Command: `php artisan horizon`
- Process Count: 1
### 2. Configure Scheduled Tasks
- Type: Shell Script
- Task Name: v2board
- Run User: www
- Frequency: 1 minute
- Script Content: `php /www/wwwroot/site-directory/artisan schedule:run`
### 3. Octane Configuration (Optional)
#### 3.1 Add Octane Daemon Process
- Name: Octane
- Run User: www
- Running Directory: Site directory
- Start Command: `/www/server/php/82/bin/php artisan octane:start --port 7010`
- Process Count: 1
#### 3.2 Octane-specific Rewrite Rules
```nginx
location ~* \.(jpg|jpeg|png|gif|js|css|svg|woff2|woff|ttf|eot|wasm|json|ico)$ {
}
location ~ .* {
proxy_pass http://127.0.0.1:7010;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Real-PORT $remote_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header Scheme $scheme;
proxy_set_header Server-Protocol $server_protocol;
proxy_set_header Server-Name $server_name;
proxy_set_header Server-Addr $server_addr;
proxy_set_header Server-Port $server_port;
}
```
## Maintenance Guide
### Version Updates
```bash
# Enter site directory
cd /www/wwwroot/your-domain
# Execute update script
git fetch --all && git reset --hard origin/master && git pull origin master
sh update.sh
# If Octane is enabled, restart the daemon process
# aaPanel > App Store > Tools > Supervisor > Restart Octane
```
### Routine Maintenance
- Regular log checking
- Monitor system resource usage
- Regular backup of database and configuration files
## Troubleshooting
### Common Issues
1. **Empty Admin Dashboard**: If the admin panel is blank, run `git submodule update --init --recursive --force` to restore the theme files.
2. Changes to admin path require service restart to take effect
3. Any code changes after enabling Octane require restart to take effect
3. When PHP extension installation fails, check if PHP version is correct
4. For database connection failures, check database configuration and permissions
## Enable WebSocket Real-time Sync (Optional)
WebSocket enables real-time synchronization of configurations and user changes to nodes.
### 1. Start WS Server
Add a WebSocket daemon process in aaPanel Supervisor:
- Name: `Xboard-WS`
- Run User: `www`
- Running Directory: Site directory
- Start Command: `php artisan ws-server start`
- Process Count: 1
### 2. Configure Nginx
Add the WebSocket location **before** the main `location ^~ /` block in your site's Nginx configuration:
```nginx
location /ws/ {
proxy_pass http://127.0.0.1:8076;
proxy_http_version 1.1;
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_read_timeout 60s;
}
```
### 3. Restart Services
Restart the Octane and WS Server processes in Supervisor.
> The node will automatically detect WebSocket availability during handshake. No extra configuration is needed on the node side.

View File

@@ -0,0 +1,77 @@
# Quick Deployment Guide with Docker Compose
This guide explains how to quickly deploy Xboard using Docker Compose. By default, it uses SQLite database, eliminating the need for a separate MySQL installation.
### 1. Environment Preparation
Install Docker:
```bash
curl -sSL https://get.docker.com | bash
# For CentOS systems, also run:
systemctl enable docker
systemctl start docker
```
### 2. Deployment Steps
1. Get project files:
```bash
git clone -b compose --depth 1 https://github.com/cedar2025/Xboard
cd Xboard
```
2. Install database:
- Quick installation (Recommended for beginners)
```bash
docker compose run -it --rm \
-e ENABLE_SQLITE=true \
-e ENABLE_REDIS=true \
-e ADMIN_ACCOUNT=admin@demo.com \
web php artisan xboard:install
```
- Custom configuration installation (Advanced users)
```bash
docker compose run -it --rm web php artisan xboard:install
```
> Please save the admin dashboard URL, username, and password shown after installation
3. Start services:
```bash
docker compose up -d
```
4. Access the site:
- Default port: 7001
- Website URL: http://your-server-ip:7001
### 3. Version Updates
> 💡 Important Note: Update commands may vary depending on your installed version:
> - For recent installations (new version), use:
```bash
cd Xboard
docker compose pull && \
docker compose run -it --rm web php artisan xboard:update && \
docker compose up -d
```
> - For older installations, replace `web` with `xboard`:
```bash
cd Xboard
docker compose pull && \
docker compose run -it --rm xboard php artisan xboard:update && \
docker compose up -d
```
> 🤔 Not sure which to use? Try the new version command first, if it fails, use the old version command.
### 4. Version Rollback
1. Modify the version number in `docker-compose.yaml` to the version you want to roll back to
2. Execute: `docker compose up -d`
### Important Notes
- If you need to use MySQL, please install it separately and redeploy
- Code changes require service restart to take effect
- You can configure Nginx reverse proxy to use port 80

View File

@@ -0,0 +1,54 @@
# Configuration Migration Guide
This guide explains how to migrate configuration files from v2board to Xboard. Xboard stores configurations in the database instead of files.
### 1. Docker Compose Environment
1. Prepare configuration file:
```bash
# Create config directory
mkdir config
# Copy old configuration file
cp old-project-path/config/v2board.php config/
```
2. Modify `docker-compose.yaml`, uncomment the following line:
```yaml
- ./config/v2board.php:/www/config/v2board.php
```
3. Execute migration:
```bash
docker compose run -it --rm web php artisan migrateFromV2b config
```
### 2. aaPanel Environment
1. Copy configuration file:
```bash
cp old-project-path/config/v2board.php config/v2board.php
```
2. Execute migration:
```bash
php artisan migrateFromV2b config
```
### 3. aaPanel + Docker Environment
1. Copy configuration file:
```bash
cp old-project-path/config/v2board.php config/v2board.php
```
2. Execute migration:
```bash
docker compose run -it --rm web php artisan migrateFromV2b config
```
### Important Notes
- After modifying the admin path, service restart is required:
- Docker environment: `docker compose restart`
- aaPanel environment: Restart the Octane daemon process

View File

@@ -0,0 +1,63 @@
# V2board 1.7.3 Migration Guide
This guide explains how to migrate from V2board version 1.7.3 to Xboard.
### 1. Database Changes Overview
- `v2_stat_order` table renamed to `v2_stat`:
- `order_amount``order_total`
- `commission_amount``commission_total`
- New fields added:
- `paid_count` (integer, nullable)
- `paid_total` (integer, nullable)
- `register_count` (integer, nullable)
- `invite_count` (integer, nullable)
- `transfer_used_total` (string(32), nullable)
- New tables added:
- `v2_log`
- `v2_server_hysteria`
- `v2_server_vless`
### 2. Prerequisites
⚠️ Please complete the basic Xboard installation first (SQLite not supported):
- [Docker Compose Deployment](../installation/docker-compose.md)
- [aaPanel + Docker Deployment](../installation/aapanel-docker.md)
- [aaPanel Deployment](../installation/aapanel.md)
### 3. Migration Steps
#### Docker Environment
```bash
# 1. Stop services
docker compose down
# 2. Clear database
docker compose run -it --rm web php artisan db:wipe
# 3. Import old database (Important)
# Please manually import the V2board 1.7.3 database
# 4. Execute migration
docker compose run -it --rm web php artisan migratefromv2b 1.7.3
```
#### aaPanel Environment
```bash
# 1. Clear database
php artisan db:wipe
# 2. Import old database (Important)
# Please manually import the V2board 1.7.3 database
# 3. Execute migration
php artisan migratefromv2b 1.7.3
```
### 4. Configuration Migration
After completing the data migration, you need to migrate the configuration file:
- [Configuration Migration Guide](./config.md)

View File

@@ -0,0 +1,51 @@
# V2board 1.7.4 Migration Guide
This guide explains how to migrate from V2board version 1.7.4 to Xboard.
### 1. Database Changes Overview
- New table added:
- `v2_server_vless`
### 2. Prerequisites
⚠️ Please complete the basic Xboard installation first (SQLite not supported):
- [Docker Compose Deployment](../installation/docker-compose.md)
- [aaPanel + Docker Deployment](../installation/aapanel-docker.md)
- [aaPanel Deployment](../installation/aapanel.md)
### 3. Migration Steps
#### Docker Environment
```bash
# 1. Stop services
docker compose down
# 2. Clear database
docker compose run -it --rm web php artisan db:wipe
# 3. Import old database (Important)
# Please manually import the V2board 1.7.4 database
# 4. Execute migration
docker compose run -it --rm web php artisan migratefromv2b 1.7.4
```
#### aaPanel Environment
```bash
# 1. Clear database
php artisan db:wipe
# 2. Import old database (Important)
# Please manually import the V2board 1.7.4 database
# 3. Execute migration
php artisan migratefromv2b 1.7.4
```
### 4. Configuration Migration
After completing the data migration, you need to migrate the configuration file:
- [Configuration Migration Guide](./config.md)

View File

@@ -0,0 +1,61 @@
# V2board Dev Migration Guide
This guide explains how to migrate from V2board Dev version (2023/10/27) to Xboard.
⚠️ Please upgrade to version 2023/10/27 following the official guide before proceeding with migration.
### 1. Database Changes Overview
- `v2_order` table:
- Added `surplus_order_ids` (text, nullable) - Deduction orders
- `v2_plan` table:
- Removed `daily_unit_price` - Affects period value
- Removed `transfer_unit_price` - Affects traffic value
- `v2_server_hysteria` table:
- Removed `ignore_client_bandwidth` - Affects bandwidth configuration
- Removed `obfs_type` - Affects obfuscation type configuration
### 2. Prerequisites
⚠️ Please complete the basic Xboard installation first (SQLite not supported):
- [Docker Compose Deployment](../installation/docker-compose.md)
- [aaPanel + Docker Deployment](../installation/aapanel-docker.md)
- [aaPanel Deployment](../installation/aapanel.md)
### 3. Migration Steps
#### Docker Environment
```bash
# 1. Stop services
docker compose down
# 2. Clear database
docker compose run -it --rm web php artisan db:wipe
# 3. Import old database (Important)
# Please manually import the V2board Dev database
# 4. Execute migration
docker compose run -it --rm web php artisan migratefromv2b dev231027
```
#### aaPanel Environment
```bash
# 1. Clear database
php artisan db:wipe
# 2. Import old database (Important)
# Please manually import the V2board Dev database
# 3. Execute migration
php artisan migratefromv2b dev231027
```
### 4. Configuration Migration
After completing the data migration, you need to migrate the configuration file:
- [Configuration Migration Guide](./config.md)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

BIN
Xboard/docs/images/user.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 489 KiB