Skip to content
gtcnsl
EN RU

Upgrades & self-update

gtcnsl updates itself from the download host with a SHA-256 check and a rollback snapshot. Gitea moves forward the same way you installed it — after a backup.

Updated for v1.3.0

Update gtcnsl itself

# is a newer release available? (no write, no --yes needed)
gtcnsl self-update --dry-run

# update to the latest release
gtcnsl self-update --yes

# pin a specific version
gtcnsl self-update --to v0.6.1 --yes

Under the hood it resolves the latest tag from versions.json, downloads https://dl.gtcnsl.com/<tag>/gtcnsl-<tag>-linux-<arch>, verifies it against checksums.txt (SHA-256), snapshots the running binary, swaps it atomically, then runs gtcnsl --version to confirm — rolling back automatically if that check fails.

Roll gtcnsl back

gtcnsl self-update --rollback --yes

Restores the binary replaced by the most recent self-update. (--rollback can't be combined with --to or --dry-run.)

i
Pick your mirror
Downloads default to https://dl.gtcnsl.com. Point elsewhere with --dl-host or the $GTCNSL_DLHOST env var; https://dl.gtcnsl.ru is an identical mirror.

Move Gitea forward

gtcnsl gitea upgrade [--to <v>] [--yes] is the short command once Gitea is already installed — it refuses cleanly if nothing is there yet, then rides the same in-place upgrade path gitea install --to <version> has always used: paths come from the live install (an upgrade never moves data), a --data-dir/--log-dir that contradicts the live install is refused, and a gitea.service unit gtcnsl did not write is preserved byte-for-byte — binary swap + restart only; pass --rewrite-unit if you deliberately want gtcnsl's template instead. Reach for gitea install --to directly when you need those extra flags in the same step. The TUI shows the same detection as an upgrade banner with the live paths prefilled.

If anything fails after the binary is swapped — deploying the unit, restarting, or the post-upgrade health check — gtcnsl restores the previous Gitea binary and restarts the service automatically; a failed upgrade never leaves the host without a running Gitea.

Gitea data is preserved across a binary swap, but take a snapshot first so you can return to a known-good state:

gtcnsl backup
gtcnsl gitea upgrade --to v1.27.0 --yes
gtcnsl doctor   # confirm the unit is back and healthy

gtcnsl backup snapshots Gitea's binary, app.ini, secrets.ini, and the custom/ tree, plus — when a runner is installed — its .runner registration, config.yaml, and the gitea-runner.service unit, all to /var/lib/gtcnsl/backups/<id>/. List and restore them with:

gtcnsl backup list
gtcnsl restore <backup-id> --yes

restore snapshots the live files, stops Gitea (and the runner, if the backup carries runner state), swaps in the backup, restarts, and health-checks — undoing itself if Gitea won't come back. A backup taken before this release restores exactly as it always did; the runner items are simply absent from it.

!
Read the changelog before a jump
Gitea runs its own migrations on first start after an upgrade; skipping several minor versions at once is riskier. Back up, move one step at a time, and check gtcnsl doctor after each.

Move the runner forward

gtcnsl runner upgrade [--to <v>] [--yes] is the runner's equivalent of gitea upgrade: it refuses cleanly if no runner is installed, otherwise swaps the binary in place and restarts the service. It follows the live unit's own facts — binary path, work dir, even a legacy act_runner.service name from before the v0.2 rename — instead of assuming gtcnsl's canonical layout, so an adopted or relocated runner (gtcnsl runner adopt) upgrades correctly too. Like gitea upgrade, a failed swap restores the previous runner binary and restarts the service automatically.

gtcnsl runner upgrade --to v2.1.0 --yes

Next steps

If something looks wrong after an upgrade, start at Troubleshooting & FAQ.