- 删除 application.properties 中的 polygon.rpc.url 配置 - 更新 ApiHealthCheckService 直接使用 RpcNodeService.getHttpUrl() - 删除所有 Docker Compose 配置中的 POLYGON_RPC_URL 环境变量 - 删除所有部署脚本中的 POLYGON_RPC_URL 环境变量 - 更新所有文档,移除 POLYGON_RPC_URL 相关说明 - 删除 application.properties 中无用的 position.push 配置项 - 修正日志配置中的包名(polyhermes -> polymarketbot) 现在系统通过 RpcNodeService 从数据库读取 RPC 节点配置,用户可以通过系统设置页面管理 RPC 节点,不再需要环境变量配置。
18 KiB
PolyHermes Deployment Guide
📖 中文版本: 部署文档(中文)
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)
- Backend Deployment
- Frontend Deployment
- Environment Configuration
- 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
- 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.
# 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)
# If you have already cloned the code
./deploy.sh --use-docker-hub
Method 3: Modify Existing docker-compose.yml
# 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:
# 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}
Update Docker Version:
When a new version is released, you can update using the following steps:
# 1. Stop currently running containers
docker-compose -f docker-compose.prod.yml down
# 2. Pull the latest version image (or specific version)
# Update to latest version
docker pull wrbug/polyhermes:latest
# Or update to specific version (e.g., v1.0.1)
docker pull wrbug/polyhermes:v1.0.1
# 3. If using a specific version, modify the image tag in docker-compose.prod.yml
# Edit docker-compose.prod.yml, change image to:
# image: wrbug/polyhermes:v1.0.1
# 4. Restart services
docker-compose -f docker-compose.prod.yml up -d
# 5. Check logs to confirm services started normally
docker-compose -f docker-compose.prod.yml logs -f
Notes:
- ⚠️ It is recommended to backup the database before updating (if using MySQL in Docker Compose)
- ⚠️ Service will be briefly interrupted during update, recommend updating during off-peak hours
- ✅ Using
docker-compose pullcan automatically pull the latest image and update (if usinglatesttag) - ✅ View available versions: Visit Docker Hub or GitHub Releases
- Local Build Deployment (Development Environment)
Suitable for development environments or scenarios requiring custom builds.
# Use deployment script
./deploy.sh
The script will automatically:
- Check Docker environment
- Create
.envconfiguration 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.
- Manual Deployment
# 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
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
- 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:
- Deploy Docker Container
# Deploy using docker-compose.prod.yml
docker-compose -f docker-compose.prod.yml up -d
- Configure External Nginx
# 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
- Configure SSL Certificate (Using Let's Encrypt)
# 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
- Modify Docker Port Mapping (Optional)
If using external Nginx, you can change Docker container port to internal port, not exposed externally:
# 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
Backend Deployment
Java Direct Deployment
Prerequisites
- JDK 17+
- MySQL 8.0+
- Gradle 7.5+ (or use Gradle Wrapper)
Deployment Steps
- Build Application
cd backend
./gradlew clean bootJar
Build artifact located at build/libs/polyhermes-backend-1.0.0.jar
- Use Deployment Script (Recommended)
# 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)
- Manual Start
# 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
- Use systemd Management (Linux)
# 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
- Use Deployment Script (Recommended)
cd backend
./deploy.sh docker
The script will automatically:
- Check Docker environment
- Create
.envconfiguration file (if it doesn't exist) - Build Docker image
- Start service
- Manual Deployment
# 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
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
- Build Image Only
docker build -t polyhermes-backend:latest .
- Run Container
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
- Use Build Script (Recommended)
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
- Manual Build
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
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
<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)
# 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 |
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 configurationapplication-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 (
mysqlinstead oflocalhost)
2. Frontend Cannot Connect to Backend
Problem: Frontend requests to backend API fail
Solution:
- Check if backend service is running
- Check if
VITE_API_URLconfiguration 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_URLconfiguration 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.internalas 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:
# 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 or contact Twitter.