Solves the problem of chat history loss caused by Huawei Cloud DevEnv container rebuilds. Uses a GitHub private repository for automatic backups, completely free. Supports GLM Proxy service backup, container keep-alive, and one-click automatic restore.
Root Cause of the Problem
Huawei Cloud DevEnv uses an overlay file system. When the container is rebuilt, the overlay layer data is cleared, causing:
- All chat session files (sessions/) disappear
- Databases such as memory.db and audit.db are lost
- Configuration files such as .bashrc are reset
- GLM Proxy service configuration is lost
This is not a bug, it is a design characteristic of overlay FS. After a container rebuild, only the data in the image layer is retained.
Solution Architecture
┌──────────────────────────────────────────────────┐
│ DevEnv 容器 │
│ │
│ ┌──────────────┐ ┌──────────────────┐ │
│ │ 聊天数据 │───→│ chat-backup.sh │ │
│ │ sessions/ │ │ (备份/恢复) │ │
│ │ memory.db │ └────────┬─────────┘ │
│ │ GLM Proxy │ │ │
│ └──────────────┘ │ │
│ ▼ │
│ ┌──────────────┐ ┌──────────────────┐ │
│ │ keepalive.sh │ │ auto-restore.sh │ │
│ │ (保活守护) │ │ (一键恢复) │ │
│ └──────────────┘ └────────┬─────────┘ │
│ │ │
└────────────────────────────────┼──────────────────┘
│
▼
┌────────────────────────┐
│ GitHub 私有仓库 │
│ (免费、可靠、可追溯) │
└────────────────────────┘
Why Choose a GitHub Private Repository?
| Solution | Pros | Cons | Conclusion |
|---|---|---|---|
| GitHub private repository | Free, reliable, git version control | Requires token configuration | ✅ Adopted |
| Huawei Cloud OBS | Object storage, reliable | Paid, requires additional configuration | ❌ Rejected |
| Local backup | Simple | Lost along with container rebuild | ❌ Rejected |
Quick Start
1. Create a GitHub Private Repository
Create a private repository on GitHub (e.g. ai-shell-backup), and generate a Personal Access Token (requires repo permission).
2. Deploy the Backup Script
# 配置 Git 凭证
git config --global credential.helper store
echo "https://YOUR_TOKEN@github.com" > ~/.git-credentials
# 克隆仓库
git clone https://YOUR_TOKEN@github.com/YOUR_USER/YOUR_REPO.git /root/chat-backup-new
# 复制全部脚本到 /root/
cp /root/chat-backup-new/scripts/*.sh /root/
chmod +x /root/*.sh
# 修改脚本顶部的 REPO_URL 为你自己的仓库地址
# (编辑 /root/chat-backup.sh 第 19 行的 REPO_URL)
# 一键设置(首次备份 + 启动守护进程 + 配置 .bashrc + 开启免确认)
/root/chat-backup.sh setup
⚠️ Please replace
YOUR_TOKEN、YOUR_USER、YOUR_REPOwith your own values!
3. Configure One-Click Automatic Restore
# 将 auto-restore.sh 加入 .bashrc,容器重启自动恢复
echo '' >> /root/.bashrc
echo '# 容器重启自动恢复' >> /root/.bashrc
echo 'bash /root/auto-restore.sh 2>/dev/null' >> /root/.bashrc
4. Restore After Container Rebuild
Method 1: Automatic restore(recommended)
After the container restarts, .bashrc automatically executes auto-restore.sh, with no manual operation required.
Method 2: Manual restore
bash /root/auto-restore.sh
auto-restore.sh will restore in sequence: chat data → GLM Proxy → keep-alive daemon → backup daemon
Core Features
Chat Backup + GLM Proxy Backup
| Command | Description |
|---|---|
chat-backup.sh setup |
Initial setup: automatic approval + backup + start daemon + configure .bashrc |
chat-backup.sh backup |
Immediately back up current data to Git (chat data + GLM Proxy configuration) |
chat-backup.sh restore |
Restore the latest data from Git (safe merge + GLM Proxy restore) |
chat-backup.sh daemon |
Start the background daemon (backup every 120 seconds) |
chat-backup.sh status |
View backup status |
chat-backup.sh auto-approve |
Enable automatic approval (no confirmation required, modifies settings.json) |
chat-backup.sh fix-visibility |
Fix session visibility (clear metadata.source="acp") |
chat-backup.sh prune |
Clean up excess sessions (interactive confirmation, keep the most recent N with the most messages) |
chat-backup.sh delete |
Interactively delete sessions (supports keyword/date/empty session filtering) |
One-Click Automatic Recovery 🆕
| Command | Description |
|---|---|
auto-restore.sh |
One-click recovery of all services (chat data + GLM Proxy + keepalive + backup daemon) |
auto-restore.sh execution flow:
- Detect and restore chat data (chat-backup.sh restore)
- Detect and start GLM Proxy service
- Start keepalive daemon (keepalive.sh setup)
- Start backup daemon (chat-backup.sh daemon)
- Configure .bashrc automatic recovery
Disconnect Prevention Keepalive
| Command | Description |
|---|---|
keepalive.sh setup |
Disconnect prevention keepalive setup (tmux + heartbeat + .bashrc + process daemon) |
keepalive.sh status |
View keepalive status |
keepalive.sh log |
View disconnect/recovery records |
keepalive.sh attach |
Enter tmux session |
GitHub Acceleration (Mirror Fallback)
| Command | Description |
|---|---|
gclone <url> [dir] |
git clone with mirror fallback |
gpull [remote] [branch] |
git pull with mirror fallback |
gfetch [remote] [branch] |
git fetch with mirror fallback |
gpush [remote] [branch] |
git push with retry (mirror does not support push) |
graw <url> [-o file] |
Download raw file with mirror fallback |
ggit <subcmd> ... |
General git accelerator (automatically selects the above functions) |
Backup Contents
| File | Description |
|---|---|
sessions/*.jsonl |
Chat session records (original timestamps preserved) |
sessions-index.md |
Human-readable session index: ID → Chinese title → date → message count |
sessions-index.json |
Machine-readable session index (JSON format) |
memory.db |
Semantic memory database (sessions + messages tables) |
audit.db |
Audit log database |
settings.json |
User settings |
SOUL.md |
Agent persona configuration |
user_info.json |
User information |
scripts/glm-proxy/ |
🆕 GLM Proxy service script backup |
tmp-data/*.txt |
🆕 GLM Proxy key/token backup |
Script List
| Script | Lines | Description |
|---|---|---|
chat-backup.sh |
284 | Chat data + GLM Proxy backup/restore core |
keepalive.sh |
85 | Container keepalive + process daemon |
github-accel.sh |
152 | GitHub acceleration (mirror + proxy fallback) |
auto-restore.sh |
132 | 🆕 One-click recovery of all services after container restart |
Key Lessons and Pitfall Avoidance Guide
⚠️ All the following lessons come from actual pitfalls encountered; see references/pitfalls.md
- rsync unavailable → use
cp -rfinstead (DevEnv minimal environment has no rsync) - git commands hang without a timeout → add
timeout 30s - Daemon CWD is lost → at startup
cd /root - crontab unavailable → use
setsid + nohup + while 循环instead - curl restricted by DNS → restore commands must use
git clone, cannot use curl - .bashrc is on the overlay layer → .bashrc is lost after container rebuild; the restore command must be run manually once
- GIT_TERMINAL_PROMPT=0 → prevents the daemon from hanging due to git waiting for input
- Zombie git processes accumulate → prevent with timeout + manually clean up index.lock
- .bashrc auto restore corrupts data → only put daemon in .bashrc; make restore manual (pitfall 11)
- restore skipping the database causes the title to be lost → switched to safe merging via SQLite ATTACH, no longer skipping (pitfall 15)
- sessions.title has a title but the UI still shows the ID → the messages table is empty, populate it from the .jsonl (pitfall 16)
- exec tmux attach disconnects → changed to a prompt, without replacing the shell process (pitfall 12)
- metadata.source="acp" makes the session invisible → clear metadata to
{}(pitfall 17) - DevEnv UI shows at most 10 sessions → automatically prune old sessions with few messages (pitfall 18)
- GLM Proxy service lost on restart → auto-restore.sh restores it automatically (pitfall 19)
References
| Documentation | Description |
|---|---|
| pitfalls.md | All the pitfalls encountered and their solutions |
| architecture.md | Detailed explanation of the solution architecture and design decisions |
| recovery-guide.md | Recovery steps after container rebuild |