-
Notifications
You must be signed in to change notification settings - Fork 32
Expand file tree
/
Copy pathdeploy.sh
More file actions
executable file
·239 lines (193 loc) · 7.86 KB
/
deploy.sh
File metadata and controls
executable file
·239 lines (193 loc) · 7.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
#!/bin/bash
# PolyHermes 一体化部署脚本
# 将前后端一起部署到一个 Docker 容器中
set -e
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 打印信息
info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 检查 Docker 环境
check_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
info "Docker 环境检查通过"
}
# 生成随机字符串
generate_random_string() {
local length=${1:-32}
openssl rand -hex $length 2>/dev/null || \
cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $length | head -n 1
}
# 创建 .env 文件(如果不存在)
create_env_file() {
if [ ! -f ".env" ]; then
warn ".env 文件不存在,创建示例文件..."
# 生成随机值
DB_PASSWORD=$(generate_random_string 32)
JWT_SECRET=$(generate_random_string 64)
ADMIN_RESET_KEY=$(generate_random_string 32)
cat > .env <<EOF
# 数据库配置
DB_URL=jdbc:mysql://mysql:3306/polyhermes?useSSL=false&serverTimezone=UTC&characterEncoding=utf8&allowPublicKeyRetrieval=true
DB_USERNAME=root
DB_PASSWORD=${DB_PASSWORD}
# Spring Profile
SPRING_PROFILES_ACTIVE=prod
# 服务器端口(对外暴露的端口)
SERVER_PORT=80
# MySQL 端口(可选,用于外部连接,默认 3307 避免与本地 MySQL 冲突)
MYSQL_PORT=3307
# JWT 密钥(已自动生成随机值,生产环境建议修改)
JWT_SECRET=${JWT_SECRET}
# 管理员密码重置密钥(已自动生成随机值,生产环境建议修改)
ADMIN_RESET_PASSWORD_KEY=${ADMIN_RESET_KEY}
# 日志级别配置(可选,默认值:root=WARN, app=INFO)
# 可选值:TRACE, DEBUG, INFO, WARN, ERROR, OFF
# LOG_LEVEL_ROOT=WARN
# LOG_LEVEL_APP=INFO
EOF
info ".env 文件已创建,已自动生成随机密码和密钥"
warn "生产环境建议修改以下参数:"
warn " - DB_PASSWORD: 数据库密码(当前: ${DB_PASSWORD:0:8}...)"
warn " - JWT_SECRET: JWT 密钥(当前: ${JWT_SECRET:0:8}...)"
warn " - ADMIN_RESET_PASSWORD_KEY: 管理员密码重置密钥(当前: ${ADMIN_RESET_KEY:0:8}...)"
exit 1
fi
}
# 检查安全配置
check_security_config() {
# 默认值常量
DEFAULT_JWT_SECRET="change-me-in-production"
DEFAULT_ADMIN_RESET_KEY="change-me-in-production"
# 从 .env 文件读取配置(如果存在)
local jwt_secret=""
local admin_reset_key=""
if [ -f ".env" ]; then
# 从 .env 文件读取(使用 grep 和 sed 避免 source 可能的问题)
jwt_secret=$(grep "^JWT_SECRET=" .env 2>/dev/null | cut -d'=' -f2- | sed 's/^"//;s/"$//' || echo "")
admin_reset_key=$(grep "^ADMIN_RESET_PASSWORD_KEY=" .env 2>/dev/null | cut -d'=' -f2- | sed 's/^"//;s/"$//' || echo "")
fi
# 如果环境变量已设置,优先使用环境变量
if [ -n "$JWT_SECRET" ]; then
jwt_secret="$JWT_SECRET"
fi
if [ -n "$ADMIN_RESET_PASSWORD_KEY" ]; then
admin_reset_key="$ADMIN_RESET_PASSWORD_KEY"
fi
local errors=0
# 检查 JWT_SECRET
if [ -z "$jwt_secret" ] || [ "$jwt_secret" = "$DEFAULT_JWT_SECRET" ]; then
error "JWT_SECRET 不能使用默认值 '${DEFAULT_JWT_SECRET}'"
error "请在 .env 文件中设置 JWT_SECRET 为安全的随机字符串"
errors=$((errors + 1))
fi
# 检查 ADMIN_RESET_PASSWORD_KEY
if [ -z "$admin_reset_key" ] || [ "$admin_reset_key" = "$DEFAULT_ADMIN_RESET_KEY" ]; then
error "ADMIN_RESET_PASSWORD_KEY 不能使用默认值 '${DEFAULT_ADMIN_RESET_KEY}'"
error "请在 .env 文件中设置 ADMIN_RESET_PASSWORD_KEY 为安全的随机字符串"
errors=$((errors + 1))
fi
if [ $errors -gt 0 ]; then
echo ""
error "安全配置检查失败,部署已取消"
echo ""
info "提示:可以使用以下命令生成随机密钥:"
info " openssl rand -hex 32 # 生成 32 字节的随机字符串(用于 ADMIN_RESET_PASSWORD_KEY)"
info " openssl rand -hex 64 # 生成 64 字节的随机字符串(用于 JWT_SECRET)"
exit 1
fi
info "安全配置检查通过"
}
# 构建并启动
deploy() {
# 检查安全配置
check_security_config
# 检查是否使用 Docker Hub 镜像
USE_DOCKER_HUB="${USE_DOCKER_HUB:-false}"
if [ "$USE_DOCKER_HUB" = "true" ]; then
info "使用 Docker Hub 镜像(推荐生产环境)..."
info "拉取最新镜像..."
docker pull wrbug/polyhermes:latest || warn "拉取镜像失败,将使用本地构建"
# 修改 docker-compose.yml 使用镜像而不是构建
# 注意:这里需要手动修改 docker-compose.yml,或者使用环境变量
warn "请确保 docker-compose.yml 中已配置使用 image: wrbug/polyhermes:latest"
else
# 版本号:优先环境变量 DOCKER_VERSION,其次 .env 中的 DOCKER_VERSION,否则用当前分支名
if [ -z "${DOCKER_VERSION}" ] && [ -f ".env" ]; then
DOCKER_VERSION=$(grep "^DOCKER_VERSION=" .env 2>/dev/null | cut -d'=' -f2- | sed 's/^["'\'']//;s/["'\'']$//' | tr -d '\r')
fi
if [ -z "${DOCKER_VERSION}" ]; then
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "dev")
DOCKER_VERSION=$(echo "$CURRENT_BRANCH" | tr '/' '-')
fi
export DOCKER_VERSION
info "构建 Docker 镜像(本地构建,版本号: ${DOCKER_VERSION})..."
# 创建占位符目录(如果不存在),避免 Dockerfile COPY 失败
# 当 BUILD_IN_DOCKER=true 时,backend/build 可能不存在
mkdir -p backend/build/libs
# 设置构建参数(通过环境变量传递给 docker-compose.yml)
export VERSION=${DOCKER_VERSION}
export GIT_TAG=${DOCKER_VERSION}
export GITHUB_REPO_URL=https://github.com/WrBug/PolyHermes
docker-compose build
fi
info "启动服务..."
docker-compose up -d
info "等待服务启动..."
sleep 5
info "检查服务状态..."
docker-compose ps
info "查看日志: docker-compose logs -f"
info "停止服务: docker-compose down"
}
# 主函数
main() {
echo "=========================================="
echo " PolyHermes 一体化部署脚本"
echo "=========================================="
echo ""
# 解析参数
if [ "$1" = "--use-docker-hub" ] || [ "$1" = "-d" ]; then
export USE_DOCKER_HUB=true
info "将使用 Docker Hub 镜像(生产环境推荐)"
echo ""
fi
check_docker
create_env_file
deploy
echo ""
info "部署完成!"
info "访问地址: http://localhost:${SERVER_PORT:-80}"
echo ""
if [ "$USE_DOCKER_HUB" != "true" ]; then
if [ -z "${DOCKER_VERSION}" ] && [ -f ".env" ]; then
DOCKER_VERSION=$(grep "^DOCKER_VERSION=" .env 2>/dev/null | cut -d'=' -f2- | sed 's/^["'\'']//;s/["'\'']$//' | tr -d '\r')
fi
if [ -z "${DOCKER_VERSION}" ]; then
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "dev")
DOCKER_VERSION=$(echo "$CURRENT_BRANCH" | tr '/' '-')
fi
info "提示:本地构建的版本号: ${DOCKER_VERSION}(可在 .env 或环境变量中设置 DOCKER_VERSION)"
info "生产环境推荐使用 Docker Hub 镜像:"
info " ./deploy.sh --use-docker-hub"
info " 或修改 docker-compose.yml 使用 image: wrbug/polyhermes:latest"
fi
}
main "$@"