Skip to content
gtcnsl
EN RU

v1.1.0

2026-07-08 latest ● stable

What changed

Added
  • **`gitea install` / `runner install` detect an existing installation.** Both flows now inspect the host first (binary version, unit file, live app.ini) and, over an existing install — even a hand-rolled one with custom paths — switch to in-place upgrade semantics: paths are taken from the **live** install instead of the defaults, an explicit `--data-dir`/`--log-dir` that contradicts the live install is refused ("an upgrade never moves data"), and a unit file gtcnsl did not write is **preserved byte-for-byte** across the upgrade (binary swap + restart only) — the new `--rewrite-unit` flag opts into replacement. The TUI install screen shows the detection as an upgrade banner with the live paths prefilled and refuses contradicting edits inline.
  • **`gtcnsl gitea adopt` — bring a hand-rolled install under management, never moving data.** Dry-run by default; `--yes` applies. Extracts the managed secrets from `app.ini` into `secrets.ini` with the **same values** (no restart — this turns doctor's secrets probe green and unlocks `secrets check`/`rotate`), tightens a world-readable `app.ini` to 0640, and `--emit-template` writes a secrets-free `app.ini.tmpl` for the declarative loop. `--unit` additionally normalizes a hand-written `gitea.service` to the managed-base + operator-drop-in canon (ADR 0025), with systemd's own effective properties proving the result behaves identically — any unexpected difference rolls back automatically.
  • **The gitea unit template grants `CAP_NET_BIND_SERVICE`.** Fresh installs can point `server.HTTP_PORT` below 1024 (e.g. direct HTTPS on :443 with Gitea's built-in ACME) without hand-editing the unit: `AmbientCapabilities` grants the capability to the non-root service and `CapabilityBoundingSet` drops every other one. Harmless on the default :3000.
  • **Serving profiles on `gitea install`.** `--serving behind-proxy` (the default — plain HTTP on :3000, exactly the previous behaviour), `--serving https-acme` (Gitea terminates TLS itself with built-in Let's Encrypt on :443, :80 answering the ACME challenge and redirecting; requires `--domain`, `--acme-email` and the **explicit `--acme-tos` consent**), and `--serving https-manual` (your `--cert-file`/`--key-file`, `--https-port` defaulting to 443). Profile-specific preflights run before anything is downloaded: target ports bindable, certificate material present and readable by the service user, ACME domain resolving to this host (best-effort warning). The TUI install wizard gained the same choice as a step, with the ACME Terms-of-Service consent as an explicit checkbox.
  • **`gtcnsl gitea enable-https` — switch a live HTTP install to HTTPS, with rollback.** Rides the declarative config machinery: the `[server]` section is rewritten atomically with a backup, Gitea restarts and is health-checked, and **any failure rolls back to the working HTTP config automatically**. Binding a privileged port on a hand-written unit that lacks `CAP_NET_BIND_SERVICE` is a hard stop that prints the exact directives — `--grant-caps` instead deploys a small gtcnsl-owned drop-in (the operator's unit file is never edited, ADR 0025), which the rollback also revokes. Re-running against an already-https install is a no-op.
  • **Doctor probes https/port/capability coherence.** `PROTOCOL = https` on a port below 1024 whose unit does not *effectively* grant `CAP_NET_BIND_SERVICE` (drop-ins counted, systemd asked directly) is reported as a blocker with the fix spelled out — this exact hand-setup would otherwise die at bind time on its next restart, months later.
  • The health prober now derives its probe target from the live `[server]` config (scheme, port, a longer first-issuance window when ACME is on) instead of assuming `http://127.0.0.1:3000`, probing loopback TLS with verification off — the certificate is domain-bound; this is liveness only.

Download

Pick your architecture. Direct links point at the release assets.

$ curl -fsSL https://dl.gtcnsl.com/v1.1.0/gtcnsl-v1.1.0-linux-amd64 -o /usr/local/bin/gtcnsl && chmod +x /usr/local/bin/gtcnsl
i
Verify
Compare against the signed checksum manifest before you run anything. checksums.txt