feat: 添加完整的部署支持

- 后端多环境配置(dev, prod)
- Docker 部署支持(Dockerfile, docker-compose.yml)
- Java 部署脚本(deploy.sh)
- 前端构建脚本(build.sh,支持自定义后端地址)
- 健康检查接口(/api/health)
- 完整的部署文档(docs/DEPLOYMENT.md)
- 前端环境变量支持(VITE_API_URL, VITE_WS_URL)
This commit is contained in:
WrBug
2025-12-03 02:48:02 +08:00
parent 220afd748f
commit 59722d7311
14 changed files with 1047 additions and 47 deletions
+33
View File
@@ -0,0 +1,33 @@
# Gradle
.gradle/
build/
out/
bin/
*.log
# IDE
.idea/
*.iml
*.iws
*.ipr
.vscode/
*.swp
*.swo
*~
.DS_Store
# 部署相关
deploy/
*.jar
!build/libs/*.jar
# 环境配置
.env
.env.local
.env.*.local
# 其他
*.bak
*.backup
*.old
+48
View File
@@ -0,0 +1,48 @@
# 多阶段构建 Dockerfile
# 阶段1:构建应用
FROM gradle:8.5-jdk17 AS build
WORKDIR /app
# 复制 Gradle 配置文件
COPY build.gradle.kts settings.gradle.kts ./
COPY gradle ./gradle
# 下载依赖(利用 Docker 缓存)
RUN gradle dependencies --no-daemon || true
# 复制源代码
COPY src ./src
# 构建应用
RUN gradle bootJar --no-daemon
# 阶段2:运行应用
FROM openjdk:17-jre-slim
WORKDIR /app
# 安装必要的工具
RUN apt-get update && \
apt-get install -y curl && \
rm -rf /var/lib/apt/lists/*
# 从构建阶段复制 JAR 文件
COPY --from=build /app/build/libs/*.jar app.jar
# 创建非 root 用户
RUN useradd -m -u 1000 appuser && \
chown -R appuser:appuser /app
USER appuser
# 暴露端口
EXPOSE 8000
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
CMD curl -f http://localhost:8000/api/health || exit 1
# 启动应用
ENTRYPOINT ["java", "-jar", "app.jar"]
+203
View File
@@ -0,0 +1,203 @@
#!/bin/bash
# PolyHermes 后端部署脚本
# 支持 Java 直接部署和 Docker 部署
set -e
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 配置
APP_NAME="polymarket-bot-backend"
JAR_NAME="polymarket-bot-backend-1.0.0.jar"
DEPLOY_DIR="./deploy"
PROFILE="${SPRING_PROFILES_ACTIVE:-prod}"
# 打印信息
info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 检查 Java 环境
check_java() {
if ! command -v java &> /dev/null; then
error "Java 未安装,请先安装 Java 17+"
exit 1
fi
JAVA_VERSION=$(java -version 2>&1 | awk -F '"' '/version/ {print $2}' | cut -d'.' -f1)
if [ "$JAVA_VERSION" -lt 17 ]; then
error "Java 版本过低,需要 Java 17+,当前版本: $JAVA_VERSION"
exit 1
fi
info "Java 环境检查通过: $(java -version 2>&1 | head -n 1)"
}
# 构建应用
build_app() {
info "开始构建应用..."
if ! command -v gradle &> /dev/null; then
error "Gradle 未安装,请先安装 Gradle 或使用 Gradle Wrapper"
exit 1
fi
./gradlew clean bootJar
if [ ! -f "build/libs/$JAR_NAME" ]; then
error "构建失败,JAR 文件不存在"
exit 1
fi
info "构建完成: build/libs/$JAR_NAME"
}
# Java 部署
deploy_java() {
info "使用 Java 方式部署..."
# 创建部署目录
mkdir -p "$DEPLOY_DIR"
# 复制 JAR 文件
cp "build/libs/$JAR_NAME" "$DEPLOY_DIR/"
# 创建启动脚本
cat > "$DEPLOY_DIR/start.sh" <<EOF
#!/bin/bash
cd \$(dirname \$0)
# 设置 JVM 参数
JVM_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC -XX:MaxGCPauseMillis=200"
# 启动应用
java \$JVM_OPTS -jar $JAR_NAME --spring.profiles.active=$PROFILE
EOF
chmod +x "$DEPLOY_DIR/start.sh"
# 创建 systemd 服务文件(可选)
cat > "$DEPLOY_DIR/${APP_NAME}.service" <<EOF
[Unit]
Description=PolyHermes Backend Service
After=network.target mysql.service
[Service]
Type=simple
User=\${USER}
WorkingDirectory=$DEPLOY_DIR
ExecStart=/usr/bin/java -Xms512m -Xmx1024m -XX:+UseG1GC -jar $JAR_NAME --spring.profiles.active=$PROFILE
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
info "Java 部署文件已创建在: $DEPLOY_DIR"
info "启动方式: cd $DEPLOY_DIR && ./start.sh"
info "或使用 systemd: sudo cp ${APP_NAME}.service /etc/systemd/system/ && sudo systemctl start ${APP_NAME}"
}
# Docker 部署
deploy_docker() {
info "使用 Docker 方式部署..."
if ! command -v docker &> /dev/null; then
error "Docker 未安装,请先安装 Docker"
exit 1
fi
if ! command -v docker-compose &> /dev/null; then
error "Docker Compose 未安装,请先安装 Docker Compose"
exit 1
fi
# 创建 .env 文件(如果不存在)
if [ ! -f ".env" ]; then
warn ".env 文件不存在,创建示例文件..."
cat > .env <<EOF
# 数据库配置
DB_URL=jdbc:mysql://mysql:3306/polymarket_bot?useSSL=false&serverTimezone=UTC&characterEncoding=utf8mb4
DB_USERNAME=root
DB_PASSWORD=your_password_here
# Spring Profile
SPRING_PROFILES_ACTIVE=prod
# 服务器端口
SERVER_PORT=8000
# Polygon RPC
POLYGON_RPC_URL=https://polygon-rpc.com
# JWT 密钥(生产环境必须修改)
JWT_SECRET=your-jwt-secret-key-change-in-production
# 管理员密码重置密钥(生产环境必须修改)
ADMIN_RESET_PASSWORD_KEY=your-admin-reset-key-change-in-production
EOF
warn "请编辑 .env 文件配置相关参数"
fi
# 构建并启动
info "构建 Docker 镜像..."
docker-compose build
info "启动服务..."
docker-compose up -d
info "Docker 部署完成"
info "查看日志: docker-compose logs -f"
info "停止服务: docker-compose down"
}
# 主函数
main() {
echo "=========================================="
echo " PolyHermes 后端部署脚本"
echo "=========================================="
echo ""
# 解析参数
DEPLOY_MODE="${1:-java}"
case "$DEPLOY_MODE" in
java)
check_java
build_app
deploy_java
;;
docker)
deploy_docker
;;
build)
check_java
build_app
;;
*)
echo "用法: $0 [java|docker|build]"
echo ""
echo " java - Java 直接部署(默认)"
echo " docker - Docker 部署"
echo " build - 仅构建应用"
exit 1
;;
esac
}
main "$@"
+54
View File
@@ -0,0 +1,54 @@
version: '3.8'
services:
backend:
build:
context: .
dockerfile: Dockerfile
container_name: polymarket-bot-backend
ports:
- "${SERVER_PORT:-8000}:8000"
environment:
- SPRING_PROFILES_ACTIVE=${SPRING_PROFILES_ACTIVE:-prod}
- DB_URL=${DB_URL:-jdbc:mysql://mysql:3306/polymarket_bot?useSSL=false&serverTimezone=UTC&characterEncoding=utf8mb4}
- DB_USERNAME=${DB_USERNAME:-root}
- DB_PASSWORD=${DB_PASSWORD:-}
- SERVER_PORT=8000
- POLYGON_RPC_URL=${POLYGON_RPC_URL:-https://polygon-rpc.com}
- JWT_SECRET=${JWT_SECRET:-change-me-in-production}
- ADMIN_RESET_PASSWORD_KEY=${ADMIN_RESET_PASSWORD_KEY:-change-me-in-production}
depends_on:
mysql:
condition: service_healthy
restart: unless-stopped
networks:
- polymarket-network
mysql:
image: mysql:8.2
container_name: polymarket-bot-mysql
ports:
- "${MYSQL_PORT:-3306}:3306"
environment:
- MYSQL_ROOT_PASSWORD=${DB_PASSWORD:-rootpassword}
- MYSQL_DATABASE=polymarket_bot
- MYSQL_CHARACTER_SET_SERVER=utf8mb4
- MYSQL_COLLATION_SERVER=utf8mb4_unicode_ci
volumes:
- mysql-data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${DB_PASSWORD:-rootpassword}"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
networks:
- polymarket-network
volumes:
mysql-data:
networks:
polymarket-network:
driver: bridge
@@ -0,0 +1,26 @@
package com.wrbug.polymarketbot.controller
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import java.util.*
/**
* 健康检查控制器
* 用于 Docker 健康检查和监控
*/
@RestController
@RequestMapping("/api/health")
class HealthController {
@GetMapping
fun health(): ResponseEntity<Map<String, Any>> {
return ResponseEntity.ok(mapOf(
"status" to "UP",
"timestamp" to System.currentTimeMillis(),
"service" to "polymarket-bot-backend"
))
}
}
@@ -1,8 +1,8 @@
# 应用配置
spring.application.name=polymarket-bot-backend
# 数据源配置
spring.datasource.url=jdbc:mysql://localhost:3306/polymarket_bot?useSSL=false&serverTimezone=UTC&characterEncoding=utf8&allowPublicKeyRetrieval=true
# 数据源配置(默认配置,可通过环境变量覆盖)
spring.datasource.url=${DB_URL:jdbc:mysql://localhost:3306/polymarket_bot?useSSL=false&serverTimezone=UTC&characterEncoding=utf8&allowPublicKeyRetrieval=true}
spring.datasource.username=${DB_USERNAME:root}
spring.datasource.password=${DB_PASSWORD:11111111}
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
@@ -25,6 +25,10 @@ spring.flyway.baseline-on-migrate=true
# 服务器配置
server.port=${SERVER_PORT:8000}
# Spring Profile 配置
# 默认使用 dev 环境,可通过 --spring.profiles.active=prod 切换
spring.profiles.active=${SPRING_PROFILES_ACTIVE:dev}
# 日志配置
logging.level.root=INFO
logging.level.com.wrbug.polymarketbot=DEBUG