增加一键启动
This commit is contained in:
@@ -10,6 +10,20 @@
|
|||||||
|
|
||||||
## 快速开始
|
## 快速开始
|
||||||
|
|
||||||
|
一键启动开发版本:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/dev.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
脚本会自动启动 MySQL、Redis、MinIO,首次初始化数据库结构,刷新开发测试数据,并同时启动后端和前端。
|
||||||
|
|
||||||
|
前端地址:`http://localhost:5173`
|
||||||
|
|
||||||
|
后台地址:`http://localhost:5173/admin/login`,开发态默认管理员为 `admin / admin123456`。
|
||||||
|
|
||||||
|
如需拆分调试,可手动执行:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose -f deploy/docker-compose.dev.yml up -d
|
docker compose -f deploy/docker-compose.dev.yml up -d
|
||||||
|
|
||||||
|
|||||||
Executable
+163
@@ -0,0 +1,163 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
COMPOSE_FILE="${ROOT_DIR}/deploy/docker-compose.dev.yml"
|
||||||
|
BACKEND_ENV="${ROOT_DIR}/backend/.env"
|
||||||
|
BACKEND_ENV_EXAMPLE="${ROOT_DIR}/backend/.env.example"
|
||||||
|
|
||||||
|
BACKEND_PID=""
|
||||||
|
FRONTEND_PID=""
|
||||||
|
CLEANED_UP=0
|
||||||
|
|
||||||
|
log() {
|
||||||
|
printf "\033[1;34m[dev]\033[0m %s\n" "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
need_cmd() {
|
||||||
|
if ! command -v "$1" >/dev/null 2>&1; then
|
||||||
|
printf "缺少命令:%s\n" "$1" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
if [[ "${CLEANED_UP}" == "1" ]]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
CLEANED_UP=1
|
||||||
|
|
||||||
|
log "正在停止前后端开发进程..."
|
||||||
|
if [[ -n "${FRONTEND_PID}" ]] && kill -0 "${FRONTEND_PID}" >/dev/null 2>&1; then
|
||||||
|
kill "${FRONTEND_PID}" >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
if [[ -n "${BACKEND_PID}" ]] && kill -0 "${BACKEND_PID}" >/dev/null 2>&1; then
|
||||||
|
kill "${BACKEND_PID}" >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_container_healthy() {
|
||||||
|
local container_name="$1"
|
||||||
|
local label="$2"
|
||||||
|
local attempt
|
||||||
|
|
||||||
|
log "等待 ${label} 就绪..."
|
||||||
|
for attempt in {1..60}; do
|
||||||
|
local status
|
||||||
|
status="$(docker inspect -f '{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}' "${container_name}" 2>/dev/null || true)"
|
||||||
|
if [[ "${status}" == "healthy" || "${status}" == "running" ]]; then
|
||||||
|
log "${label} 已就绪"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
|
||||||
|
printf "%s 启动超时,请检查:docker logs %s\n" "${label}" "${container_name}" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
init_database() {
|
||||||
|
local table_count
|
||||||
|
table_count="$(
|
||||||
|
docker exec hfb-mysql mysql -uhfb -psecret -N -s -e \
|
||||||
|
"SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'hfb_sys' AND table_name = 'users';" 2>/dev/null
|
||||||
|
)"
|
||||||
|
|
||||||
|
if [[ "${table_count}" == "0" ]]; then
|
||||||
|
log "首次启动,初始化数据库结构..."
|
||||||
|
docker exec -i hfb-mysql mysql -uhfb -psecret hfb_sys < "${ROOT_DIR}/backend/migrations/000001_init.sql"
|
||||||
|
else
|
||||||
|
log "数据库结构已存在,跳过迁移"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "刷新开发测试数据..."
|
||||||
|
docker exec -i hfb-mysql mysql -uhfb -psecret hfb_sys < "${ROOT_DIR}/backend/seeds/dev_orders.sql"
|
||||||
|
}
|
||||||
|
|
||||||
|
load_env_file() {
|
||||||
|
local env_file="$1"
|
||||||
|
local line
|
||||||
|
|
||||||
|
while IFS= read -r line || [[ -n "${line}" ]]; do
|
||||||
|
[[ -z "${line}" || "${line}" =~ ^[[:space:]]*# ]] && continue
|
||||||
|
line="${line#export }"
|
||||||
|
export "${line}"
|
||||||
|
done < "${env_file}"
|
||||||
|
}
|
||||||
|
|
||||||
|
start_backend() {
|
||||||
|
if [[ ! -f "${BACKEND_ENV}" ]]; then
|
||||||
|
log "创建 backend/.env"
|
||||||
|
cp "${BACKEND_ENV_EXAMPLE}" "${BACKEND_ENV}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "启动后端:http://localhost:8080"
|
||||||
|
(
|
||||||
|
cd "${ROOT_DIR}/backend"
|
||||||
|
load_env_file "${BACKEND_ENV}"
|
||||||
|
go run ./cmd/api
|
||||||
|
) &
|
||||||
|
BACKEND_PID="$!"
|
||||||
|
}
|
||||||
|
|
||||||
|
start_frontend() {
|
||||||
|
if [[ ! -d "${ROOT_DIR}/frontend/node_modules" ]]; then
|
||||||
|
log "安装前端依赖..."
|
||||||
|
(
|
||||||
|
cd "${ROOT_DIR}/frontend"
|
||||||
|
npm ci
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "启动前端:http://localhost:5173"
|
||||||
|
(
|
||||||
|
cd "${ROOT_DIR}/frontend"
|
||||||
|
npm run dev
|
||||||
|
) &
|
||||||
|
FRONTEND_PID="$!"
|
||||||
|
}
|
||||||
|
|
||||||
|
watch_processes() {
|
||||||
|
while true; do
|
||||||
|
if ! kill -0 "${BACKEND_PID}" >/dev/null 2>&1; then
|
||||||
|
wait "${BACKEND_PID}" || true
|
||||||
|
printf "后端进程已退出\n" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! kill -0 "${FRONTEND_PID}" >/dev/null 2>&1; then
|
||||||
|
wait "${FRONTEND_PID}" || true
|
||||||
|
printf "前端进程已退出\n" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
need_cmd docker
|
||||||
|
need_cmd go
|
||||||
|
need_cmd npm
|
||||||
|
|
||||||
|
trap cleanup EXIT
|
||||||
|
trap 'cleanup; exit 130' INT TERM
|
||||||
|
|
||||||
|
log "启动开发依赖:MySQL、Redis、MinIO"
|
||||||
|
docker compose -f "${COMPOSE_FILE}" up -d
|
||||||
|
|
||||||
|
wait_container_healthy hfb-mysql "MySQL"
|
||||||
|
wait_container_healthy hfb-redis "Redis"
|
||||||
|
wait_container_healthy hfb-minio "MinIO"
|
||||||
|
|
||||||
|
init_database
|
||||||
|
start_backend
|
||||||
|
start_frontend
|
||||||
|
|
||||||
|
log "开发环境已启动"
|
||||||
|
log "前台:http://localhost:5173"
|
||||||
|
log "后台:http://localhost:5173/admin/login(admin / admin123456)"
|
||||||
|
log "按 Ctrl+C 停止前后端;Docker 依赖会保留运行"
|
||||||
|
|
||||||
|
watch_processes
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
Reference in New Issue
Block a user