Tasks are now stored in SQLite (DB_PATH env var, defaults to ./tasks.db). Pre-seeding runs only when the table is empty, so upgrades preserve data. This is the v1.0.0 baseline for the persistence demo. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
96 lines
2.9 KiB
Markdown
96 lines
2.9 KiB
Markdown
# demoapp — Clouderized Demo App
|
||
|
||
A task manager built with Scala 3 + Thorium, used to demonstrate Clouderized's core value prop: **stateful app upgrades with zero data loss**.
|
||
|
||
Tasks are persisted in SQLite backed by a Docker named volume (`demouser-data`). Rebuilding or upgrading the container leaves all user data intact.
|
||
|
||
## Prerequisites
|
||
|
||
- Access to `git.clouderized.com` (Gitea)
|
||
- The app deployed at `demouser.clouderized.com`
|
||
- VPS SSH access: `ssh -i ssh/id_rsa -p 9876 cldrzd@194.233.75.123`
|
||
|
||
---
|
||
|
||
## v1 → v2 Upgrade Demo (with data persistence)
|
||
|
||
This is the primary demo sequence. It shows that Clouderized can upgrade a running app without wiping user data.
|
||
|
||
### 1. Deploy v1.0.0
|
||
|
||
On the VPS:
|
||
|
||
```bash
|
||
cd ~/customers/demouser/demoapp && git fetch --tags && git checkout v1.0.0
|
||
cd ~/customers/demouser && docker compose up -d --build
|
||
```
|
||
|
||
Visit `https://demouser.clouderized.com`:
|
||
- **Teal header**, version badge shows **v1.0.0**
|
||
- Three pre-seeded tasks are present
|
||
- `/health` returns `{"status":"ok"}`
|
||
|
||
### 2. Add user data
|
||
|
||
In the browser, add 2–3 tasks and delete one of the pre-seeded tasks. This simulates real user activity before an upgrade.
|
||
|
||
### 3. Upgrade to v2.0.0
|
||
|
||
On the VPS:
|
||
|
||
```bash
|
||
cd ~/customers/demouser/demoapp && git checkout v2.0.0
|
||
cd ~/customers/demouser && docker compose up -d --build
|
||
```
|
||
|
||
Revisit `https://demouser.clouderized.com`:
|
||
- **Blue header**, version badge shows **v2.0.0**
|
||
- All tasks added in step 2 are still there
|
||
- Pre-seeded tasks are not re-added (seeding is skipped when the table is non-empty)
|
||
|
||
### 4. Verify persistence
|
||
|
||
```bash
|
||
# On the VPS — confirm the volume exists and is mounted
|
||
docker volume inspect demouser-data
|
||
```
|
||
|
||
---
|
||
|
||
## How Persistence Works
|
||
|
||
| Component | Detail |
|
||
|-----------|--------|
|
||
| Storage | SQLite at `/data/tasks.db` inside the container |
|
||
| Volume | Docker named volume `demouser-data` mounted at `/data` |
|
||
| Env var | `DB_PATH=/data/tasks.db` (set in `docker-compose.yml`) |
|
||
| Seeding | Pre-seed runs only when the `tasks` table is empty |
|
||
|
||
The named volume `demouser-data` survives `docker compose up --build` — data is never lost on rebuild.
|
||
|
||
---
|
||
|
||
## Config Reference
|
||
|
||
All visual changes are driven by `src/main/resources/site.conf`:
|
||
|
||
| Key | v1.0.0 | v2.0.0 | What it controls |
|
||
|-----|--------|--------|-----------------|
|
||
| `app.version` | `"1.0.0"` | `"2.0.0"` | Version badge in header |
|
||
| `app.theme.background` | `"#0F766E"` (teal) | `"#1D4ED8"` (blue) | Header and button color |
|
||
|
||
## Endpoints
|
||
|
||
| Method | Path | Description |
|
||
|--------|------|-------------|
|
||
| GET | `/` | Task list (HTML) |
|
||
| GET | `/health` | Health check (JSON) |
|
||
| POST | `/tasks` | Create task (form) |
|
||
| POST | `/tasks/:id/toggle` | Toggle completion |
|
||
| POST | `/tasks/:id/delete` | Delete task |
|
||
|
||
## Notes
|
||
|
||
- The app runs on the **Pro tier** (2GB RAM, 2 vCPU) since JVM needs the headroom.
|
||
- Local dev uses `./tasks.db` (relative path) when `DB_PATH` is not set.
|