Maintenance

Updating

This page describes exactly what happens when you apply an update package, in the order it happens. Read it before you run an update on a live installation — applying one makes real, irreversible changes to your files and database with no built-in rollback.

Before you update

Back up your database and your entire install directory before you start. There is no undo. If the SQL step or the file copy fails partway through (see If something goes wrong, below), the only way back is a backup.

Updates apply one version at a time, in order. Every package under Updates/ in the release is built against one specific starting version and named for that transition — for example Updates/v3.9.8-fix-102525 to v3.10.0/update.zip is only safe to apply to an install that is currently running v3.9.8-fix-102525. Nothing in the updater checks this for you (see What an update package contains), so if your site is several versions behind, apply each package in sequence — don't skip ahead to the newest one. Your installed version is shown as Installed on the System card at Admin → Overview.

Running an update requires a super admin account (the original admin created at install time) — anyone else gets "You don't have permission for this action!".

Applying an update

Go to Admin → Overview. The System card there has an Update button, which opens a form with a single file field. Choose the update.zip from the Updates/ folder matching your currently installed version, submit, and wait — don't navigate away or close the tab. Only a .zip file is accepted; anything else is rejected before it's even saved.

In order, the update process then:

  1. Saves the upload, failing with "Failed uploading update file!" if it isn't there afterward.
  2. Extracts it. If extraction fails, the failure is logged — but the process carries on to the next step regardless of whether the extraction actually produced anything.
  3. Copies everything under the package's files/ folder over your live installation, file by file, overwriting anything with the same path. Copy failures here are silently ignored — nothing is written to the log for this step.
  4. Checks for manual.conf. If it's present, you're redirected immediately to the changelog URL written inside that file, and the process stops — instructions.conf and remove.conf are never read on this path. See the warning below.
  5. Otherwise, reads instructions.conf line by line. A database line imports update.sql; a cache line wipes and recreates the system cache. SQL import failures are logged as "Update SQL Error"; cache-clear failures are silently ignored.
  6. Reads remove.conf line by line and deletes each path listed, now that files/ has already been copied in. Entries must be individual files, not directories; missing files and failed deletes are silently ignored.
  7. Deletes the extracted temporary files and responds with success.
On success the dashboard shows a toast and then reloads the page automatically once you dismiss it — this is the "wait for the page to reload" step. There's no progress bar in between; the request is synchronous, so the tab will simply sit on the loading state until the whole sequence above has finished.
If the response tells you the update requires manual intervention, that means the package included manual.conf and none of the database changes, cache clearing, or file removals below were applied. You'll be redirected to a changelog page after a few seconds — follow the manual steps written there, since the updater itself didn't do them for you.

Nothing in this process writes a new version number anywhere. The version shown throughout the dashboard is read straight from a version file in your installation, and the only reason it changes after an update is that a new copy of that file is sitting inside the package's files/ tree and gets copied over the old one in step 3 above. If a package is missing that file, or you build one by hand, your installed version won't advance even though everything else updated.

What an update package contains

EntryPurpose
files/New and changed files, copied over your installation.
update.sqlDatabase changes, applied only if instructions.conf lists database.
instructions.confTells the updater whether to run update.sql and/or clear the system cache — one keyword (database or cache) per line.
remove.confIndividual file paths, one per line, deleted after files/ has been copied in — files that existed in the previous version and don't exist in this one.
manual.confIf present, a changelog URL. Its mere presence short-circuits the whole handler before instructions.conf or remove.conf run — used for versions that need steps a script can't safely perform.

None of these files are required to exist — every check above is an if(...exists(...)) guard, so a package can ship just files/ and nothing else if that's all a given version needs.

If something goes wrong

Check your installation's error log first. Of everything that can go wrong during an update, only two failure points are actually written there:

  • "System Update Error: ..." — the uploaded zip couldn't be opened/extracted (corrupt upload, or not actually a zip despite the extension).
  • "Update SQL Error: ..." — update.sql failed to import (bad database credentials, or the SQL itself doesn't apply cleanly to your current schema).

Everything else that can fail — the initial upload, copying files/ over your installation, clearing the cache directory, and every individual delete in remove.conf — is either reported straight back to the browser (the upload) or fails silently, with nothing written to the log. An update that "does nothing" after you submit it, with no error log entry at all, most likely means the zip extracted and the files copied, but the response never made it back to your browser (a server timeout on a slow connection, for instance) — check whether your files actually changed before re-uploading the same package.

If the site is stuck showing a maintenance message afterward, see Troubleshooting for what updating.lock does and how to clear it.