chore: rename quicproquo → quicprochat in docs, Docker, CI, and packaging
Rename all project references from quicproquo/qpq to quicprochat/qpc across documentation, Docker configuration, CI workflows, packaging scripts, operational configs, and build tooling. - Docker: crate paths, binary names, user/group, data dirs, env vars - CI: workflow crate references, binary names, artifact names - Docs: all markdown files under docs/, SDK READMEs, book.toml - Packaging: OpenWrt Makefile, init script, UCI config (file renames) - Scripts: justfile, dev-shell, screenshot, cross-compile, ai_team - Operations: Prometheus config, alert rules, Grafana dashboard - Config: .env.example (QPQ_* → QPC_*), CODEOWNERS paths - Top-level: README, CONTRIBUTING, ROADMAP, CLAUDE.md
This commit is contained in:
@@ -1,15 +1,15 @@
|
||||
# Backup and Restore Procedures
|
||||
|
||||
This document covers backup and restore for all quicproquo server data stores.
|
||||
This document covers backup and restore for all quicprochat server data stores.
|
||||
|
||||
## Data Inventory
|
||||
|
||||
| Data | Location | Backend | Contains |
|
||||
|------|----------|---------|----------|
|
||||
| SQLCipher DB | `QPQ_DB_PATH` (default `data/qpq.db`) | `store_backend=sql` | Users, key packages, delivery queues, sessions, KT log, OPAQUE setup, blobs metadata, moderation |
|
||||
| File store | `QPQ_DATA_DIR` (default `data/`) | `store_backend=file` | Bincode-serialized key packages, delivery queues, server state |
|
||||
| Blob storage | `QPQ_DATA_DIR/blobs/` | Filesystem | Uploaded file transfer blobs |
|
||||
| TLS certificates | `QPQ_TLS_CERT`, `QPQ_TLS_KEY` | DER files | Server identity |
|
||||
| SQLCipher DB | `QPC_DB_PATH` (default `data/qpc.db`) | `store_backend=sql` | Users, key packages, delivery queues, sessions, KT log, OPAQUE setup, blobs metadata, moderation |
|
||||
| File store | `QPC_DATA_DIR` (default `data/`) | `store_backend=file` | Bincode-serialized key packages, delivery queues, server state |
|
||||
| Blob storage | `QPC_DATA_DIR/blobs/` | Filesystem | Uploaded file transfer blobs |
|
||||
| TLS certificates | `QPC_TLS_CERT`, `QPC_TLS_KEY` | DER files | Server identity |
|
||||
| OPAQUE ServerSetup | Inside DB or file store | Persisted | OPAQUE credential state (critical for auth) |
|
||||
| Server signing key | Inside DB or file store | Persisted | Ed25519 key for delivery proofs |
|
||||
| KT Merkle log | Inside DB or file store | Persisted | Key transparency audit log |
|
||||
@@ -22,13 +22,13 @@ SQLCipher supports the `.backup` command while the server is running (WAL mode a
|
||||
|
||||
```bash
|
||||
# 1. Open the encrypted database with the same key
|
||||
sqlite3 data/qpq.db
|
||||
sqlite3 data/qpc.db
|
||||
|
||||
# 2. At the sqlite3 prompt, set the encryption key
|
||||
PRAGMA key = 'your-db-key-here';
|
||||
|
||||
# 3. Perform an online backup
|
||||
.backup /backups/qpq-$(date +%Y%m%d-%H%M%S).db
|
||||
.backup /backups/qpc-$(date +%Y%m%d-%H%M%S).db
|
||||
|
||||
.quit
|
||||
```
|
||||
@@ -39,11 +39,11 @@ PRAGMA key = 'your-db-key-here';
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
BACKUP_DIR="/backups/qpq"
|
||||
DB_PATH="${QPQ_DB_PATH:-data/qpq.db}"
|
||||
DB_KEY="${QPQ_DB_KEY}"
|
||||
BACKUP_DIR="/backups/qpc"
|
||||
DB_PATH="${QPC_DB_PATH:-data/qpc.db}"
|
||||
DB_KEY="${QPC_DB_KEY}"
|
||||
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
|
||||
BACKUP_FILE="${BACKUP_DIR}/qpq-${TIMESTAMP}.db"
|
||||
BACKUP_FILE="${BACKUP_DIR}/qpc-${TIMESTAMP}.db"
|
||||
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
@@ -58,40 +58,40 @@ sqlite3 "$BACKUP_FILE" "PRAGMA key = '${DB_KEY}'; PRAGMA integrity_check;" \
|
||||
|| { echo "ERROR: backup verification failed"; exit 1; }
|
||||
|
||||
# Retain last 7 daily backups
|
||||
find "$BACKUP_DIR" -name 'qpq-*.db' -mtime +7 -delete
|
||||
find "$BACKUP_DIR" -name 'qpc-*.db' -mtime +7 -delete
|
||||
```
|
||||
|
||||
### Cold Backup (Offline)
|
||||
|
||||
```bash
|
||||
# 1. Stop the server
|
||||
systemctl stop qpq-server # or docker compose stop server
|
||||
systemctl stop qpc-server # or docker compose stop server
|
||||
|
||||
# 2. Copy the database file
|
||||
cp data/qpq.db /backups/qpq-$(date +%Y%m%d).db
|
||||
cp data/qpc.db /backups/qpc-$(date +%Y%m%d).db
|
||||
|
||||
# 3. Copy the WAL and SHM files if they exist
|
||||
cp data/qpq.db-wal /backups/ 2>/dev/null || true
|
||||
cp data/qpq.db-shm /backups/ 2>/dev/null || true
|
||||
cp data/qpc.db-wal /backups/ 2>/dev/null || true
|
||||
cp data/qpc.db-shm /backups/ 2>/dev/null || true
|
||||
|
||||
# 4. Restart the server
|
||||
systemctl start qpq-server
|
||||
systemctl start qpc-server
|
||||
```
|
||||
|
||||
## File Backend Backup
|
||||
|
||||
When using `store_backend=file`, data is stored as bincode files under `QPQ_DATA_DIR`.
|
||||
When using `store_backend=file`, data is stored as bincode files under `QPC_DATA_DIR`.
|
||||
|
||||
```bash
|
||||
# Full directory backup
|
||||
tar czf /backups/qpq-data-$(date +%Y%m%d-%H%M%S).tar.gz \
|
||||
-C "$(dirname "${QPQ_DATA_DIR:-data}")" \
|
||||
"$(basename "${QPQ_DATA_DIR:-data}")"
|
||||
tar czf /backups/qpc-data-$(date +%Y%m%d-%H%M%S).tar.gz \
|
||||
-C "$(dirname "${QPC_DATA_DIR:-data}")" \
|
||||
"$(basename "${QPC_DATA_DIR:-data}")"
|
||||
```
|
||||
|
||||
## Blob Storage Backup
|
||||
|
||||
Blobs are stored in `QPQ_DATA_DIR/blobs/`. These are immutable once written.
|
||||
Blobs are stored in `QPC_DATA_DIR/blobs/`. These are immutable once written.
|
||||
|
||||
```bash
|
||||
# Incremental rsync (blobs are write-once, ideal for rsync)
|
||||
@@ -117,38 +117,38 @@ cp data/federation-ca.der /backups/tls/federation-ca.der 2>/dev/null || true
|
||||
|
||||
```bash
|
||||
# 1. Stop the server
|
||||
systemctl stop qpq-server
|
||||
systemctl stop qpc-server
|
||||
|
||||
# 2. Move the current (corrupt/lost) database aside
|
||||
mv data/qpq.db data/qpq.db.broken 2>/dev/null || true
|
||||
rm -f data/qpq.db-wal data/qpq.db-shm
|
||||
mv data/qpc.db data/qpc.db.broken 2>/dev/null || true
|
||||
rm -f data/qpc.db-wal data/qpc.db-shm
|
||||
|
||||
# 3. Copy the backup in place
|
||||
cp /backups/qpq-20260304.db data/qpq.db
|
||||
cp /backups/qpc-20260304.db data/qpc.db
|
||||
|
||||
# 4. Verify integrity
|
||||
sqlite3 data/qpq.db "PRAGMA key = '${QPQ_DB_KEY}'; PRAGMA integrity_check;"
|
||||
sqlite3 data/qpc.db "PRAGMA key = '${QPC_DB_KEY}'; PRAGMA integrity_check;"
|
||||
|
||||
# 5. Start the server (migrations will apply automatically if needed)
|
||||
systemctl start qpq-server
|
||||
systemctl start qpc-server
|
||||
```
|
||||
|
||||
### Restore File Backend
|
||||
|
||||
```bash
|
||||
# 1. Stop the server
|
||||
systemctl stop qpq-server
|
||||
systemctl stop qpc-server
|
||||
|
||||
# 2. Replace the data directory
|
||||
mv data data.broken 2>/dev/null || true
|
||||
tar xzf /backups/qpq-data-20260304.tar.gz -C .
|
||||
tar xzf /backups/qpc-data-20260304.tar.gz -C .
|
||||
|
||||
# 3. Restore TLS certs if not included in the data backup
|
||||
cp /backups/tls/server-cert.der data/server-cert.der
|
||||
cp /backups/tls/server-key.der data/server-key.der
|
||||
|
||||
# 4. Start the server
|
||||
systemctl start qpq-server
|
||||
systemctl start qpc-server
|
||||
```
|
||||
|
||||
### Restore Blobs Only
|
||||
@@ -170,16 +170,16 @@ rsync -av /backups/blobs/ data/blobs/
|
||||
|
||||
```cron
|
||||
# SQLCipher hot backup every 6 hours
|
||||
0 */6 * * * /opt/qpq/scripts/backup-db.sh >> /var/log/qpq-backup.log 2>&1
|
||||
0 */6 * * * /opt/qpc/scripts/backup-db.sh >> /var/log/qpc-backup.log 2>&1
|
||||
|
||||
# Full data directory daily at 02:00
|
||||
0 2 * * * tar czf /backups/qpq-data-$(date +\%Y\%m\%d).tar.gz -C /var/lib quicproquo
|
||||
0 2 * * * tar czf /backups/qpc-data-$(date +\%Y\%m\%d).tar.gz -C /var/lib quicprochat
|
||||
|
||||
# Blob sync every hour
|
||||
0 * * * * rsync -a /var/lib/quicproquo/blobs/ /backups/blobs/
|
||||
0 * * * * rsync -a /var/lib/quicprochat/blobs/ /backups/blobs/
|
||||
|
||||
# Prune backups older than 30 days
|
||||
0 3 * * 0 find /backups -name 'qpq-*' -mtime +30 -delete
|
||||
0 3 * * 0 find /backups -name 'qpc-*' -mtime +30 -delete
|
||||
```
|
||||
|
||||
## Verification
|
||||
@@ -188,11 +188,11 @@ Always verify backups after creation:
|
||||
|
||||
```bash
|
||||
# SQLCipher integrity check
|
||||
sqlite3 /backups/qpq-latest.db \
|
||||
"PRAGMA key = '${QPQ_DB_KEY}'; PRAGMA integrity_check; SELECT count(*) FROM users;"
|
||||
sqlite3 /backups/qpc-latest.db \
|
||||
"PRAGMA key = '${QPC_DB_KEY}'; PRAGMA integrity_check; SELECT count(*) FROM users;"
|
||||
|
||||
# File backend: check the archive is valid
|
||||
tar tzf /backups/qpq-data-latest.tar.gz > /dev/null
|
||||
tar tzf /backups/qpc-data-latest.tar.gz > /dev/null
|
||||
|
||||
# TLS cert: check it parses and is not expired
|
||||
openssl x509 -inform DER -in /backups/tls/server-cert.der -noout -dates
|
||||
|
||||
Reference in New Issue
Block a user