docs: 重构文档结构,使用 zh/ 和 en/ 目录区分中英文文档

- 创建 docs/zh/ 和 docs/en/ 目录结构
- 将所有中文文档移动到 docs/zh/
- 创建主要文档的英文版本:
  - DEPLOYMENT.md (651行)
  - DEVELOPMENT.md (514行)
  - VERSION_MANAGEMENT.md (已有)
- 更新所有文档中的内部链接
- 更新 README.md 和 README_EN.md 中的文档链接
- 在文档中添加中英文版本互链
This commit is contained in:
WrBug
2025-12-07 18:01:11 +08:00
parent 62d13001cd
commit a222c9a52f
19 changed files with 1541 additions and 20 deletions
+652
View File
@@ -0,0 +1,652 @@
# PolyHermes Deployment Guide
> 📖 **中文版本**: [部署文档(中文)](../zh/DEPLOYMENT.md)
This document describes how to deploy the PolyHermes project, including different deployment methods for backend and frontend.
## Table of Contents
- [All-in-One Deployment (Recommended)](#all-in-one-deployment-recommended)
- [Using Docker Hub Images](#using-docker-hub-images-recommended-for-production)
- [Using External Nginx Reverse Proxy](#using-external-nginx-reverse-proxy-recommended-for-production)
- [Backend Deployment](#backend-deployment)
- [Java Direct Deployment](#java-direct-deployment)
- [Docker Deployment](#docker-deployment)
- [Frontend Deployment](#frontend-deployment)
- [Environment Configuration](#environment-configuration)
- [FAQ](#faq)
## All-in-One Deployment (Recommended)
Deploy both frontend and backend together in a single Docker container, using Nginx to serve frontend static files and proxy backend API.
### Prerequisites
- Docker 20.10+
- Docker Compose 2.0+
### Deployment Steps
1. **Using Docker Hub Images (Recommended, Production First Choice)**
Use officially built Docker images, no local build required, fast deployment.
**Method 1: Standalone Deployment (No code clone required, Recommended for Production)**
Suitable for production environments, no need to download project code, only configuration files needed for deployment.
```bash
# 1. Create deployment directory
mkdir polyhermes && cd polyhermes
# 2. Download production environment configuration files
# Download docker-compose.prod.yml and docker-compose.prod.env.example from GitHub
curl -O https://raw.githubusercontent.com/WrBug/PolyHermes/main/docker-compose.prod.yml
curl -O https://raw.githubusercontent.com/WrBug/PolyHermes/main/docker-compose.prod.env.example
# 3. Create configuration file
cp docker-compose.prod.env.example .env
# 4. Edit .env file, modify the following required configurations:
# - DB_PASSWORD: Database password (recommended to use strong password)
# - JWT_SECRET: JWT secret key (generate using openssl rand -hex 64)
# - ADMIN_RESET_PASSWORD_KEY: Admin password reset key (generate using openssl rand -hex 32)
#
# Example of generating random keys:
# openssl rand -hex 64 # For JWT_SECRET
# openssl rand -hex 32 # For ADMIN_RESET_PASSWORD_KEY
# 5. Start services
docker-compose -f docker-compose.prod.yml up -d
# 6. View logs
docker-compose -f docker-compose.prod.yml logs -f
# 7. Stop services
docker-compose -f docker-compose.prod.yml down
```
**Method 2: Using Deployment Script (Requires code clone)**
```bash
# If you have already cloned the code
./deploy.sh --use-docker-hub
```
**Method 3: Modify Existing docker-compose.yml**
```bash
# 1. Modify docker-compose.yml
# Uncomment: image: wrbug/polyhermes:latest
# Comment out build section
# 2. Create .env file (see environment configuration below)
# 3. Start services
docker-compose up -d
```
**Advantages**:
- ✅ No local build required, fast deployment
- ✅ No code clone required, only configuration files needed for deployment
- ✅ Uses officially built images with correct version numbers
- ✅ Supports multiple architectures (amd64, arm64), automatically selects matching architecture
- ✅ Recommended for production environments
**Pull Specific Version**:
```bash
# Modify image tag in docker-compose.prod.yml
# image: wrbug/polyhermes:v1.0.0
# Or use environment variable
export IMAGE_TAG=v1.0.0
# In docker-compose.prod.yml use: image: wrbug/polyhermes:${IMAGE_TAG:-latest}
```
2. **Local Build Deployment (Development Environment)**
Suitable for development environments or scenarios requiring custom builds.
```bash
# Use deployment script
./deploy.sh
```
The script will automatically:
- Check Docker environment
- Create `.env` configuration file (if it doesn't exist)
- Build Docker image (including frontend and backend)
- Start services (application + MySQL)
**Note**: Locally built version numbers will display as `dev`.
3. **Manual Deployment**
```bash
# Create .env file
cat > .env <<EOF
DB_URL=jdbc:mysql://mysql:3306/polyhermes?useSSL=false&serverTimezone=UTC&characterEncoding=utf8&allowPublicKeyRetrieval=true
DB_USERNAME=root
DB_PASSWORD=your_password_here
SPRING_PROFILES_ACTIVE=prod
SERVER_PORT=80
POLYGON_RPC_URL=https://polygon-rpc.com
JWT_SECRET=your-jwt-secret-key-change-in-production
ADMIN_RESET_PASSWORD_KEY=your-admin-reset-key-change-in-production
EOF
# Build and start
docker-compose build
docker-compose up -d
# View logs
docker-compose logs -f
# Stop services
docker-compose down
```
4. **Access Application**
- Frontend and backend unified access: `http://localhost:80`
- Nginx automatically handles:
- `/api/*` → Backend API (`localhost:8000`)
- `/ws` → Backend WebSocket (`localhost:8000`)
- Other paths → Frontend static files
### Architecture Description
```
User Request
Nginx (Port 80)
├─ /api/* → Backend Service (localhost:8000)
├─ /ws → Backend WebSocket (localhost:8000)
└─ /* → Frontend Static Files (/usr/share/nginx/html)
```
### Advantages
- ✅ Single container, simplified deployment
- ✅ Unified port, no CORS configuration needed
- ✅ Automatic handling of frontend and backend routing
- ✅ Production ready
### Using External Nginx Reverse Proxy (Recommended for Production)
In production environments, it is recommended to deploy Nginx as a reverse proxy outside the Docker container for:
- **SSL/TLS Termination**: Handle HTTPS requests
- **Domain Binding**: Bind custom domain names
- **Load Balancing**: Support multiple backend instances
- **More Flexible Configuration**: More granular control
**Deployment Architecture**:
```
User Request (HTTPS)
External Nginx (443) - SSL Termination
Docker Container (80) - Internal Nginx + Backend
├─ /api/* → Backend Service (localhost:8000)
├─ /ws → Backend WebSocket (localhost:8000)
└─ /* → Frontend Static Files
```
**Deployment Steps**:
1. **Deploy Docker Container**
```bash
# Deploy using docker-compose.prod.yml
docker-compose -f docker-compose.prod.yml up -d
```
2. **Configure External Nginx**
```bash
# 1. Download Nginx configuration example
curl -O https://raw.githubusercontent.com/WrBug/PolyHermes/main/docs/zh/nginx-reverse-proxy.conf
# 2. Copy to Nginx configuration directory
sudo cp nginx-reverse-proxy.conf /etc/nginx/sites-available/polyhermes
# 3. Edit configuration file, modify domain name and SSL certificate paths
sudo nano /etc/nginx/sites-available/polyhermes
# Modify the following:
# - server_name: Change to your domain name
# - ssl_certificate: SSL certificate path
# - ssl_certificate_key: SSL private key path
# - upstream server: If Docker container port is not 80, need to modify
# 4. Create symbolic link
sudo ln -s /etc/nginx/sites-available/polyhermes /etc/nginx/sites-enabled/
# 5. Test configuration
sudo nginx -t
# 6. Reload configuration
sudo systemctl reload nginx
```
3. **Configure SSL Certificate (Using Let's Encrypt)**
```bash
# Install Certbot
sudo apt-get update
sudo apt-get install certbot python3-certbot-nginx
# Get SSL certificate
sudo certbot --nginx -d your-domain.com -d www.your-domain.com
# Certificate will be automatically configured to Nginx and set up auto-renewal
```
4. **Modify Docker Port Mapping (Optional)**
If using external Nginx, you can change Docker container port to internal port, not exposed externally:
```yaml
# In docker-compose.prod.yml
ports:
- "127.0.0.1:80:80" # Only bind to localhost, not exposed externally
```
**Nginx Configuration Description**:
- Configuration file location: `docs/zh/nginx-reverse-proxy.conf`
- Supports HTTPS (SSL/TLS)
- Supports WebSocket proxy
- Includes security headers
- Supports load balancing (can configure multiple backends)
For detailed configuration examples, please refer to: [Nginx Reverse Proxy Configuration](../zh/nginx-reverse-proxy.conf)
## Backend Deployment
### Java Direct Deployment
#### Prerequisites
- JDK 17+
- MySQL 8.0+
- Gradle 7.5+ (or use Gradle Wrapper)
#### Deployment Steps
1. **Build Application**
```bash
cd backend
./gradlew clean bootJar
```
Build artifact located at `build/libs/polyhermes-backend-1.0.0.jar`
2. **Use Deployment Script (Recommended)**
```bash
# Build and create deployment files
./deploy.sh java
# Or build only
./deploy.sh build
```
The script will automatically:
- Check Java environment
- Build application
- Create deployment directory and startup script
- Generate systemd service file (optional)
3. **Manual Start**
```bash
# Development environment
java -jar build/libs/polyhermes-backend-1.0.0.jar --spring.profiles.active=dev
# Production environment
java -jar build/libs/polyhermes-backend-1.0.0.jar --spring.profiles.active=prod
```
4. **Use systemd Management (Linux)**
```bash
# Copy service file
sudo cp deploy/polyhermes-backend.service /etc/systemd/system/
# Edit service file, modify path and user
sudo nano /etc/systemd/system/polyhermes-backend.service
# Start service
sudo systemctl daemon-reload
sudo systemctl enable polyhermes-backend
sudo systemctl start polyhermes-backend
# View logs
sudo journalctl -u polyhermes-backend -f
```
### Docker Deployment
#### Prerequisites
- Docker 20.10+
- Docker Compose 2.0+
#### Deployment Steps
1. **Use Deployment Script (Recommended)**
```bash
cd backend
./deploy.sh docker
```
The script will automatically:
- Check Docker environment
- Create `.env` configuration file (if it doesn't exist)
- Build Docker image
- Start service
2. **Manual Deployment**
```bash
# Create .env file
cat > .env <<EOF
DB_URL=jdbc:mysql://mysql:3306/polyhermes?useSSL=false&serverTimezone=UTC&characterEncoding=utf8&allowPublicKeyRetrieval=true
DB_USERNAME=root
DB_PASSWORD=your_password_here
SPRING_PROFILES_ACTIVE=prod
SERVER_PORT=8000
POLYGON_RPC_URL=https://polygon-rpc.com
JWT_SECRET=your-jwt-secret-key-change-in-production
ADMIN_RESET_PASSWORD_KEY=your-admin-reset-key-change-in-production
EOF
# Build and start
docker-compose up -d
# View logs
docker-compose logs -f
# Stop service
docker-compose down
```
3. **Build Image Only**
```bash
docker build -t polyhermes-backend:latest .
```
4. **Run Container**
```bash
docker run -d \
--name polyhermes-backend \
-p 8000:8000 \
-e SPRING_PROFILES_ACTIVE=prod \
-e DB_URL=jdbc:mysql://host.docker.internal:3306/polyhermes?useSSL=false&allowPublicKeyRetrieval=true \
-e DB_USERNAME=root \
-e DB_PASSWORD=your_password \
-e JWT_SECRET=your-jwt-secret \
polyhermes-backend:latest
```
## Frontend Deployment
### Build Steps
1. **Use Build Script (Recommended)**
```bash
cd frontend
# Use default backend address (http://127.0.0.1:8000)
./build.sh
# Or specify custom backend address
./build.sh --api-url http://your-backend-server.com:8000
# Or use environment variable
VITE_API_URL=http://your-backend-server.com:8000 ./build.sh
```
2. **Manual Build**
```bash
cd frontend
# Create environment configuration file
cat > .env.production <<EOF
VITE_API_URL=http://your-backend-server.com:8000
VITE_WS_URL=ws://your-backend-server.com:8000
EOF
# Install dependencies (first time)
npm install
# Build
npm run build
```
Build artifact located in `dist/` directory.
### Deployment Methods
#### Method 1: Nginx Deployment
```nginx
server {
listen 80;
server_name your-domain.com;
root /path/to/frontend/dist;
index index.html;
# API proxy
location /api {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# WebSocket proxy
location /ws {
proxy_pass http://localhost:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
# Frontend routing (SPA)
location / {
try_files $uri $uri/ /index.html;
}
}
```
#### Method 2: Apache Deployment
```apache
<VirtualHost *:80>
ServerName your-domain.com
DocumentRoot /path/to/frontend/dist
# API proxy
ProxyPass /api http://localhost:8000/api
ProxyPassReverse /api http://localhost:8000/api
# WebSocket proxy
ProxyPass /ws ws://localhost:8000/ws
ProxyPassReverse /ws ws://localhost:8000/ws
# Frontend routing (SPA)
<Directory /path/to/frontend/dist>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</Directory>
</VirtualHost>
```
#### Method 3: Using serve (Development/Testing)
```bash
# Install serve
npm install -g serve
# Start service
serve -s dist -l 3000
```
## Environment Configuration
### Backend Environment Variables
| Variable Name | Description | Default Value | Required |
|---------------|-------------|---------------|----------|
| `SPRING_PROFILES_ACTIVE` | Spring Profile | `dev` | No |
| `DB_URL` | Database connection URL | - | Yes (Production) |
| `DB_USERNAME` | Database username | `root` | Yes (Production) |
| `DB_PASSWORD` | Database password | - | Yes (Production) |
| `SERVER_PORT` | Server port | `8000` | No |
| `POLYGON_RPC_URL` | Polygon RPC address | `https://polygon-rpc.com` | No |
| `JWT_SECRET` | JWT secret key | - | Yes (Production) |
| `ADMIN_RESET_PASSWORD_KEY` | Admin password reset key | - | Yes (Production) |
### Frontend Environment Variables
| Variable Name | Description | Default Value |
|---------------|-------------|---------------|
| `VITE_API_URL` | Backend API address | `http://127.0.0.1:8000` |
| `VITE_WS_URL` | WebSocket address | `ws://127.0.0.1:8000` |
### Configuration File Description
#### Backend Configuration Files
- `application.properties` - Base configuration (shared by all environments)
- `application-dev.properties` - Development environment configuration
- `application-prod.properties` - Production environment configuration
Switch environments via `--spring.profiles.active=prod` or environment variable `SPRING_PROFILES_ACTIVE=prod`.
#### Frontend Environment Variables
Vite uses `.env.production` file to inject environment variables during build. The build script will automatically create this file.
## FAQ
### 1. Database Connection Failed
**Problem**: Backend cannot connect to database
**Solution**:
- Check if database service is running
- Check if database connection URL, username, password are correct
- Check if firewall allows connection
- For Docker deployment, ensure using correct database address (`mysql` instead of `localhost`)
### 2. Frontend Cannot Connect to Backend
**Problem**: Frontend requests to backend API fail
**Solution**:
- Check if backend service is running
- Check if `VITE_API_URL` configuration is correct
- Check CORS configuration (if cross-origin)
- Check network connection and firewall
### 3. WebSocket Connection Failed
**Problem**: WebSocket cannot establish connection
**Solution**:
- Check if `VITE_WS_URL` configuration is correct
- Check WebSocket proxy configuration (Nginx/Apache)
- Check if firewall allows WebSocket connection
- Check if backend WebSocket service is normal
### 4. Docker Container Cannot Access Database
**Problem**: Backend in Docker container cannot connect to host database
**Solution**:
- Use `host.docker.internal` as database address (Mac/Windows)
- Use Docker network connection (recommended to use docker-compose)
- Check if database allows remote connection
### 5. Build Failed
**Problem**: Frontend or backend build fails
**Solution**:
- Check Node.js version (requires 18+)
- Check Java version (requires 17+)
- Clean cache and rebuild:
```bash
# Frontend
rm -rf node_modules dist
npm install
npm run build
# Backend
./gradlew clean build
```
## Production Environment Checklist
- [ ] Modify all default passwords and keys (JWT_SECRET, ADMIN_RESET_PASSWORD_KEY, database password)
- [ ] Configure correct database connection (use SSL)
- [ ] Set correct Spring Profile (`prod`)
- [ ] Configure correct backend API address (frontend)
- [ ] Configure reverse proxy (Nginx/Apache)
- [ ] Configure HTTPS (recommended for production)
- [ ] Configure firewall rules
- [ ] Set up log rotation
- [ ] Configure monitoring and alerts
- [ ] Regular database backups
## Performance Optimization Recommendations
### Backend
- Adjust JVM parameters (heap memory, GC strategy)
- Configure database connection pool size
- Enable HTTP compression
- Configure caching strategy
### Frontend
- Enable Gzip compression (Nginx)
- Configure static resource caching
- Use CDN acceleration
- Enable HTTP/2
## Security Recommendations
- Use HTTPS (required for production)
- Configure CORS whitelist
- Regularly update dependencies
- Use strong passwords and keys
- Limit database access permissions
- Configure firewall rules
- Regular data backups
- Monitor abnormal access
## Technical Support
If you have any questions, please submit an Issue to [GitHub](https://github.com/WrBug/PolyHermes) or contact [Twitter](https://x.com/quant_tr).
+520
View File
@@ -0,0 +1,520 @@
# PolyHermes Development Guide
> 📖 **中文版本**: [开发文档(中文)](../zh/DEVELOPMENT.md)
This document describes the development guide for the PolyHermes project, including project structure, development environment setup, code standards, API interfaces, etc.
## 📋 Table of Contents
- [Project Structure](#project-structure)
- [Development Environment Setup](#development-environment-setup)
- [Code Standards](#code-standards)
- [API Documentation](#api-documentation)
- [Database Design](#database-design)
- [Frontend Development Guide](#frontend-development-guide)
- [Backend Development Guide](#backend-development-guide)
- [FAQ](#faq)
## 📦 Project Structure
```
polyhermes/
├── backend/ # Backend service
│ ├── src/main/kotlin/
│ │ └── com/wrbug/polymarketbot/
│ │ ├── api/ # API interface definitions (Retrofit)
│ │ ├── config/ # Configuration classes
│ │ ├── controller/ # REST controllers
│ │ ├── dto/ # Data Transfer Objects
│ │ ├── entity/ # Database entities
│ │ ├── repository/ # Data access layer
│ │ ├── service/ # Business logic services
│ │ ├── util/ # Utility classes
│ │ └── websocket/ # WebSocket handling
│ └── src/main/resources/
│ ├── application.properties
│ └── db/migration/ # Flyway database migration scripts
├── frontend/ # Frontend application
│ ├── src/
│ │ ├── components/ # Common components
│ │ ├── pages/ # Page components
│ │ ├── services/ # API services
│ │ ├── store/ # State management (Zustand)
│ │ ├── types/ # TypeScript type definitions
│ │ ├── utils/ # Utility functions
│ │ ├── hooks/ # React Hooks
│ │ ├── locales/ # Internationalization resources
│ │ └── styles/ # Style files
│ └── public/ # Static resources
├── docs/ # Documentation
│ ├── zh/ # Chinese documentation
│ │ ├── DEPLOYMENT.md # Deployment documentation
│ │ ├── VERSION_MANAGEMENT.md # Version management documentation
│ │ └── ...
│ ├── en/ # English documentation
│ │ ├── DEPLOYMENT.md # Deployment documentation
│ │ ├── VERSION_MANAGEMENT.md # Version management documentation
│ │ └── ...
│ └── copy-trading-requirements.md # Copy trading system requirements
├── .github/workflows/ # GitHub Actions workflows
└── README.md # Project description
```
## 🛠️ Development Environment Setup
### Prerequisites
- **JDK**: 17+
- **Node.js**: 18+
- **MySQL**: 8.0+
- **Gradle**: 7.5+ (or use Gradle Wrapper)
- **Docker**: 20.10+ (optional, for containerized deployment)
### Backend Development Environment
1. **Clone Repository**
```bash
git clone https://github.com/WrBug/PolyHermes.git
cd PolyHermes
```
2. **Configure Database**
Create MySQL database:
```sql
CREATE DATABASE polyhermes CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
```
3. **Configure Environment Variables**
Edit `backend/src/main/resources/application.properties` or use environment variables:
```properties
# Database configuration
spring.datasource.url=jdbc:mysql://localhost:3306/polyhermes?useSSL=false&serverTimezone=UTC&characterEncoding=utf8mb4
spring.datasource.username=${DB_USERNAME:root}
spring.datasource.password=${DB_PASSWORD:password}
# Server port
server.port=${SERVER_PORT:8000}
# Polygon RPC
polygon.rpc.url=${POLYGON_RPC_URL:https://polygon-rpc.com}
# JWT secret
jwt.secret=${JWT_SECRET:change-me-in-production}
# Encryption key (for encrypting stored private keys and API Keys)
crypto.secret.key=${CRYPTO_SECRET_KEY:change-me-in-production}
```
4. **Start Backend Service**
```bash
cd backend
./gradlew bootRun
```
Backend service will start at `http://localhost:8000`.
### Frontend Development Environment
1. **Install Dependencies**
```bash
cd frontend
npm install
```
2. **Configure Environment Variables (Optional)**
Create `.env` file:
```env
VITE_API_URL=http://localhost:8000
VITE_WS_URL=ws://localhost:8000
```
3. **Start Development Server**
```bash
npm run dev
```
Frontend application will start at `http://localhost:3000`.
## 📝 Code Standards
### Backend Development Standards
For detailed standards, please refer to: [Backend Development Standards](.cursor/rules/backend.mdc)
**Core Standards**:
- Follow Kotlin coding standards
- Controller methods **must not** use `suspend`
- Entity ID fields use `Long? = null`
- All time fields use `Long` timestamps (milliseconds)
- Use `BigDecimal` for numerical calculations
- Use `ErrorCode` enum to define error codes and messages
- **Do not** add TODO comments in code
- **Do not** directly return mock data
### Frontend Development Standards
For detailed standards, please refer to: [Frontend Development Standards](.cursor/rules/frontend.mdc)
**Core Standards**:
- Use TypeScript type definitions
- Use functional components and Hooks
- **Do not** use `any` type
- **Must** use internationalization (i18n) for all text display
- **Must** use `formatUSDC` function to format USDC amounts
- **Must** support mobile and desktop
- **Do not** add TODO comments in code
### Commit Standards
Follow [Conventional Commits](https://www.conventionalcommits.org/) standards:
- `feat`: New feature
- `fix`: Bug fix
- `docs`: Documentation update
- `style`: Code style adjustment
- `refactor`: Code refactoring
- `test`: Test related
- `chore`: Build/tool related
Examples:
```bash
git commit -m "feat: Add version number display feature"
git commit -m "fix: Fix order status update issue"
```
## 📡 API Documentation
### Unified Response Format
All API interfaces use POST method uniformly, response format as follows:
```json
{
"code": 0,
"data": {},
"msg": ""
}
```
- `code`: Response code, 0 means success, non-0 means failure
- `data`: Response data, can be any type
- `msg`: Response message, usually empty on success, contains error message on failure
### Error Code Standards
- `0`: Success
- `1001-1999`: Parameter error
- `2001-2999`: Authentication/permission error
- `3001-3999`: Resource not found
- `4001-4999`: Business logic error
- `5001-5999`: Server internal error
### Main API Interfaces
#### Account Management
- `POST /api/accounts/list` - Get account list
- `POST /api/accounts/import` - Import account (via private key)
- `POST /api/accounts/detail` - Get account details
- `POST /api/accounts/edit` - Edit account
- `POST /api/accounts/delete` - Delete account
- `POST /api/accounts/balance` - Get account balance
#### Leader Management
- `POST /api/leaders/list` - Get Leader list
- `POST /api/leaders/add` - Add Leader
- `POST /api/leaders/edit` - Edit Leader
- `POST /api/leaders/delete` - Delete Leader
#### Copy Trading Templates
- `POST /api/templates/list` - Get template list
- `POST /api/templates/add` - Add template
- `POST /api/templates/edit` - Edit template
- `POST /api/templates/delete` - Delete template
#### Copy Trading Configuration
- `POST /api/copy-trading/list` - Get copy trading configuration list
- `POST /api/copy-trading/add` - Add copy trading configuration
- `POST /api/copy-trading/edit` - Edit copy trading configuration
- `POST /api/copy-trading/delete` - Delete copy trading configuration
- `POST /api/copy-trading/enable` - Enable copy trading
- `POST /api/copy-trading/disable` - Disable copy trading
#### Order Management
- `POST /api/copy-trading/orders/buy` - Get buy order list
- `POST /api/copy-trading/orders/sell` - Get sell order list
- `POST /api/copy-trading/orders/matched` - Get matched order list
#### Statistical Analysis
- `POST /api/statistics/global` - Get global statistics
- `POST /api/statistics/leader` - Get Leader statistics
- `POST /api/statistics/category` - Get category statistics
- `POST /api/copy-trading/statistics` - Get copy trading relationship statistics
#### Position Management
- `POST /api/positions/list` - Get position list
- `POST /api/positions/sell` - Sell position
- `POST /api/positions/redeem` - Redeem position
#### System Management
- `POST /api/system-settings/proxy` - Configure proxy
- `POST /api/system-settings/api-health` - Get API health status
- `POST /api/users/list` - Get user list
- `POST /api/users/add` - Add user
- `POST /api/users/edit` - Edit user
- `POST /api/users/delete` - Delete user
For detailed API interface documentation, please refer to: [Copy Trading System Requirements](../zh/copy-trading-requirements.md)
## 🗄️ Database Design
### Main Data Tables
- `accounts` - Account table
- `leaders` - Leader table
- `templates` - Copy trading template table
- `copy_trading` - Copy trading configuration table
- `copy_orders` - Copy trading order table
- `positions` - Position table
- `users` - User table
- `system_settings` - System settings table
Database migration scripts are located at `backend/src/main/resources/db/migration/`, managed using Flyway.
## 🎨 Frontend Development Guide
### Project Structure
```
frontend/src/
├── components/ # Common components
│ ├── Layout.tsx # Layout component (supports mobile)
│ └── Logo.tsx # Logo component
├── pages/ # Page components
│ ├── AccountList.tsx
│ ├── LeaderList.tsx
│ ├── CopyTradingList.tsx
│ └── ...
├── services/ # API services
│ ├── api.ts # API service definitions
│ └── websocket.ts # WebSocket service
├── store/ # State management (Zustand)
├── types/ # TypeScript type definitions
├── utils/ # Utility functions
│ ├── index.ts # Unified export
│ ├── ethers.ts # Ethereum related utilities
│ ├── auth.ts # Authentication related utilities
│ └── version.ts # Version number utilities
├── hooks/ # React Hooks
├── locales/ # Internationalization resources
│ ├── zh-CN/
│ ├── zh-TW/
│ └── en/
└── styles/ # Style files
```
### Internationalization Support
The project supports multiple languages (Simplified Chinese, Traditional Chinese, English), using `react-i18next`.
**Adding New Translations**:
1. Add translations in `src/locales/{locale}/common.json`
2. Use `useTranslation` Hook in components:
```typescript
import { useTranslation } from 'react-i18next'
const MyComponent: React.FC = () => {
const { t } = useTranslation()
return <div>{t('key')}</div>
}
```
### Mobile Adaptation
- Use `react-responsive` to detect device type
- Breakpoint settings: Mobile < 768px, Desktop >= 768px
- Use responsive layouts and components
### Utility Functions
**USDC Amount Formatting**:
```typescript
import { formatUSDC } from '../utils'
const balance = formatUSDC('1.23456') // "1.2345"
```
**Ethereum Address Validation**:
```typescript
import { isValidWalletAddress } from '../utils'
if (isValidWalletAddress(address)) {
// Address is valid
}
```
## ⚙️ Backend Development Guide
### Project Structure
```
backend/src/main/kotlin/com/wrbug/polymarketbot/
├── api/ # API interface definitions (Retrofit)
│ ├── PolymarketClobApi.kt
│ ├── PolymarketGammaApi.kt
│ └── GitHubApi.kt
├── controller/ # REST controllers
├── service/ # Business logic services
├── entity/ # Database entities
├── repository/ # Data access layer
├── dto/ # Data Transfer Objects
├── util/ # Utility classes
│ ├── CryptoUtils.kt # Encryption utilities
│ ├── RetrofitFactory.kt # Retrofit factory
│ └── ...
└── websocket/ # WebSocket handling
```
### Creating New API Interface
1. **Define Retrofit Interface** (in `api/` directory):
```kotlin
interface MyApi {
@POST("/endpoint")
suspend fun myMethod(@Body request: MyRequest): Response<MyResponse>
}
```
2. **Create Service** (in `service/` directory):
```kotlin
@Service
class MyService(
private val myApi: MyApi
) {
suspend fun doSomething(): Result<MyResponse> {
// Business logic
}
}
```
3. **Create Controller** (in `controller/` directory):
```kotlin
@RestController
@RequestMapping("/api/my")
class MyController(
private val myService: MyService,
private val messageSource: MessageSource
) {
@PostMapping("/list")
fun list(@RequestBody request: MyListRequest): ResponseEntity<ApiResponse<MyListResponse>> {
return try {
val data = runBlocking { myService.getList(request) }
ResponseEntity.ok(ApiResponse.success(data))
} catch (e: Exception) {
logger.error("Failed to get list", e)
ResponseEntity.ok(ApiResponse.error(ErrorCode.SERVER_ERROR, messageSource = messageSource))
}
}
}
```
### Database Operations
Using Spring Data JPA:
```kotlin
@Repository
interface MyRepository : JpaRepository<MyEntity, Long> {
fun findByCode(code: String): MyEntity?
fun findByCategory(category: String): List<MyEntity>
}
```
### Encrypted Storage
Use `CryptoUtils` to encrypt sensitive data:
```kotlin
@Autowired
private lateinit var cryptoUtils: CryptoUtils
// Encrypt
val encrypted = cryptoUtils.encrypt("sensitive-data")
// Decrypt
val decrypted = cryptoUtils.decrypt(encrypted)
```
## 🔧 FAQ
### Q1: How to add a new page?
1. Create page component in `frontend/src/pages/`
2. Add route in `frontend/src/App.tsx`
3. Add menu item in `frontend/src/components/Layout.tsx` (if needed)
### Q2: How to add a new API interface?
1. Create Controller in `backend/src/main/kotlin/.../controller/`
2. Create Service in `backend/src/main/kotlin/.../service/`
3. Add API call method in `frontend/src/services/api.ts`
### Q3: How to add a database table?
1. Create Entity class (in `entity/` directory)
2. Create Repository interface (in `repository/` directory)
3. Create Flyway migration script (in `resources/db/migration/`)
### Q4: How to test WebSocket?
Use browser console or WebSocket client tool to connect to `ws://localhost:8000/ws`
### Q5: How to debug backend code?
1. Use IDE's debugging feature (IntelliJ IDEA, VS Code, etc.)
2. Add logs in code: `logger.debug("Debug info")`
3. View log output: `./gradlew bootRun` or view log files
## 📚 Related Documentation
- [Deployment Documentation](../zh/DEPLOYMENT.md) / [English](../en/DEPLOYMENT.md) - Detailed deployment guide
- [Version Management Documentation](../zh/VERSION_MANAGEMENT.md) / [English](../en/VERSION_MANAGEMENT.md) - Version number management and auto-build
- [Copy Trading System Requirements](../zh/copy-trading-requirements.md) - Backend API interface documentation
- [Frontend Requirements](../zh/copy-trading-frontend-requirements.md) - Frontend feature documentation
## 🤝 Contributing
Contributions are welcome! Please follow these steps:
1. Fork this repository
2. Create a feature branch (`git checkout -b feature/AmazingFeature`)
3. Follow code standards
4. Commit your changes (`git commit -m 'feat: Add some AmazingFeature'`)
5. Push to the branch (`git push origin feature/AmazingFeature`)
6. Open a Pull Request
---
**Happy Coding! 🚀**
+268
View File
@@ -0,0 +1,268 @@
# Version Management Guide
> 📖 **中文版本**: [版本号管理说明(中文)](../zh/VERSION_MANAGEMENT.md)
## Overview
This project supports automatic version number management and display. When creating a release tag on GitHub, it automatically triggers GitHub Actions to build Docker images and push them to Docker Hub, while displaying the version number after the frontend title.
## Features
1. **Auto Build**: Automatically triggers GitHub Actions when creating release tags
2. **Version Display**: Displays version number after frontend title (small font)
3. **Click to Navigate**: Click version number to jump to corresponding GitHub tag page
4. **Docker Push**: Automatically builds and pushes to Docker Hub
5. **Auto Delete**: Automatically deletes corresponding Docker image tags when releases are deleted
6. **Version Validation**: Strictly matches version format `v数字.数字.数字` or `v数字.数字.数字-后缀` (e.g., `v1.0.0`, `v1.0.0-beta`)
7. **Independent Scripts**: Build and delete functions separated into different workflow files for easier management and maintenance
## Workflow File Description
The project uses two independent GitHub Actions workflow files:
- **`.github/workflows/docker-build.yml`**: Responsible for building and pushing Docker images
- Trigger: `release: published` (when creating release)
- Functions: Extract version number, build multi-architecture images, push to Docker Hub
- **`.github/workflows/docker-delete.yml`**: Responsible for deleting Docker images
- Trigger: `release: deleted` (when deleting release)
- Functions: Validate version format, delete corresponding Docker image tags
## Usage
### 1. Configure Docker Hub Credentials
Add the following Secrets in GitHub repository settings:
- `DOCKER_USERNAME`: Docker Hub username (e.g., `wrbug`)
- `DOCKER_PASSWORD`: Docker Hub access token (recommended) or password
**Setup Steps**:
1. **Create Docker Hub Access Token** (Recommended):
- Visit: https://hub.docker.com/settings/security
- Click "New Access Token"
- Fill in description (e.g., `GitHub Actions PolyHermes`)
- **Important**: Check the following permissions:
-`Read & Write` (for pushing images)
-`Delete repository tags` (for deleting images)
- Click "Generate"
- **Copy the token immediately** (only shown once)
2. **Add Secrets in GitHub**:
- Visit GitHub repository → Settings → Secrets and variables → Actions
- Click "New repository secret"
- Add `DOCKER_USERNAME`: Your Docker Hub username
- Add `DOCKER_PASSWORD`: The Access Token you just created (not password)
**Note**:
- ⚠️ If using password instead of Access Token, the delete image function may not work properly
- ✅ Recommended to use Access Token and ensure `Delete repository tags` permission
### 2. Create Release (Must be via GitHub Releases Page)
**Important**: Only creating releases via [GitHub Releases page](https://github.com/WrBug/PolyHermes/releases/new) will trigger auto build.
**Workflow Description**:
- When creating a release, it triggers `docker-build.yml` workflow, automatically building and pushing images
- When deleting a release, it triggers `docker-delete.yml` workflow, automatically deleting corresponding image tags
**Creation Steps**:
1. Visit [GitHub Releases page](https://github.com/WrBug/PolyHermes/releases/new)
2. Click "Choose a tag" dropdown, enter new tag name (e.g., `v1.0.0` or `v1.0.0-beta`)
- If tag doesn't exist, GitHub will automatically create it
- Tag format: `v数字.数字.数字` or `v数字.数字.数字-后缀` (e.g., `v1.0.0`, `v1.0.0-beta`, `v2.10.102-rc.1`)
3. Fill in Release title (e.g., `v1.0.0` or `v1.0.0-beta`)
4. Fill in Release description (optional, recommended to include update content)
5. Click "Publish release" button
**Note**:
- ⚠️ Pushing tags directly via `git push` **will not** trigger build
- ✅ Only clicking "Publish release" on Releases page will trigger build
- This ensures only officially released versions will build Docker images
### 3. Auto Build Process
After clicking "Publish release", GitHub Actions will automatically:
1. **Extract Version**: Extract version number from tag (e.g., `v1.0.0``1.0.0`)
2. **Build Docker Image**: Use version number as build parameter
3. **Inject Version**: Inject version number into code when building frontend
4. **Push Image**: Push to Docker Hub with tags:
- `wrbug/polyhermes:v1.0.0` (specific version)
- `wrbug/polyhermes:latest` (latest version)
### 4. Version Display
Frontend will display version number after title "PolyHermes", format: `PolyHermes v1.0.0`
- **Display Location**: Desktop left sidebar title, mobile top title
- **Style**: Small font, semi-transparent, normal display (no underline or special styles)
- **Click Behavior**: Click version number to jump to corresponding GitHub tag page
### 5. Delete Release and Docker Image
When deleting a release on GitHub Releases page, it will automatically delete corresponding Docker image tag:
1. Visit [GitHub Releases page](https://github.com/WrBug/PolyHermes/releases)
2. Find the release to delete
3. Click "Delete" button
4. GitHub Actions will automatically trigger delete process
5. Delete corresponding Docker image tag (e.g., `wrbug/polyhermes:v1.0.0`)
**Notes**:
- ⚠️ Only version numbers in format `v数字.数字.数字` or `v数字.数字.数字-后缀` will be deleted (e.g., `v1.0.0`, `v1.0.0-beta`, `v2.10.102`)
- ⚠️ If image tag doesn't exist, it will show warning but won't fail
- ⚠️ `latest` tag will not be deleted (even if deleting the latest release)
## Technical Implementation
### Version Injection Process
1. **GitHub Actions** extracts version number from tag
2. **Dockerfile** receives build parameters (`VERSION`, `GIT_TAG`, `GITHUB_REPO_URL`)
3. **Vite Build** injects version number into `window.__VERSION__` via environment variables
4. **Frontend Code** reads version number from `window.__VERSION__` and displays it
### File Description
- `.github/workflows/docker-build.yml`: GitHub Actions workflow configuration
- `Dockerfile`: Supports version number build parameters
- `frontend/vite.config.ts`: Vite configuration, injects version number into global variable
- `frontend/src/utils/version.ts`: Version number utility functions
- `frontend/src/components/Layout.tsx`: Component that displays version number
### Environment Variables
Environment variables used during build:
- `VERSION`: Version number (e.g., `1.0.0`)
- `GIT_TAG`: Git tag (e.g., `v1.0.0`)
- `GITHUB_REPO_URL`: GitHub repository URL (default: `https://github.com/WrBug/PolyHermes`)
## Development Environment
In development environment, version number defaults to `dev` and won't display as a link.
If you need to test version display, you can set in `.env` file:
```env
VITE_APP_VERSION=1.0.0
VITE_APP_GIT_TAG=v1.0.0
VITE_APP_GITHUB_REPO_URL=https://github.com/WrBug/PolyHermes
```
## FAQ
### Q1: Build not triggered after creating release?
**A:** Check the following:
1. Confirm release was created via [GitHub Releases page](https://github.com/WrBug/PolyHermes/releases/new), not by directly pushing tag
2. Confirm "Publish release" button was clicked (not "Save draft")
3. Check if GitHub Actions is enabled
4. View workflow runs in Actions tab
5. Confirm release status is "Published" (not "Draft" or "Prerelease")
### Q2: Docker push failed?
**A:** Check the following:
1. Confirm `DOCKER_USERNAME` and `DOCKER_PASSWORD` Secrets are correctly configured
2. Confirm Docker Hub account has permission to push images
3. Check if Docker Hub repository name is correct (`wrbug/polyhermes`)
### Q3: Frontend not displaying version number?
**A:** Check the following:
1. Confirm version number environment variables were passed during build
2. Check browser console for errors
3. Confirm using built image, not development environment
### Q4: Version number click not navigating?
**A:** Check the following:
1. Confirm `GIT_TAG` environment variable is correctly set
2. Confirm GitHub repository URL is correct
3. Check if browser is blocking popups
### Q5: Docker image not deleted after deleting release?
**A:** Check the following:
1. Confirm version format is `v数字.数字.数字` or `v数字.数字.数字-后缀` (e.g., `v1.0.0`, `v1.0.0-beta`)
2. Confirm Docker Hub credentials (`DOCKER_USERNAME` and `DOCKER_PASSWORD`) are correctly configured
3. **Confirm Docker Hub access token has permission to delete images**:
- If using Access Token, ensure it has `Delete repository tags` permission
- Visit Docker Hub → Account Settings → Security → Access Tokens
- Create or edit access token, ensure `Delete repository tags` permission is checked
4. If encountering 401 error, it might be:
- Access token expired, need to regenerate
- Access token has insufficient permissions, need to add delete permission
- Username or password/token is incorrect
5. View GitHub Actions logs to confirm delete operation was executed
6. If image tag doesn't exist, it will show warning but won't fail (this is normal)
### Q6: Encountered 401 unauthorized error when deleting image?
**A:** This is usually due to authentication failure, please check:
1. **If using Access Token**:
- Ensure access token is not expired
- Ensure access token has `Delete repository tags` permission
- Check permissions in Docker Hub → Account Settings → Security → Access Tokens
2. **If using password**:
- Ensure username and password are correct
- If 2FA is enabled, need to use Access Token instead of password
3. **Create new Access Token**:
- Visit: https://hub.docker.com/settings/security
- Click "New Access Token"
- Fill in description (e.g., `GitHub Actions Delete Images`)
- **Important**: Check `Delete repository tags` permission
- Copy generated token, update `DOCKER_PASSWORD` in GitHub Secrets
### Q7: What are the version number format requirements?
**A:** Version number must strictly match format: `v数字.数字.数字` or `v数字.数字.数字-后缀`
- ✅ Correct: `v1.0.0`, `v2.10.102`, `v1.0.0-beta`, `v1.0.0-rc.1`, `v2.10.102-alpha`
- ❌ Wrong: `v1.0`, `1.0.0`, `v1.0.0.1`, `v1.0.0_beta` (underscore not supported)
## Examples
### Create Release Example
**Step 1: Visit Releases Page**
Visit: https://github.com/WrBug/PolyHermes/releases/new
**Step 2: Create Release**
1. Enter `v1.0.0` in "Choose a tag" (will be created automatically if doesn't exist)
2. Fill in Release title: `v1.0.0`
3. Fill in Release description (optional)
4. Click "Publish release"
**Step 3: Auto Build**
- GitHub Actions will automatically trigger build
- After build completes, Docker image will be automatically pushed to Docker Hub
- Frontend will display "PolyHermes v1.0.0"
**Note**: Pushing tag directly via `git push` will not trigger build, must create via Releases page.
### Use Docker Image Example
```bash
# Pull specific version
docker pull wrbug/polyhermes:v1.0.0
# Pull latest version
docker pull wrbug/polyhermes:latest
# Run container
docker run -d -p 80:80 wrbug/polyhermes:v1.0.0
```
## Notes
1. **Tag Format**: Must use `v*` format (e.g., `v1.0.0`), otherwise won't trigger build
2. **Version Format**: Recommend using Semantic Versioning
3. **Docker Hub**: Ensure Docker Hub repository is created
4. **Permissions**: Ensure GitHub Actions has permission to access Docker Hub
+170
View File
@@ -0,0 +1,170 @@
# PolyHermes Nginx 反向代理配置示例
#
# 适用于生产环境,在 Docker 容器外部部署 Nginx 作为反向代理
#
# 使用场景:
# - SSL/TLS 终止(HTTPS
# - 域名绑定
# - 负载均衡
# - 更灵活的配置
#
# 部署步骤:
# 1. 将本文件复制到 /etc/nginx/sites-available/polyhermes
# 2. 创建软链接: ln -s /etc/nginx/sites-available/polyhermes /etc/nginx/sites-enabled/
# 3. 修改配置中的域名和 SSL 证书路径
# 4. 测试配置: nginx -t
# 5. 重载配置: systemctl reload nginx
# HTTP 服务器(可选:用于重定向到 HTTPS)
server {
listen 80;
server_name your-domain.com www.your-domain.com;
# 重定向到 HTTPS
return 301 https://$server_name$request_uri;
}
# HTTPS 服务器
server {
listen 443 ssl http2;
server_name your-domain.com www.your-domain.com;
# SSL 证书配置(使用 Let's Encrypt 或其他证书)
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.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;
# 安全头
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# 日志
access_log /var/log/nginx/polyhermes-access.log;
error_log /var/log/nginx/polyhermes-error.log;
# 客户端最大上传大小
client_max_body_size 10M;
# 上游服务(Docker 容器)
# 如果使用 docker-compose,容器名是 polyhermes,端口是 80
upstream polyhermes_backend {
server 127.0.0.1:80;
# 如果需要负载均衡,可以添加多个后端:
# server 127.0.0.1:8001;
# server 127.0.0.1:8002;
}
# API 代理
location /api {
proxy_pass http://polyhermes_backend;
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_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
# 超时设置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 缓冲设置
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
proxy_busy_buffers_size 8k;
}
# WebSocket 代理
location /ws {
proxy_pass http://polyhermes_backend;
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_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
# WebSocket 超时设置(长连接)
proxy_connect_timeout 7d;
proxy_send_timeout 7d;
proxy_read_timeout 7d;
}
# 前端静态文件代理
location / {
proxy_pass http://polyhermes_backend;
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_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
# 静态资源缓存(由后端 Nginx 处理)
proxy_cache_valid 200 1y;
}
# 健康检查(可选)
location /health {
proxy_pass http://polyhermes_backend;
access_log off;
}
}
# 如果不需要 HTTPS,可以使用以下简化配置
# server {
# listen 80;
# server_name your-domain.com www.your-domain.com;
#
# access_log /var/log/nginx/polyhermes-access.log;
# error_log /var/log/nginx/polyhermes-error.log;
#
# client_max_body_size 10M;
#
# upstream polyhermes_backend {
# server 127.0.0.1:80;
# }
#
# location /api {
# proxy_pass http://polyhermes_backend;
# 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;
# }
#
# location /ws {
# proxy_pass http://polyhermes_backend;
# 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_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-Forwarded-Proto $scheme;
# proxy_read_timeout 86400;
# proxy_send_timeout 86400;
# }
#
# location / {
# proxy_pass http://polyhermes_backend;
# 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;
# }
# }