Documentation

Updating QueryGlow

Every 1.x update is included in your license. On the server, one command in your QueryGlow checkout does the whole update in both deployment modes:

./queryglow update

It backs up first, checks the nginx config before anything restarts, keeps the running image, builds the new one and checks that the new version is actually serving. If it is not, it rolls back on its own. Your domain, deployment mode and app port are detected automatically. QueryGlow itself never phones home: the update check is a git fetch against your own remote, and it runs only when you ask for it.

What a run looks like

The queryglow command ships with 1.3.0, so a 1.2.1 install reaches 1.3.0 with ./update.sh first. From then on, an update prints output like this (the release test run from 1.2.1 to 1.3.0). The example shows the versions of the 1.2.1 to 1.3.0 step (output shortened, the domain is a placeholder):

$ ./queryglow update --checkInstalled: 1.2.1 (v1.2.1, 05d13c0) on branch mainAvailable: 1.3.0 (v1.3.0, 6060169) on origin/main→ Update available. Run: ./queryglow update $ ./queryglow update→ Backing up to backups/20260925-081057/ …→ Fast-forwarding main to 1.3.0 (v1.3.0, 6060169) ...→ Re-rendering nginx config for db.your-company.com (app port 3000)…→ Validating the rendered config…  config OK→ Building the new image (the running containers keep serving until it succeeds) ...→ Starting the new release ...→ Waiting for http://127.0.0.1:3000/api/health ...✓ Update complete: 1.3.0 (v1.3.0, 6060169). Backup: backups/20260925-081057

Coming from 1.2.x? Run ./update.sh once; it installs the queryglow command.

./queryglow update --check only asks. It exits with code 10 when a newer release is available, so you can run it from a cron job or a monitor.

What ./queryglow update does, step by step

  1. Refuses a checkout with local changes.

    If tracked files were edited, it stops before anything happens and tells you how to stash or discard the changes. Its own backups/ and .queryglow/ directories do not count.

  2. Fetches the newest release.

    git fetch against the remote your checkout tracks. If the newest release is already installed and running, it stops with "Already up to date" and changes nothing.

  3. Backs up first.

    .env, the git ref and version of the release being replaced, and a copy of the app data go to backups/<timestamp>/. In standalone mode the rendered nginx config, the htpasswd file and the certificates go in as well.

  4. Fast-forwards to the new release.

    git merge --ff-only, or the tag you asked for. Settings that are new since your version are listed with a pointer to .env.example; existing values in .env are never changed.

  5. Re-renders and validates nginx before any restart (standalone mode).

    The new nginx config is checked with nginx -t first. An invalid config is restored in place, the checkout returns to the previous release, nothing restarts and your site keeps serving.

  6. Keeps the running image and builds the new one.

    The running image is tagged queryglow:previous. The old containers keep serving while the new image builds, so a failed build is not an outage.

  7. Starts the new release and waits for the health check.

    It starts the new containers, reloads nginx in standalone mode and waits up to 90 seconds for /api/health (set QG_HEALTH_TIMEOUT to change the wait).

  8. Checks the running version.

    /api/version must report the version of the new checkout.

  9. Rolls back on its own if a check fails.

    After a failed build, health check or version check it returns to the previous commit and the queryglow:previous image and restores the previous nginx config. Your app data is not touched by a rollback.

  10. Writes a receipt.

    Every update that changes something writes .queryglow/receipts/<timestamp>.json (from and to version, backup path, outcome) and appends to .queryglow/update.log.

If the checkout is already current but the running app is not (a container is down, unhealthy or on another version), the command rebuilds and starts it. Nothing is deleted: backups/ grows by one directory per update, and the command prints its size and the line to remove old snapshots.

What an update does not do

It does not back up the databases QueryGlow connects to, only QueryGlow's own settings and data. It does not run by itself: nothing changes until you type the command. The containers are recreated during the switch.

Integration mode (your own system nginx)

The command rebuilds and health-checks the app container only. Your nginx site and its htpasswd file live under /etc/nginx, outside the repository, so they are neither changed nor backed up. Your site needs the /api/mcp block for Agent Access, the /api/health block for external monitors, and the two browser icon blocks that keep Safari on iOS from asking for the password twice. The command lists them at the end of every run; the Docker guide shows all four, and ./queryglow doctor reports a site file that lacks the health or agent block.

Update options

CommandWhat it does
./queryglow update --checkOnly reports whether a newer release is available. Exit code 10 when one is.
./queryglow update --dry-runPrints the seven step plan and changes nothing.
./queryglow update --tag v1.3.0Updates to that release, or downgrades to it after a confirmation (the checkout is then pinned on that tag). The next plain ./queryglow update returns to the newest release. Tags before v1.3.0 do not contain the queryglow command. After a downgrade to v1.2.1, return with git checkout main && ./update.sh.
./queryglow update --yesAnswers the confirmations. Required when the command runs without an interactive terminal.

The rest of the queryglow command

The command needs bash, git, Docker with the compose plugin and curl on the host, no Node.js. ./queryglow install offers to link it into /usr/local/bin, so queryglow status works from any directory.

CommandWhat it does
status [--json]Install directory, mode, domain and port, installed and running version, containers, nginx, certificate expiry, last backup and last update. --json gives the same for monitoring and scripts.
doctor [--fix] [--report]Checks the host and the install: Docker, tools, .env permissions and secrets, containers, health, versions, ports, nginx config, DNS, certificate and free disk. --fix applies exactly four safe repairs: start Docker at boot, set .env to mode 600, give the app data back to the app user, set backups/ and .queryglow/ to mode 700. --report prints a support report without a single .env value.
backupSnapshot of .env, the app data and (standalone mode) the nginx files to backups/<timestamp>/.
restore <backup-dir>Puts the app data from a snapshot back, after a confirmation. --env, --htpasswd and --nginx restore those too (the last two in standalone mode). Certificates are not restored.
rollback [<backup-dir>]Returns to the release recorded in the newest snapshot (or the one you name), reusing queryglow:previous when it matches. It does not restore the app data.
logs [queryglow|nginx|certbot] [-f]Last 100 lines of a container log; -f follows.
versionInstalled and running version.
config check-on-status [on|off]Whether status may run git fetch to report newer releases. Off by default; the installer asks once.

Exit codes: 0 ok, 1 failed, 2 usage error, 10 update available (update --check only).

Updating from 1.2.1 or older

Installs before 1.3.0 do not have the queryglow command yet. Run the old updater once. On 1.2.1 it backs up, fetches the new release fast-forward only, rebuilds and waits for the health check, and the new release brings the queryglow command with it:

./update.sh

# from now on
./queryglow update

On 1.2.0, ./update.sh works in standalone mode only and pulls and rebuilds without a backup (./queryglow backup does not exist there yet), so copy .env somewhere safe first. Integration installs on 1.2.0: email [email protected].

In 1.3.0, ./update.sh forwards to ./queryglow update with the same options, so existing scripts keep working.

Installs from 1.0 and 1.1 have no update.sh, it first shipped in 1.2.0. If you still run one of those, email [email protected] and we move it to the current release together.