Better-PaaS

Updates

Keep Better-PaaS up to date with one-click, self-healing updates.

Better-PaaS can update itself from the dashboard or from your server terminal. If an in-app update goes wrong, it rolls itself back automatically.

The easiest and most reliable way to update a git-checkout install is to SSH into your server, pull the latest code, and re-run the installer from your Better-PaaS directory:

cd ~/better-paas
git pull
sudo bash install.sh

Replace ~/better-paas with the path where you cloned the repo, if different. The installer rebuilds the backend and frontend, restarts the Better-PaaS services, and leaves your repo-root data/ directory untouched (the same path Docker Compose uses). If an older git install kept data under backend/data/, install.sh migrates it automatically.

When to use this

Prefer the terminal flow after first install, if the dashboard UI did not change after an in-app update, or whenever you want the same update path the installer uses on a fresh setup.

Services disappeared after install.sh?

That usually means the backend was reading a different data/ folder than before (for example backend/data/ vs repo-root data/ after switching from Docker). Re-run install.sh from your clone so paths are aligned, or restore a backup from Backups → Restore.

After install.sh finishes, hard-refresh the dashboard in your browser (Cmd+Shift+R or Ctrl+Shift+R) so you load the new frontend assets.

Updating from the dashboard

Go to Settings → Software Updates.

Click Check for updates. Better-PaaS queries GitHub Releases for a newer version (results are cached for 30 minutes).

If an update is available, click Update now.

What "Update now" does

The update is careful and self-healing. In order, it:

flowchart TD
  A[Back up data/ first, always] --> B[git fetch + checkout new tag]
  B --> C[Rebuild backend + frontend]
  C --> D[Restart services]
  D --> E{Health check /api/health}
  E -->|Healthy| F[Done - running new version]
  E -->|Unhealthy| G[Restore previous binary + ref, restart]
  1. Takes a backup of your data/ directory first - always.
  2. Launches a detached helper that runs git fetch and checks out the new release tag.
  3. Rebuilds the backend (swapping in the new binary only on a successful build, keeping server.bak) and rebuilds the frontend out-of-band into .next.new - the running dashboard keeps serving its current assets, untouched, for the entire build.
  4. Atomically swaps the new frontend build in and restarts the frontend before restarting the backend, so the version badge and dashboard UI stay in sync.
  5. Restarts the services and health-checks the new build at /api/health.
  6. If the new build doesn't come up, it automatically restores the previous binary, frontend build, and git ref and restarts - so a bad release rolls itself back.

Your data is never touched

Updates never modify your data/ directory. Schema changes are applied by additive migrations on the next boot, so upgrading is safe.

Requirements

Git-checkout installs only

One-click update is available only for git-checkout installs, because it currently rebuilds from source on the host. That means the server needs the Go / Node / pnpm toolchain present (the installer sets this up for you). Downloading prebuilt release binaries is a planned follow-up.

How releases work

Releases are tag-triggered, not produced on every push. Pushing a tag matching v* runs the release workflow:

git tag v1.2.3
git push origin v1.2.3   # this builds and publishes the release

A normal push to main does not create a release. Each release cross-compiles the backend for Linux and macOS (amd64 + arm64), bakes the version into the binary, and publishes the binaries plus a SHA256SUMS file to GitHub Releases.

Keep tags semver-shaped (vMAJOR.MINOR.PATCH) - the updater parses major.minor.patch for version comparison.

Choosing the update source

The updater checks the repo named by UPDATE_REPO. It's resolved in this order:

  1. The UPDATE_REPO environment variable
  2. A stored value
  3. The checkout's git remote origin URL

So git installs work even without the variable set. To pin it explicitly:

/etc/systemd/system/better-paas-backend.service
Environment=UPDATE_REPO=your-org/better-paas

Next step

On this page