- Cleaned 242MB of recursive data/data/data/ nesting
- Added nesting-guard.js: auto-detects and removes recursive duplicates at startup
- Wired VM sandbox cleanup into uninstall wizard (calls vmDestroy before regular uninstall)
- Container stats, health data, and VM disk all cleaned on uninstall
- Add VM provisioning module (vm-provisioner.js) with 3 platform strategies:
* Windows: WSL2 distro with fixed VHDX
* macOS: Lima VM with fixed disk
* Linux: loopback ext4 image
- Add IPC handlers (vm-ipc.js) for Electron wizard integration
- Add disk budget wizard step (disk-budget-step.js) with presets
- Wire VM handlers into main process (index.js)
- Add preload bridges for VM operations
- Update install.sh with --disk-size flag and sandbox functions
- Add disk safety env vars to docker-compose template
- Add memory limits to prevent OOM during startup
Users can now pick a disk budget (10GB/30GB/100GB/custom) and DashCaddy
creates a sandboxed VM that physically cannot exceed that limit.
Uninstall cleanly removes the entire VM/disk with zero leakage.
ARCHITECTURE:
- Windows: dedicated WSL2 distro with fixed VHDX, Docker inside
- macOS: Lima VM with fixed disk, Docker inside
- Linux: sparse ext4 loopback image, Docker data-root inside
NEW FILES:
- vm-provisioner.js: core provisioning engine (create/start/destroy/export)
- Disk presets: Minimal(10GB), Balanced(30GB), Power(100GB), Custom
- Sparse images that grow on demand (start at ~0 bytes)
- Full lifecycle: provision → deploy DashCaddy → destroy (clean removal)
- Data export before uninstall for users who want to migrate
- vm-ipc.js: Electron IPC handlers connecting wizard to provisioner
- vm:provision, vm:destroy, vm:get-status, vm:export-data, vm:get-presets
- disk-budget-step.js: wizard UI step with preset cards + custom slider
- Real-time free space check against selected disk size
- Plain English description of what each tier handles
UPDATED:
- caddyfile-generator.js: docker-compose now includes disk safety env vars
(health retention, stats caps, memory limits) as defense-in-depth
even inside the VM sandbox
GUARANTEE: DashCaddy physically cannot exceed the storage budget.
The OS enforces the limit at the disk/image level, not our code.
- dashcaddy-installer/install.sh: 1.1.0 → 1.14.6 (matches current release)
- dashcaddy-api/VERSION: 10f72af → a5f51e4 (current HEAD with TOTP security fixes)
The host source tree was rebuilt from the published v1.14.6 tarball to fix a
deletion gap where /opt/dashcaddy/dashcaddy-api/{routes,src}/ were gutted by an
interrupted prior update cycle. Container was unaffected (built from image).
After the DC-005 module reorganization (41 files moved into src/ subdirs),
138 test suites failed because the refactor script's path-rewrite logic
missed three categories:
1. Files inside src/ doing 'require("./src/...")' — should be 'require("../...")'
2. Files in src/X/Y/ doing 'require("../../../src/...")' — should be 'require("../../...")'
3. Test files in __tests__/ with leftover 'require("../../../src/...")' paths
Root cause: the original refactor script ran before all files were moved,
so it computed relative paths against stale filesystem state.
Result:
- 30/30 test suites pass
- 879/879 tests pass (was: 18/30 suites, 614/687 tests)
Also fixed:
- routes/apps/restore.js: wrong responses import path
- routes/*/*.js: '../../src/utilities/X' → '../src/utilities/X' (depth 2 routes)
The 1.5.0 API cutover removed the legacy `/api` mount, but the
`dashcaddy_auth` Caddy snippet generated by the installer still called
`uri /api/auth/gate/{args[0]}`. forward_auth then hit the notFoundHandler
and propagated a DC-404 to the browser instead of a 401-redirect to the
login flow (seen on requests.sami).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- install.sh now deploys the src/ directory alongside routes/.
Without this, fresh installs of v1.3.0+ produce containers whose
Dockerfile references src/ but the directory is missing on the host
filesystem, so docker build fails with "/src: not found".
- The fallback heredoc that writes /etc/systemd/system/dashcaddy-
updater.path drops MakeDirectory=yes for the same reason it was
removed from the on-disk unit (e994ad1): systemd creates the watched
trigger.json path as an empty directory on unit start, blocking
every subsequent update with EISDIR.
Bumped to 1.3.1 so the existing v1.3.0 instance auto-updates and
picks up these and the host-script fix from 0cf6323.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When the in-container self-updater downloads a new version, it writes
trigger.json. The new systemd path unit watches for this file and runs
dashcaddy-update.sh, which backs up current API files, copies the new
ones, rebuilds the container, verifies health, and writes result.json.
Automatic rollback on build or health check failure.
Also fixes undefined `isWindows` variable in self-updater.js and adds
DASHCADDY_HOST_UPDATES_DIR env var to the installer's docker-compose
template for correct container-to-host path translation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- self-updater.js: polls for new versions, downloads/verifies tarballs,
triggers host-side rebuild via systemd path unit
- dashcaddy-update.sh + systemd units: host-side container rebuild with
automatic rollback on health check failure
- 7 new /api/v1/system/* endpoints for version info, update check/apply,
rollback, and update history
- Frontend: DashCaddy tab in Updates modal with version display,
changelog, update button, rollback, and notification dot
- install.sh: updater service installation, volume mounts, env vars
- build-release.sh + webhook-handler.js: release server pipeline
(Gitea webhook → build tarball → deploy to get.dashcaddy.net)
- Dockerfile: DASHCADDY_COMMIT build arg → VERSION file
- Version bump to 1.1.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Full codebase including API server (32 modules + routes), dashboard frontend,
DashCA certificate distribution, installer script, and deployment skills.