Skip to content

Updating

Updating a server means pulling new source from Git, building a new originchats-osl, and restarting. On the first start after an update, the server may migrate stored data to a newer layout. This page covers each step and how to roll back.

  1. Back up the database. Migrations can change files in ways an older version can’t read, so a backup is your only way back. Follow Make a backup.

  2. Note the current version, so you can return to it:

    Terminal window
    git -C ~/originchats-osl rev-parse HEAD
  3. Make sure the checkout is clean. The updater refuses to run if git status shows any change, including untracked files. A database directory inside the checkout counts, unless it’s the ignored ./db.

For a large server, test the update on a copy first: restore the backup into another directory, build the new version in a separate checkout, and start it on a different port.

When the server runs under scripts/run.sh, the owner can update it without shell access by sending server_maintenance:

{
"cmd": "server_maintenance",
"action": "update",
"confirm": true
}

What happens next:

  1. The server replies with its status and stays online.
  2. It runs scripts/update.sh, which downloads and builds the new version. See What the updater does.
  3. If the update fails, the state becomes failed and the current version keeps running. The owner can read the updater’s output in the status details field.
  4. If it succeeds, the server records a server_maintenance audit entry, exits with status 75, and the launcher starts the new build.
  5. The new build runs startup migrations, then accepts connections. Clients reconnect on their own.

Send "action": "status" to follow progress. The update and restart actions are available only to the owner.

This path doesn’t stop the server for a backup. Take one first, or use a filesystem snapshot.

To update by hand:

Terminal window
# 1. Stop the server (Ctrl+C, or: sudo systemctl stop originchats)
# 2. Back up the database
# 3. Build and install the new version
cd ~/originchats-osl
./scripts/update.sh
# 4. Start the server again
./scripts/run.sh

run.sh rebuilds from source every time it starts. So git pull --ff-only followed by ./scripts/run.sh also updates the server. update.sh adds safety checks and installs the binary only after a successful build.

You can also run update.sh while the server is running. The new binary takes effect at the next restart.

scripts/update.sh works on the checkout it lives in, whatever directory you run it from. In order, it:

  1. Refuses to continue if the checkout has any local change: Update refused: the source checkout has local changes.
  2. Finds the current branch’s upstream, and stops if there isn’t one: The current branch needs a remote upstream. It also stops if the checkout isn’t on a branch.
  3. Fetches the upstream branch, without tags.
  4. Refuses if your branch has commits the upstream doesn’t: Update refused: the upstream has diverged.
  5. Checks out the fetched commit in a temporary Git worktree under .update-XXXXXX/, and builds originchats-osl there without the build cache.
  6. Stops if the build produced no executable: The build did not produce an executable.
  7. Fast-forwards your branch to the fetched commit, and replaces originchats-osl with the new build.
  8. Prints Installed <commit> and removes the temporary worktree.

If any step fails, the checkout and the installed binary are left as they were. The updater never touches the database.

Migrations convert data written by older versions into the current layout. They run on their own. There’s no command to run them or to check their progress, apart from the logs.

On every start, before accepting connections, the server:

  1. Undoes any interrupted write.
  2. Loads users, roles, channels, webhooks, access settings, and unread state, migrating unread state if needed.
  3. Builds mention history if it hasn’t been built yet.
  4. Migrates attachment details if needed.

If step 1, 3, or 4 fails, the server logs the error and exits. run.sh doesn’t retry after that. Restore the backup, or fix the cause and start again.

Two more migrations run later, the first time the data is used.

Migration When it runs What changes If it fails
Unread state At startup, if unreads.json exists Each account’s unread state moves to users/<id>/unreads.json. unreads.json is renamed to unreads.json.migrated. Ping counts start at 0. Startup continues. unreads.json is kept and the migration runs again on the next start.
Mention history At startup, if mentions-version.json doesn’t exist Scans every channel and thread once and writes each account’s mention history to users/<id>/mentions/. Then writes mentions-version.json. The server logs unable to build persistent mention history and exits.
Attachments At startup, if attachment_ids.txt or attachment_stats.json is missing attachments.json is split into one attachments/<id>.json per attachment, plus the ID index and totals. attachments.json is renamed to attachments.json.migrated. The server logs unable to migrate metadata and exits.
Audit log The first time the audit log is read or written modlog.json is converted to modlog.jsonl and deleted. The audit log is unavailable until it succeeds.
Thread messages The first time a thread with no messages in the current layout is read The first non-empty old thread file (threads/<id>.jsonl, threadMessages/<id>.jsonl, or their .bak copies) is copied into threads/<id>/0000.jsonl. The old file is left in place. Not reported. Check old threads after updating.

Things to know:

  • The mention history build reads all message history. On a large server the first start after it’s introduced can take a while. Progress is logged under mentions.migrate.
  • Mention history is built from members’ current roles and permissions, because the server can’t know who held which role when an old message was sent.
  • If modlog.json can’t be parsed, it is deleted, not converted. Keep a backup if you care about old audit entries.
  • *.migrated files are kept for reference. Delete them once you’re sure the migration worked and you have a backup.

See legacy formats for the full list of older layouts the server reads.

A migration can’t be reversed in place, and an older build may not understand migrated data. To go back, restore both the old code and the old data:

Terminal window
# Stop the server first.
cd ~/originchats-osl
git reset --hard <commit you noted before updating>
# Restore the database backup you took before updating.
./scripts/run.sh

run.sh rebuilds the old version when it starts. The next update.sh run will fast-forward to the latest version again.

After the restart:

  • Check the logs for server listening and for any migration errors.
  • Send server_maintenance with "action": "status". started_at shows when the running process started. The version field comes from service.version in the config, so it doesn’t change with updates. Use git log -1 in the checkout to see which commit is installed.
  • Log in as an ordinary member and read and send a message.