a1f22624de
Co-authored-by: Cursor <cursoragent@cursor.com>
113 lines
3.6 KiB
Bash
113 lines
3.6 KiB
Bash
#!/usr/bin/env bash
|
|
# qihuo · PostgreSQL 一键部署 / 从 SQLite 迁移
|
|
# 用法: sudo bash scripts/deploy_postgres.sh
|
|
# 可选: MIGRATE_SQLITE=1 自动从 /opt/qihuo/futures.db 迁移
|
|
|
|
set -euo pipefail
|
|
|
|
APP_DIR="${APP_DIR:-/opt/qihuo}"
|
|
PG_DB="${PG_DB:-qihuo}"
|
|
PG_USER="${PG_USER:-qihuo}"
|
|
PG_HOST="${PG_HOST:-127.0.0.1}"
|
|
PG_PORT="${PG_PORT:-5432}"
|
|
MIGRATE_SQLITE="${MIGRATE_SQLITE:-0}"
|
|
|
|
if [ "$(id -u)" -ne 0 ]; then
|
|
echo "请使用 root: sudo bash scripts/deploy_postgres.sh"
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -d "$APP_DIR" ]; then
|
|
echo "错误: 应用目录不存在 $APP_DIR,请先 bash deploy.sh"
|
|
exit 1
|
|
fi
|
|
|
|
echo "==> 安装 PostgreSQL..."
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
apt-get update -qq
|
|
apt-get install -y postgresql postgresql-contrib
|
|
|
|
echo "==> 创建数据库与用户..."
|
|
if [ -z "${PG_PASSWORD:-}" ]; then
|
|
PG_PASSWORD="$(python3 -c 'import secrets; print(secrets.token_urlsafe(16))')"
|
|
fi
|
|
|
|
sudo -u postgres psql -v ON_ERROR_STOP=1 <<SQL
|
|
DO \$\$
|
|
BEGIN
|
|
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = '${PG_USER}') THEN
|
|
CREATE ROLE ${PG_USER} LOGIN PASSWORD '${PG_PASSWORD}';
|
|
ELSE
|
|
ALTER ROLE ${PG_USER} WITH PASSWORD '${PG_PASSWORD}';
|
|
END IF;
|
|
END
|
|
\$\$;
|
|
SELECT 'CREATE DATABASE ${PG_DB} OWNER ${PG_USER}'
|
|
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '${PG_DB}')\\gexec
|
|
GRANT ALL PRIVILEGES ON DATABASE ${PG_DB} TO ${PG_USER};
|
|
SQL
|
|
|
|
DATABASE_URL="postgresql://${PG_USER}:${PG_PASSWORD}@${PG_HOST}:${PG_PORT}/${PG_DB}"
|
|
|
|
echo "==> 写入 .env DATABASE_URL..."
|
|
ENV_FILE="$APP_DIR/.env"
|
|
if grep -q "^DATABASE_URL=" "$ENV_FILE" 2>/dev/null; then
|
|
sed -i "s|^DATABASE_URL=.*|DATABASE_URL=${DATABASE_URL}|" "$ENV_FILE"
|
|
else
|
|
echo "" >>"$ENV_FILE"
|
|
echo "# PostgreSQL(生产推荐,消除 SQLite 并发锁)" >>"$ENV_FILE"
|
|
echo "DATABASE_URL=${DATABASE_URL}" >>"$ENV_FILE"
|
|
echo "PG_POOL_MIN=2" >>"$ENV_FILE"
|
|
echo "PG_POOL_MAX=20" >>"$ENV_FILE"
|
|
fi
|
|
|
|
echo "==> Python 依赖..."
|
|
# shellcheck disable=SC1091
|
|
source "$APP_DIR/venv/bin/activate"
|
|
pip install -q -r "$APP_DIR/requirements.txt"
|
|
|
|
if [ "$MIGRATE_SQLITE" = "1" ]; then
|
|
echo "==> 重置 PostgreSQL 库(迁移模式)..."
|
|
sudo -u postgres psql -v ON_ERROR_STOP=0 -c \
|
|
"SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname='${PG_DB}' AND pid <> pg_backend_pid();" \
|
|
>/dev/null 2>&1 || true
|
|
sudo -u postgres dropdb --if-exists "${PG_DB}"
|
|
sudo -u postgres createdb -O "${PG_USER}" "${PG_DB}"
|
|
fi
|
|
|
|
echo "==> 初始化 PostgreSQL 表结构..."
|
|
cd "$APP_DIR"
|
|
export DATABASE_URL
|
|
export QIHUO_SKIP_INIT_DB=1
|
|
python3 -c "from app import init_db; init_db(); from db_conn import database_label; print('OK:', database_label())"
|
|
unset QIHUO_SKIP_INIT_DB
|
|
|
|
if [ "$MIGRATE_SQLITE" = "1" ] && [ -f "$APP_DIR/futures.db" ]; then
|
|
echo "==> 从 SQLite 迁移数据..."
|
|
python3 "$APP_DIR/scripts/migrate_sqlite_to_postgres.py" --sqlite "$APP_DIR/futures.db"
|
|
if [ "${BACKUP_SQLITE:-1}" = "1" ]; then
|
|
BAK="$APP_DIR/futures.db.pre_pg.$(date +%Y%m%d_%H%M%S)"
|
|
cp -a "$APP_DIR/futures.db" "$BAK"
|
|
echo " 已备份旧库: $BAK"
|
|
fi
|
|
elif [ -f "$APP_DIR/futures.db" ]; then
|
|
echo "提示: 检测到 futures.db,如需迁移请: MIGRATE_SQLITE=1 bash scripts/deploy_postgres.sh"
|
|
fi
|
|
|
|
echo "==> 重启 PM2..."
|
|
if pm2 describe qihuo &>/dev/null; then
|
|
pm2 restart ecosystem.config.cjs --update-env
|
|
else
|
|
pm2 start "$APP_DIR/ecosystem.config.cjs"
|
|
fi
|
|
pm2 save
|
|
|
|
echo ""
|
|
echo "=========================================="
|
|
echo " PostgreSQL 部署完成"
|
|
echo " DATABASE_URL=${DATABASE_URL}"
|
|
echo " 请妥善保存数据库密码: ${PG_PASSWORD}"
|
|
echo " 文档: docs/POSTGRES.md"
|
|
echo " 备份: 系统设置页 或 pg_dump / 自动备份"
|
|
echo "=========================================="
|