统一开发环境使用 MySQL
This commit is contained in:
+16
-1
@@ -21,11 +21,26 @@ APP_PORT=8000
|
|||||||
# Docker 构建镜像源(服务器保持 true;本地测试可改为 false)
|
# Docker 构建镜像源(服务器保持 true;本地测试可改为 false)
|
||||||
USE_CHINA_MIRRORS=true
|
USE_CHINA_MIRRORS=true
|
||||||
|
|
||||||
# MySQL 配置(生产环境必须设置密码;MySQL 不映射宿主端口)
|
# MySQL 配置(生产环境必须设置密码;默认只映射到宿主机 127.0.0.1,供本地 dev.sh 使用)
|
||||||
|
# 服务器部署默认使用国内镜像;./dev.sh 默认临时改用 mysql:8.4,避免本地测试走国内镜像。
|
||||||
|
# MYSQL_IMAGE=docker.m.daocloud.io/library/mysql:8.4
|
||||||
MYSQL_DATABASE=douyu_login
|
MYSQL_DATABASE=douyu_login
|
||||||
MYSQL_USER=douyu_login
|
MYSQL_USER=douyu_login
|
||||||
MYSQL_PASSWORD=
|
MYSQL_PASSWORD=
|
||||||
MYSQL_ROOT_PASSWORD=
|
MYSQL_ROOT_PASSWORD=
|
||||||
|
MYSQL_BIND_HOST=127.0.0.1
|
||||||
|
MYSQL_HOST_PORT=3307
|
||||||
|
|
||||||
|
# 本地调试后端连接 MySQL(./dev.sh 使用;默认连接上面的宿主机端口)
|
||||||
|
DEV_DB_HOST=127.0.0.1
|
||||||
|
DEV_DB_PORT=3307
|
||||||
|
|
||||||
|
# 直接运行后端时使用;./dev.sh 会自动按 DEV_DB_* 和 MYSQL_* 生成这些变量
|
||||||
|
# DB_HOST=127.0.0.1
|
||||||
|
# DB_PORT=3307
|
||||||
|
# DB_NAME=douyu_login
|
||||||
|
# DB_USER=douyu_login
|
||||||
|
# DB_PASSWORD=
|
||||||
|
|
||||||
# 数据库连接池配置(仅 MySQL 生效)
|
# 数据库连接池配置(仅 MySQL 生效)
|
||||||
DB_POOL_SIZE=20
|
DB_POOL_SIZE=20
|
||||||
|
|||||||
@@ -19,18 +19,43 @@ BACKEND_PORT="${BACKEND_PORT:-8800}"
|
|||||||
FRONTEND_HOST="${FRONTEND_HOST:-0.0.0.0}"
|
FRONTEND_HOST="${FRONTEND_HOST:-0.0.0.0}"
|
||||||
FRONTEND_PORT="${FRONTEND_PORT:-5174}"
|
FRONTEND_PORT="${FRONTEND_PORT:-5174}"
|
||||||
LOG_LEVEL="${LOG_LEVEL:-DEBUG}"
|
LOG_LEVEL="${LOG_LEVEL:-DEBUG}"
|
||||||
|
MYSQL_IMAGE="${MYSQL_IMAGE:-mysql:8.4}"
|
||||||
|
MYSQL_BIND_HOST="${MYSQL_BIND_HOST:-127.0.0.1}"
|
||||||
|
MYSQL_HOST_PORT="${MYSQL_HOST_PORT:-3307}"
|
||||||
|
MYSQL_DATABASE="${MYSQL_DATABASE:-douyu_login}"
|
||||||
|
MYSQL_USER="${MYSQL_USER:-douyu_login}"
|
||||||
|
DEV_DB_HOST="${DEV_DB_HOST:-127.0.0.1}"
|
||||||
|
DEV_DB_PORT="${DEV_DB_PORT:-$MYSQL_HOST_PORT}"
|
||||||
|
DB_HOST="$DEV_DB_HOST"
|
||||||
|
DB_PORT="$DEV_DB_PORT"
|
||||||
|
DB_NAME="${DB_NAME:-$MYSQL_DATABASE}"
|
||||||
|
DB_USER="${DB_USER:-$MYSQL_USER}"
|
||||||
|
DB_PASSWORD="${DB_PASSWORD:-${MYSQL_PASSWORD:-}}"
|
||||||
|
DB_POOL_SIZE="${DB_POOL_SIZE:-20}"
|
||||||
|
DB_MAX_OVERFLOW="${DB_MAX_OVERFLOW:-20}"
|
||||||
|
DB_POOL_TIMEOUT="${DB_POOL_TIMEOUT:-30}"
|
||||||
|
DB_POOL_RECYCLE="${DB_POOL_RECYCLE:-1800}"
|
||||||
|
|
||||||
BACKEND_PID=""
|
BACKEND_PID=""
|
||||||
FRONTEND_PID=""
|
FRONTEND_PID=""
|
||||||
|
|
||||||
|
stop_tree() {
|
||||||
|
local pid="$1"
|
||||||
|
local children
|
||||||
|
if [ -z "$pid" ] || ! kill -0 "$pid" 2>/dev/null; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
children="$(pgrep -P "$pid" 2>/dev/null || true)"
|
||||||
|
for child in $children; do
|
||||||
|
stop_tree "$child"
|
||||||
|
done
|
||||||
|
kill "$pid" 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
trap - EXIT INT TERM
|
trap - EXIT INT TERM
|
||||||
if [ -n "$FRONTEND_PID" ] && kill -0 "$FRONTEND_PID" 2>/dev/null; then
|
stop_tree "$FRONTEND_PID"
|
||||||
kill "$FRONTEND_PID" 2>/dev/null || true
|
stop_tree "$BACKEND_PID"
|
||||||
fi
|
|
||||||
if [ -n "$BACKEND_PID" ] && kill -0 "$BACKEND_PID" 2>/dev/null; then
|
|
||||||
kill "$BACKEND_PID" 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
require_cmd() {
|
require_cmd() {
|
||||||
@@ -42,9 +67,61 @@ require_cmd() {
|
|||||||
|
|
||||||
require_cmd uv
|
require_cmd uv
|
||||||
require_cmd npm
|
require_cmd npm
|
||||||
|
require_cmd docker
|
||||||
|
|
||||||
|
detect_compose() {
|
||||||
|
if docker compose version >/dev/null 2>&1; then
|
||||||
|
echo "docker compose"
|
||||||
|
elif command -v docker-compose >/dev/null 2>&1; then
|
||||||
|
echo "docker-compose"
|
||||||
|
else
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ -n "${DATABASE_URL:-}" ] && [[ "$DATABASE_URL" != mysql+* ]]; then
|
||||||
|
echo "dev.sh 只支持 MySQL,请移除 SQLite DATABASE_URL: $DATABASE_URL"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${MYSQL_PASSWORD:-}" ] || [ -z "${MYSQL_ROOT_PASSWORD:-}" ]; then
|
||||||
|
echo "请先在 .env 中设置 MYSQL_PASSWORD 和 MYSQL_ROOT_PASSWORD"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$DB_PASSWORD" ]; then
|
||||||
|
echo "请先在 .env 中设置 DB_PASSWORD 或 MYSQL_PASSWORD"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
COMPOSE=$(detect_compose)
|
||||||
|
if [ -z "$COMPOSE" ]; then
|
||||||
|
echo "缺少 docker compose"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
mkdir -p data logs
|
mkdir -p data logs
|
||||||
|
|
||||||
|
echo "正在启动本地 MySQL..."
|
||||||
|
MYSQL_IMAGE="$MYSQL_IMAGE" \
|
||||||
|
MYSQL_BIND_HOST="$MYSQL_BIND_HOST" \
|
||||||
|
MYSQL_HOST_PORT="$MYSQL_HOST_PORT" \
|
||||||
|
$COMPOSE up -d mysql
|
||||||
|
|
||||||
|
echo "等待 MySQL 就绪..."
|
||||||
|
for i in $(seq 1 30); do
|
||||||
|
if $COMPOSE exec -T mysql sh -c 'mysqladmin ping -h localhost -uroot -p"$MYSQL_ROOT_PASSWORD" --silent' >/dev/null 2>&1; then
|
||||||
|
echo "MySQL 已就绪"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
if [ "$i" = "30" ]; then
|
||||||
|
echo "MySQL 启动超时,查看日志:"
|
||||||
|
$COMPOSE logs --tail 50 mysql
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "=============================="
|
echo "=============================="
|
||||||
echo " 本地调试模式"
|
echo " 本地调试模式"
|
||||||
@@ -52,12 +129,22 @@ echo "=============================="
|
|||||||
echo " 后端: http://${BACKEND_HOST}:${BACKEND_PORT}"
|
echo " 后端: http://${BACKEND_HOST}:${BACKEND_PORT}"
|
||||||
echo " 前端: http://localhost:${FRONTEND_PORT}"
|
echo " 前端: http://localhost:${FRONTEND_PORT}"
|
||||||
echo " API 代理: http://127.0.0.1:${BACKEND_PORT}"
|
echo " API 代理: http://127.0.0.1:${BACKEND_PORT}"
|
||||||
|
echo " MySQL: ${DB_HOST}:${DB_PORT}/${DB_NAME}"
|
||||||
echo " 退出: Ctrl+C"
|
echo " 退出: Ctrl+C"
|
||||||
echo "=============================="
|
echo "=============================="
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
trap cleanup EXIT INT TERM
|
trap cleanup EXIT INT TERM
|
||||||
|
|
||||||
|
DB_HOST="$DB_HOST" \
|
||||||
|
DB_PORT="$DB_PORT" \
|
||||||
|
DB_NAME="$DB_NAME" \
|
||||||
|
DB_USER="$DB_USER" \
|
||||||
|
DB_PASSWORD="$DB_PASSWORD" \
|
||||||
|
DB_POOL_SIZE="$DB_POOL_SIZE" \
|
||||||
|
DB_MAX_OVERFLOW="$DB_MAX_OVERFLOW" \
|
||||||
|
DB_POOL_TIMEOUT="$DB_POOL_TIMEOUT" \
|
||||||
|
DB_POOL_RECYCLE="$DB_POOL_RECYCLE" \
|
||||||
LOG_LEVEL="$LOG_LEVEL" \
|
LOG_LEVEL="$LOG_LEVEL" \
|
||||||
uv run uvicorn web.backend.main:app \
|
uv run uvicorn web.backend.main:app \
|
||||||
--host "$BACKEND_HOST" \
|
--host "$BACKEND_HOST" \
|
||||||
|
|||||||
+4
-1
@@ -56,9 +56,12 @@ services:
|
|||||||
retries: 3
|
retries: 3
|
||||||
|
|
||||||
mysql:
|
mysql:
|
||||||
image: docker.m.daocloud.io/library/mysql:8.4
|
image: ${MYSQL_IMAGE:-docker.m.daocloud.io/library/mysql:8.4}
|
||||||
container_name: douyu-login-db
|
container_name: douyu-login-db
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
# 仅绑定宿主机本地地址,供 ./dev.sh 的本地后端连接,不对外网开放。
|
||||||
|
- "${MYSQL_BIND_HOST:-127.0.0.1}:${MYSQL_HOST_PORT:-3307}:3306"
|
||||||
environment:
|
environment:
|
||||||
- TZ=Asia/Shanghai
|
- TZ=Asia/Shanghai
|
||||||
- MYSQL_DATABASE=${MYSQL_DATABASE:-douyu_login}
|
- MYSQL_DATABASE=${MYSQL_DATABASE:-douyu_login}
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ from sqlalchemy import create_engine, event
|
|||||||
from sqlalchemy.orm import sessionmaker, declarative_base
|
from sqlalchemy.orm import sessionmaker, declarative_base
|
||||||
|
|
||||||
PROJECT_ROOT = Path(__file__).resolve().parents[2]
|
PROJECT_ROOT = Path(__file__).resolve().parents[2]
|
||||||
DB_PATH = PROJECT_ROOT / "data" / "web.db"
|
|
||||||
DB_PATH.parent.mkdir(parents=True, exist_ok=True)
|
|
||||||
|
|
||||||
|
|
||||||
def _env_int(name: str, default: int) -> int:
|
def _env_int(name: str, default: int) -> int:
|
||||||
@@ -40,7 +38,10 @@ def _get_database_url() -> str:
|
|||||||
f"@{db_host}:{db_port}/{db_name}?charset=utf8mb4"
|
f"@{db_host}:{db_port}/{db_name}?charset=utf8mb4"
|
||||||
)
|
)
|
||||||
|
|
||||||
return f"sqlite:///{DB_PATH}"
|
raise RuntimeError(
|
||||||
|
"未配置数据库连接。请设置 DATABASE_URL=mysql+pymysql://...,"
|
||||||
|
"或设置 DB_HOST、DB_NAME、DB_USER、DB_PASSWORD"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
DATABASE_URL = _get_database_url()
|
DATABASE_URL = _get_database_url()
|
||||||
|
|||||||
Reference in New Issue
Block a user