mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-07-26 11:49:16 +00:00
32a7d53b2b
* feat: add RBAC viewer accounts, atomic deployments, and fleet-wide backups (Pro) Introduces three Pro-tier features: - RBAC: Multi-user system with admin/viewer roles, user management UI, automatic migration from single-admin credentials, viewer restrictions across the entire UI (read-only editor, hidden action buttons) - Atomic Deployments: Pre-deploy file backup to .sencho-backup/, automatic rollback on health probe failure, manual rollback button, health probes added to stack updates, webhook-triggered deploys use atomic rollback - Fleet-Wide Backups: Point-in-time snapshots of compose files across all nodes (local + remote), stored centrally in SQLite, per-stack restore with optional redeploy, graceful handling of offline nodes * fix(settings): use correct ProGate prop name in UsersSection * fix(settings): remove unused isPro prop from UsersSection * fix(auth): fetch user info after login and setup so isAdmin is set correctly * feat(pricing): revise pricing strategy and enforce variant-based seat limits Raise Personal Pro from $49/yr to $69/yr with 3 viewer seats (up from 1). Add $15/mo billing option for Team Pro. Mark lifetime pricing as a 90-day early-adopter offer. Store Lemon Squeezy variant_name on activation/validation and enforce seat limits server-side per variant. * feat(licensing): add Lemon Squeezy checkout, webhook, and billing portal integration Server-side checkout URL generation (POST /api/checkout) with admin email pre-fill and instance_id custom data. HMAC-SHA256 verified webhook endpoint (POST /api/webhooks/lemonsqueezy) handling order, subscription, and payment lifecycle events for automatic license activation. Customer billing portal link stored from webhook events and exposed via GET /api/billing/portal. In-app checkout buttons in Settings with manual license key fallback. * fix(licensing): exempt Lemon Squeezy webhook from auth middleware The catch-all auth middleware on /api/* was blocking the public webhook endpoint. Added /webhooks/lemonsqueezy to the exemption list alongside /auth/* and /webhooks/:id/trigger. * feat(pricing): update pricing to final live rates Personal Pro: $7.99/month, $69.99/year, $249 lifetime. Team Pro: $49.99/month, $499.99/year, $1,499 lifetime. Added personal_monthly checkout variant across backend, frontend, and website. * refactor(licensing): remove server-side checkout/webhook for self-hosted model Sencho is self-hosted — each user runs their own instance, so there is no central server to receive webhooks or hold the store API key. Replaced in-app checkout buttons with a "View Pricing" redirect to sencho.io and kept manual license key activation as the primary flow. - Delete LemonSqueezyService (checkout, webhook, HMAC verification) - Remove POST /api/checkout, GET /api/billing/portal, POST /api/webhooks/lemonsqueezy - Remove raw body parser and auth exemption for webhook route - Remove all LEMONSQUEEZY_* env vars from .env.example - Replace checkout buttons in SettingsModal with single "View Pricing" button - Simplify LicenseContext checkout to open sencho.io pricing page - Update licensing docs to reflect website-based purchase flow * chore: normalize em-dashes to hyphens across codebase (linter) * chore: remove accidentally tracked directories from index
140 lines
4.2 KiB
Plaintext
140 lines
4.2 KiB
Plaintext
---
|
|
title: Backup & Restore
|
|
description: What to back up, how to restore it, and how to migrate Sencho to a new host.
|
|
---
|
|
|
|
Sencho stores all its state in two places: the **data directory** (SQLite database) and your **compose directory** (your actual stack files). Both need to be backed up for a complete recovery.
|
|
|
|
---
|
|
|
|
## What to back up
|
|
|
|
### 1. Data directory (`DATA_DIR`)
|
|
|
|
Default path: `/app/data` inside the container, mapped to wherever you mounted it on the host (e.g. `./sencho-data`).
|
|
|
|
Contains:
|
|
- `sencho.db` - SQLite database with all settings, nodes, alerts, metrics history, and notification history
|
|
|
|
This single file is everything Sencho knows about itself. Back it up and you can fully restore any Sencho installation.
|
|
|
|
### 2. Compose directory (`COMPOSE_DIR`)
|
|
|
|
The directory containing your stack subdirectories - your `compose.yaml` files, `.env` files, and any bind-mounted config files stored there.
|
|
|
|
This is your actual application data. It lives entirely outside Sencho and you almost certainly already have it on a schedule, but include it in any Sencho backup plan.
|
|
|
|
---
|
|
|
|
## Backing up
|
|
|
|
### Simple file copy
|
|
|
|
```bash
|
|
# Stop Sencho to ensure the SQLite WAL is flushed (recommended but not strictly required)
|
|
docker stop sencho
|
|
|
|
# Copy the data directory
|
|
cp -r /path/to/sencho-data /path/to/backup/sencho-data-$(date +%Y%m%d)
|
|
|
|
# Copy compose stacks
|
|
cp -r /opt/compose /path/to/backup/compose-$(date +%Y%m%d)
|
|
|
|
# Restart
|
|
docker start sencho
|
|
```
|
|
|
|
### SQLite online backup (without stopping)
|
|
|
|
SQLite supports hot backups via its `.backup` command. This is safe to run while Sencho is running:
|
|
|
|
```bash
|
|
sqlite3 /path/to/sencho-data/sencho.db ".backup '/path/to/backup/sencho.db'"
|
|
```
|
|
|
|
### Automated daily backup (cron example)
|
|
|
|
```cron
|
|
0 3 * * * sqlite3 /path/to/sencho-data/sencho.db ".backup '/backups/sencho-$(date +\%Y\%m\%d).db'" && find /backups -name "sencho-*.db" -mtime +30 -delete
|
|
```
|
|
|
|
This backs up the database at 3 AM daily and deletes backups older than 30 days.
|
|
|
|
---
|
|
|
|
## Restoring
|
|
|
|
### Restore from backup
|
|
|
|
1. Stop Sencho:
|
|
```bash
|
|
docker stop sencho
|
|
```
|
|
|
|
2. Replace the data directory with your backup:
|
|
```bash
|
|
rm -rf /path/to/sencho-data/*
|
|
cp /path/to/backup/sencho.db /path/to/sencho-data/sencho.db
|
|
```
|
|
|
|
3. Restore your compose directory if needed:
|
|
```bash
|
|
cp -r /path/to/backup/compose /opt/compose
|
|
```
|
|
|
|
4. Start Sencho:
|
|
```bash
|
|
docker start sencho
|
|
```
|
|
|
|
Sencho will read the restored database and resume with all your previous settings, nodes, and alert rules intact.
|
|
|
|
---
|
|
|
|
## Migrating to a new host
|
|
|
|
### Step 1: Prepare the new host
|
|
|
|
Install Docker and Docker Compose on the new machine. Create the same directory structure you use for your compose files, following the [1:1 path rule](/getting-started/configuration#compose-directory-the-11-path-rule).
|
|
|
|
### Step 2: Copy data
|
|
|
|
Transfer your backup files to the new host:
|
|
|
|
```bash
|
|
scp -r /path/to/sencho-data newhost:/path/to/sencho-data
|
|
scp -r /opt/compose newhost:/opt/compose
|
|
```
|
|
|
|
### Step 3: Deploy Sencho on the new host
|
|
|
|
Use the same `docker-compose.yml` you used on the old host (with the same `COMPOSE_DIR` and `DATA_DIR` paths):
|
|
|
|
```bash
|
|
docker compose up -d
|
|
```
|
|
|
|
### Step 4: Update remote node references
|
|
|
|
If other Sencho instances were pointing to your old host as a remote node, update their node config to use the new host's IP or hostname. Generate a new API token on the restored instance and distribute it.
|
|
|
|
### Step 5: Verify
|
|
|
|
- Log in and confirm your stacks, nodes, and alerts are all present
|
|
- Check that at least one stack deploys correctly
|
|
- Verify the node switcher shows the expected nodes with green status
|
|
|
|
---
|
|
|
|
## What is NOT backed up by this process
|
|
|
|
| Item | Location | Notes |
|
|
|------|----------|-------|
|
|
| Container data volumes | Wherever each stack's volumes are mounted on the host | Back these up separately per-application |
|
|
| Actual container images | Docker image cache | These are re-pulled on next deploy - no backup needed |
|
|
| Sencho logs (docker logs) | Container stdout | Not persisted beyond container lifetime |
|
|
|
|
<Note>
|
|
Sencho does not currently have a built-in backup scheduler or export function. The approaches above use standard OS tools and SQLite's own backup mechanism.
|
|
</Note>
|