gtcnsl
EN RU
Static Go binary · zero runtime deps

Self-hosted Gitea,
managed from one binary.

Install, upgrade, and configure Gitea and act_runner — declarative config, built-in secret management, systemd units. One verifiable binary, no runtime to babysit.

Read the docs Verified with GPG + SHA-256
$ curl -fsSL https://dl.gtcnsl.com/latest/gtcnsl-v0.6.3-linux-amd64 -o /usr/local/bin/gtcnsl && chmod +x /usr/local/bin/gtcnsl
Checksums and signatures verified on download.
// 02

What it does

The whole Gitea lifecycle, declarative and verifiable.

gpg 01

Verified install & upgrade

Pulls Gitea and act_runner from the official mirror, checked against GPG signatures and SHA-256.

ini 02

Declarative app.ini

Keep desired state in Git. gtcnsl config apply reconciles the server — with a diff and a backup first.

key 03

Secret management

Generate, rotate, and store Gitea secrets safely. No hand-edited files, no leaks in shell history.

sys 04

systemd units

Manages the gitea and gitea-runner units directly — start, stop, status, enable.

i/o 05

TUI and CLI

Interactive TUI by default; a non-interactive CLI for cron and CI pipelines.

arch 06

Multi-arch

linux amd64, arm64, and armv7. From a VPS to a Raspberry Pi in the closet.

// 03

A console, not a script

Launch gtcnsl with no arguments and you get a real terminal UI — services, config drift, and secrets at a glance.

gtcnsl — v0.6.3
SERVICES
gitea active · 1.26.1
gitea-runner active · 0.2.11
CONFIG
app.ini in sync ✓
secrets 3 managed
ACTIONS
Upgrade Gitea
Apply config
Rotate secrets
View logs
❯ 
↑/↓ navigate ⏎ select q quit
// 04

Quickstart

Zero to a running Gitea with CI — three commands.

1
$ gtcnsl gitea install --domain git.example.com

Installs Gitea, generates secrets, writes app.ini, and starts the systemd unit.

2
$ gtcnsl runner install

Installs act_runner and its gitea-runner unit.

3
$ gtcnsl runner register --instance https://git.example.com

Registers the runner with your instance. CI is live.

// 05

Declarative by default

Keep app.ini in Git. gtcnsl config apply reconciles the server — with a diff and a backup first.

app.ini
[server]
DOMAIN = git.example.com
ROOT_URL = https://git.example.com/
SSH_PORT = 2222
[actions]
ENABLED = true
[security]
INSTALL_LOCK = true
gtcnsl config apply
$ gtcnsl config apply
~ [server] SSH_PORT 22 → 2222
+ [actions] ENABLED = true
backup → /var/backups/gitea/app.ini.2026-05-30
3 changes applied · gitea restarted
// 06

Runs where you run

One binary across the distros and architectures you actually deploy.

Debian
13
Ubuntu
24.04 LTS
Rocky
9
linux/amd64 linux/arm64 linux/armv7
From a cloud VPS to a Raspberry Pi in the closet.
// 07

Why a binary, not a script

Built for people who treat their server like production.

One static binary

No Python, no Ansible, no runtime to install or version. Drop it on the box and run.

Verifiable

Every download is checked against GPG signatures and SHA-256 before it touches your system.

Idempotent

Declarative state means re-running is safe. Apply the same config twice, get the same server.

Whole lifecycle

Install, upgrade, configure, and run — one tool instead of a folder of fragile shell scripts.

// 08

Status

v0.x — early, but already running in production homelabs.

Shipped v0.5
Install & upgrade Gitea + act_runner
Declarative app.ini with diff + backup
Secret generation & rotation
systemd unit management
TUI and non-interactive CLI
Next v0.6
gtcnsl self-update
Config templates
Exploring later
Backup & restore flows
Multi-host inventories
// 09

Questions

Only what your declarative config covers. Everything else is left alone, and config apply shows a diff and writes a backup before any change.

Yes. Point it at your current app.ini, review the diff, and apply only what you want. There is no all-or-nothing migration.

For installs and service operations, yes — it manages systemd units. Read-only commands like status and config diff do not.

No. No account, no telemetry, no phone-home. One binary and your server.

GPG signature plus SHA-256 against the official Gitea mirror, every time.