Add automatic database backup with download and restore docs.
Back up futures.db and uploads to /root/qihuo_backup on a daily schedule, expose backup downloads in settings, and document cross-server restore. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -54,6 +54,19 @@
|
||||
.settings-ctp-fold-body{padding:0 1rem .85rem}
|
||||
.settings-ctp-fold.is-collapsed .settings-ctp-fold-body{display:none}
|
||||
.settings-ctp-status{font-size:.82rem;color:var(--text-muted);margin-top:.75rem;line-height:1.5}
|
||||
.settings-backup-table{width:100%;border-collapse:collapse;font-size:.82rem;margin-top:.65rem}
|
||||
.settings-backup-table th,.settings-backup-table td{padding:.45rem .5rem;border-bottom:1px solid var(--border);text-align:left}
|
||||
.settings-backup-table th{color:var(--text-muted);font-weight:600}
|
||||
.settings-backup-restore{
|
||||
margin-top:.85rem;padding:.75rem .85rem;border-radius:8px;
|
||||
border:1px solid var(--border);background:var(--card-inner);
|
||||
font-size:.82rem;color:var(--text-muted);line-height:1.6;
|
||||
}
|
||||
.settings-backup-restore summary{cursor:pointer;color:var(--text-title);font-weight:600}
|
||||
.settings-backup-meta{font-size:.82rem;color:var(--text-muted);line-height:1.55;margin:.35rem 0 .65rem}
|
||||
.settings-backup-actions{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem .65rem}
|
||||
.settings-backup-download{color:var(--accent);text-decoration:none;font-weight:600}
|
||||
.settings-backup-download:hover{text-decoration:underline}
|
||||
@media(max-width:900px){
|
||||
.settings-password-form{grid-template-columns:1fr}
|
||||
.settings-ctp-cards-row{grid-template-columns:1fr}
|
||||
@@ -293,6 +306,75 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>数据备份与恢复</h2>
|
||||
<p class="settings-backup-meta">
|
||||
自动备份目录:<code>{{ backup_dir }}</code>
|
||||
{% if backup_last_at %} · 上次备份 {{ backup_last_at.replace('T', ' ') }}{% else %} · 尚未备份{% endif %}
|
||||
{% if backup_running %} · <span style="color:var(--accent)">备份进行中…</span>{% endif %}
|
||||
</p>
|
||||
<form action="{{ url_for('settings') }}" method="post" style="margin-bottom:.85rem">
|
||||
<input type="hidden" name="action" value="backup_config">
|
||||
<div class="split-grid" style="margin-bottom:.65rem">
|
||||
<div class="field">
|
||||
<label style="display:flex;align-items:center;gap:.45rem;cursor:pointer">
|
||||
<input type="checkbox" name="backup_auto_enabled" value="1" {% if backup_auto_enabled %}checked{% endif %}>
|
||||
<span>启用每日自动备份</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>自动备份时刻(0–23 点)</label>
|
||||
<input name="backup_auto_hour" type="number" min="0" max="23" step="1" value="{{ backup_auto_hour }}">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>保留最近份数</label>
|
||||
<input name="backup_keep_count" type="number" min="5" max="200" step="1" value="{{ backup_keep_count }}">
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn-primary">保存备份策略</button>
|
||||
</form>
|
||||
<div class="settings-backup-actions">
|
||||
<form action="{{ url_for('settings') }}" method="post">
|
||||
<input type="hidden" name="action" value="backup_now">
|
||||
<button type="submit" class="btn-primary" {% if backup_running %}disabled{% endif %}>立即备份</button>
|
||||
</form>
|
||||
</div>
|
||||
<p class="hint" style="margin:.65rem 0 0">备份包含 <code>futures.db</code> 与 <code>uploads/</code>,压缩包可在其他服务器恢复。默认恢复目录 <code>{{ backup_restore_dir }}</code>。</p>
|
||||
|
||||
{% if backup_items %}
|
||||
<table class="settings-backup-table">
|
||||
<thead>
|
||||
<tr><th>文件名</th><th>大小</th><th>时间</th><th></th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for item in backup_items %}
|
||||
<tr>
|
||||
<td><code>{{ item.name }}</code></td>
|
||||
<td>{{ item.size_mb }} MB</td>
|
||||
<td>{{ item.mtime.replace('T', ' ') }}</td>
|
||||
<td><a href="{{ url_for('api_backup_download', filename=item.name) }}" class="settings-backup-download">下载</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<p class="hint" style="margin-top:.65rem;margin-bottom:0">暂无备份文件,可点击「立即备份」生成第一份。</p>
|
||||
{% endif %}
|
||||
|
||||
<details class="settings-backup-restore">
|
||||
<summary>备份恢复说明</summary>
|
||||
<ol style="margin:.65rem 0 0 1.1rem;padding:0">
|
||||
<li>下载上方 <code>.tar.gz</code> 到目标服务器(如 <code>/root/</code>)。</li>
|
||||
<li>解压:<code>tar -xzf qihuo_backup_YYYYMMDD_HHMMSS.tar.gz</code></li>
|
||||
<li>进入目录执行:<code>chmod +x restore.sh && ./restore.sh</code>(默认恢复到 <code>{{ backup_restore_dir }}</code>)。</li>
|
||||
<li>指定目录:<code>RESTORE_DIR=/opt/qihuo ./restore.sh</code></li>
|
||||
<li>在新服务器部署 qihuo 代码与虚拟环境,配置 <code>.env</code> 后 <code>pm2 restart qihuo</code>。</li>
|
||||
<li>恢复前请停止 qihuo,避免覆盖正在使用的数据库。</li>
|
||||
</ol>
|
||||
<p style="margin:.65rem 0 0">完整说明见项目文档 <code>docs/BACKUP.md</code>;压缩包内亦含 <code>RESTORE.md</code>。</p>
|
||||
</details>
|
||||
</div>
|
||||
|
||||
<div class="split-grid">
|
||||
<div class="card">
|
||||
<h2>修改密码</h2>
|
||||
|
||||
Reference in New Issue
Block a user