Import Wizard — migrate from Umbrel or Nextcloud
Already running another self-hosted server? The import wizard at /setup/import pulls your apps, files, calendars, and contacts into Quazzar without touching the source side. Phase В.3 of the GA roadmap.
What’s supported
| Source | Apps | Files | Calendars | Contacts | Status |
|---|---|---|---|---|---|
| Umbrel | ✅ (5 templates mapped) | ✅ (data volumes copied) | — | — | shipped |
| Nextcloud | — | ✅ (WebDAV) | ✅ (CalDAV) | ✅ (VCF in Drive) | shipped |
| CasaOS | — | — | — | — | Phase В.3.b |
| Synology DSM | — | — | — | — | Phase В.3.b |
Walkthrough
- Open Setup wizard (or browse to
/setup/importdirectly). - Pick a source on the SourcePicker screen.
- Fill in the source-specific form:
- Umbrel — single field: source path. Default
~/umbrel/; use an absolute path if your install lives elsewhere. - Nextcloud — three fields: URL, username, app password. Use an app password, NOT your login password (Settings → Security → Devices & sessions → Create new app password in Nextcloud).
- Umbrel — single field: source path. Default
- Click Preview. Quazzar runs
Probeand renders a manifest:- Apps — per-app rows with mapping decision (
install/skip with reason). - Files — total bytes + count.
- Calendars + Contacts — counts.
- Warnings — soft incompatibilities the user should review.
- Apps — per-app rows with mapping decision (
- Click Start import. The run goes background; the screen shows live progress via SSE.
You can leave the screen — the import keeps running and the dashboard banners when it finishes.
Source-specific detail
Umbrel
Reads <root>/app-data/<app>/umbrel-app.yml and maps:
| Umbrel app | Quazzar template |
|---|---|
bitwarden / vaultwarden | vaultwarden |
pi-hole | pi-hole |
plex | plex |
jellyfin | jellyfin |
home-assistant / homeassistant | home-assistant |
tailscale | skipped — Quazzar ships native VPN |
nextcloud | skipped — use the Nextcloud importer |
Apps not in the table produce a warning (“no Quazzar template for X”). Data volumes are copied to ~/Quazzar/imports/umbrel/<app>/ preserving mtime. The bandwidth cap (10 MB/s by default) prevents the file copy from saturating the host.
Nextcloud
Three protocols, same wizard:
- WebDAV (
/remote.php/dav/files/<user>/) — depth-first walk via PROPFIND; per-fileGETstreams through the rate-limit reader to~/Quazzar/Drive/Nextcloud/<original-path>. - CalDAV (
/remote.php/dav/calendars/<user>/) — calendars become local Calendar collections; events POST through the Calendar service. - CardDAV (
/remote.php/dav/addressbooks/users/<user>/) — VCARDs are written as.vcffiles under~/Quazzar/Drive/Nextcloud/contacts/<book>/. (Native contacts UI ships in a later release.)
Resume support: per-file SHA-256 checkpoint in migrate_files_seen. A retry on a paused or failed run skips already-pulled files.
Plans
| Tier | Umbrel | Nextcloud |
|---|---|---|
| Free (Community) | ✅ unlimited | ≤ 50 GB total imported bytes |
| Pro / Team / Enterprise | ✅ | ✅ unlimited |
The 50 GB Free cap is enforced in the runner: when total progress.Current hits the cap, the run pauses and the wizard surfaces an upgrade modal. This matches Drive’s existing storage gate (Free Drive = 50 GB).
API
POST /api/migrate/probe → Manifest
POST /api/migrate/start → 202 { run_id } (admin)
GET /api/migrate/runs → list
GET /api/migrate/runs/:id → snapshot OR SSE (Accept: text/event-stream)
POST /api/migrate/runs/:id/cancel → 204
POST /api/migrate/runs/:id/retry → 202 (admin)Run state persists in migrate_runs; per-file resume in migrate_files_seen.
What happens to the source side
Nothing. Imports are one-shot pulls; Quazzar becomes the source of truth after the run completes. We don’t write back to Umbrel/Nextcloud — when you’re satisfied with the import, shut the source down on your own time.