Single-server installs older than v2.2.1 need a one-time installer refresh before they can follow the normal upgrade path. The setup.sh that shipped with those releases cannot fetch a newer online bundle on its own. Re-running bootstrap.sh replaces it with the current installer. After that, use updating the single-server install for later upgrades.
This applies only to the single-server (k3s) install. Kubernetes-with-Helm upgrades are unchanged — see upgrading on Kubernetes. Air-gapped servers skip this page and keep using the air-gapped update.
Back up /opt/3b/.env and the database before you start.
Refresh the installer
On the server, download the current bootstrap.sh and run it as root, targeting v2.2.1 (or a later release):
curl --proto '=https' --tlsv1.2 -fsSL \ https://sh.3b.dev \ -o /tmp/3b-bootstrap.sh sudo VERSION=v2.2.1 \ bash /tmp/3b-bootstrap.sh rm /tmp/3b-bootstrap.sh
The server needs outbound access to oci.tines.com, as it did at first install.
If /opt/3b/.env already has REGISTRY_USERNAME and REGISTRY_PASSWORD, bootstrap reuses them. Otherwise enter your Tines tenant name and Docker Registry API key when prompted. Configuration and secrets already in /opt/3b/.env are preserved; nothing rotates.
Verify
After the installer finishes, confirm the pods rolled out:
sudo k3s kubectl -n 3b get pods
Application pods should be Running, and the one-off migration job Completed. Then open the UI. See verifying the install.
Later upgrades
From here you do not re-run bootstrap.sh. Change VERSION in /opt/3b/.env and run:
sudo bash /opt/3b/setup.sh
You can also pass the version on the command line; setup.sh writes it into .env:
sudo VERSION=<new-version> bash /opt/3b/setup.sh
See updating the single-server install for the full online and air-gapped flow.
