3 Commits

Author SHA1 Message Date
mac
668576b866 v1.0.3 — 修复 gunicorn 多 worker session 丢失
- secret_key 从 os.urandom() 改为固定值/环境变量
- deploy.sh 首次部署自动生成 .env 并持久化
- 解决多 worker 下 session 解密失败导致保存 302
2026-06-02 23:40:14 +08:00
mac
abdc1fc739 v1.0.2 — 数据库 schema 版本迁移机制
- 新增 schema_version 表记录数据库版本
- init_db() 自动检测版本并执行对应迁移
- 全新安装/版本升级/无变更重启 三场景均安全幂等
- CURRENT_SCHEMA_VERSION=1,将来改表时 +1 补迁移即可
2026-06-02 23:39:09 +08:00
mac
082d7fa133 v1.0.1 — 部署脚本 & 环境兼容
- 新增 deploy.sh 一键部署:自动 venv/依赖/数据库/启动
- app.py 端口从环境变量 PORT 读取
2026-06-02 23:36:35 +08:00
3 changed files with 114 additions and 11 deletions

6
app.py
View File

@@ -9,7 +9,8 @@ from werkzeug.security import generate_password_hash, check_password_hash
from database import init_db, get_checkin, save_checkin, delete_checkin, get_all_checkins
app = Flask(__name__)
app.secret_key = os.urandom(24)
# 固定密钥确保 gunicorn 多 worker 下 session 可互通
app.secret_key = os.environ.get('SECRET_KEY', 'ziwei-power-secret-2026')
# 会话持久化30 天
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days=30)
@@ -179,4 +180,5 @@ def api_user():
if __name__ == '__main__':
init_db()
app.config['TEMPLATES_AUTO_RELOAD'] = True
app.run(host='0.0.0.0', port=5058, debug=False)
port = int(os.environ.get('PORT', 5058))
app.run(host='0.0.0.0', port=port, debug=False)

View File

@@ -10,6 +10,9 @@ DB_DIR = os.path.join(os.path.expanduser('~'), '.workbuddy', 'data', 'ziwei-powe
os.makedirs(DB_DIR, exist_ok=True)
DB_PATH = os.path.join(DB_DIR, 'ziwei_power.db')
# 当前数据库 schema 版本 —— 改表结构时必须 +1 并补迁移逻辑
CURRENT_SCHEMA_VERSION = 1
def get_conn():
conn = sqlite3.connect(DB_PATH)
@@ -17,18 +20,49 @@ def get_conn():
return conn
def init_db():
"""初始化数据库表"""
conn = get_conn()
def _get_schema_version(conn):
"""读取当前数据库的 schema 版本,无表时返回 0"""
conn.execute('''
CREATE TABLE IF NOT EXISTS checkins (
id INTEGER PRIMARY KEY AUTOINCREMENT,
date TEXT UNIQUE NOT NULL,
data TEXT NOT NULL,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
CREATE TABLE IF NOT EXISTS schema_version (
version INTEGER NOT NULL
)
''')
row = conn.execute('SELECT version FROM schema_version').fetchone()
return row['version'] if row else 0
def _set_schema_version(conn, version):
"""写入 schema 版本"""
conn.execute('DELETE FROM schema_version')
conn.execute('INSERT INTO schema_version (version) VALUES (?)', (version,))
def init_db():
"""初始化数据库表 & 自动迁移"""
conn = get_conn()
current = _get_schema_version(conn)
# ── 迁移步骤(按版本号递增)────────────────────────
if current < 1:
# v1: 初始表结构
conn.execute('''
CREATE TABLE IF NOT EXISTS checkins (
id INTEGER PRIMARY KEY AUTOINCREMENT,
date TEXT UNIQUE NOT NULL,
data TEXT NOT NULL,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
)
''')
# ── 将来加字段/改表在此扩展 ──
# if current < 2:
# conn.execute('ALTER TABLE checkins ADD COLUMN tags TEXT DEFAULT ""')
# # 可选:对已有行做数据补全
# conn.execute("UPDATE checkins SET tags = '[]' WHERE tags IS NULL")
# ── 写入最新版本号 ──
_set_schema_version(conn, CURRENT_SCHEMA_VERSION)
conn.commit()
conn.close()

67
deploy.sh Normal file
View File

@@ -0,0 +1,67 @@
#!/bin/bash
# ziwei-power 一键部署脚本
# 用法: bash deploy.sh [port]
#
# 首次运行: 自动生成 .env (SECRET_KEY),之后不变
# 多 worker 安全: 所有 worker 共享同一密钥
set -e
PORT="${1:-5058}"
PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)"
LOG_FILE="/tmp/ziwei-power.log"
echo "=== ziwei-power 部署 ==="
echo "目录: $PROJECT_DIR"
echo "端口: $PORT"
# 1. 停止旧进程
OLD_PID=$(lsof -ti :$PORT 2>/dev/null || true)
if [ -n "$OLD_PID" ]; then
echo "停止旧进程 PID=$OLD_PID..."
kill $OLD_PID 2>/dev/null || true
sleep 1
fi
# 2. 创建/激活 venv
cd "$PROJECT_DIR"
if [ ! -d "venv" ]; then
echo "创建虚拟环境..."
python3 -m venv venv
fi
echo "安装依赖..."
venv/bin/pip install -q -r requirements.txt
# 3. 生成/读取固定 SECRET_KEY多 worker 共享)
if [ ! -f ".env" ]; then
echo "生成 SECRET_KEY..."
python3 -c "import os; print('SECRET_KEY=' + os.urandom(24).hex())" > .env
fi
set -a; source .env; set +a
export SECRET_KEY
# 4. 自动建表(首次运行)
echo "初始化数据库..."
venv/bin/python -c "
from database import init_db
init_db()
print('数据库就绪')
"
# 4. 启动服务
echo "启动服务 (PID=$$)..."
nohup venv/bin/python app.py > "$LOG_FILE" 2>&1 &
NEW_PID=$!
sleep 1
if kill -0 $NEW_PID 2>/dev/null; then
echo "部署完成!"
echo " 访问: http://localhost:$PORT"
echo " 日志: $LOG_FILE"
echo " PID : $NEW_PID"
else
echo "启动失败,查看日志:"
cat "$LOG_FILE"
exit 1
fi