Upgrading¶
install.sh is idempotent. To upgrade to the latest main, re-run it on the host:
What re-running does:
- Creates/reuses the dedicated
nova-veservice user, then fast-forwards the cloned repo at${NOVA_VE_REPO_DIR}(default/var/lib/nova-ve/nova-ve-git; legacy~${SUDO_USER}/nova-ve-gitcheckouts are reused during migration when present). - Re-runs
provision-ubuntu-2604.shto top up OS-level packages and migrate/var/lib/nova-veownership to the service user. - Reapplies the backend venv (
pip install -r requirements.txt) and Alembic migrations. - Rebuilds the frontend (
npm ci && vite build) and rsyncs it into/var/lib/nova-ve/www. - Reinstalls the privileged network helper and sudoers fragment, including NAT-Cloud DHCP, NAT, and forwarding verbs.
- Restarts Docker,
nova-ve-backend, andcaddy. - Reconciles existing NAT-Cloud bridges from lab JSON files, re-applying IPv4 forwarding, NAT, DOCKER-USER forwarding rules, and dnsmasq leases where the bridge already exists.
It does not rotate existing secrets, drop the database, or touch lab JSON files. The upgraded backend also reconciles deterministic Docker node names at start time: a running same-name nova-ve container is adopted into runtime state, while a stopped stale same-name container is removed before docker run.
When upgrading an older host that ran nova-ve-backend as the installer user, the installer migrates the unit, repo, and /var/lib/nova-ve ownership to the dedicated service user. Already-running QEMU nodes may still be owned by the old user until they are stopped; the privileged helper includes a registry-authorized QEMU signal path so the new backend can still stop those migrated runtimes.
The smoke check at the end exits non-zero if anything broke.
Pinning to a specific release¶
Set NOVA_VE_REPO_REF before piping the installer:
NOVA_VE_REPO_REF accepts a branch, tag, or SHA.
Manual upgrade (without the installer)¶
If you prefer to drive the upgrade yourself:
cd /var/lib/nova-ve/nova-ve-git
git fetch origin
git checkout v0.4.0 # or main, or a specific SHA
# Backend
cd backend
.venv/bin/pip install -r requirements.txt
.venv/bin/alembic upgrade head
# Frontend
cd ../frontend
npm ci
npm run build
sudo rsync -a --delete build/ /var/lib/nova-ve/www/
# Restart
sudo systemctl restart nova-ve-backend
The manual path above is enough for application code, migrations, and the static frontend. It does not reinstall /opt/nova-ve/bin/nova-ve-net.py, refresh /etc/sudoers.d/nova-ve, or run the installer-side NAT-Cloud bridge reconciliation. Use the full installer path when upgrading across host-networking changes such as NAT-Cloud DHCP/NAT/forwarding or Docker runtime reconciliation.
The Caddy unit reloads itself on file changes and does not need restarting after a frontend rebuild.
What can go wrong¶
- Alembic migration fails — investigate with
journalctl -u nova-ve-backend -n 100. Common cause: out-of-order migration heads after a long detour. The contract is thatnova-ve-backenddoes not self-migrate; you mustalembic upgrade headmanually before restarting. - Frontend build fails — usually a Node version drift. The provisioner installs Node 22.x from NodeSource; if you bumped Node manually, ensure it still satisfies
package.json'senginesfield. - Caddy refuses to start — port 80 / 443 already in use.
sudo ss -ltnp | grep -E ':(80|443) 'finds the offender. - NAT-Cloud clients get DHCP but no internet — re-run the installer so the current helper is installed and NAT-Cloud reconciliation reapplies IPv4 forwarding, masquerade NAT, Docker
DOCKER-USERforwarding rules, anddnsmasqstate for existing bridges. - Docker node start fails with a container-name conflict — make sure the backend is upgraded and restarted. The current runtime path adopts a running same-name nova-ve container or removes a stopped stale same-name container before starting the node.
When in doubt, Troubleshooting has the recipes.