Skip to content

Install

The fastest way to see nit working is the development stack: PostgreSQL, a Gitea acting as the forge, the control plane, a worker and the web console — with a seeded repository and three accounts whose access deliberately differs.

Terminal window
git clone https://github.com/NitScm/nit
cd nit/deploy/dev
docker compose up -d
docker compose logs -f bootstrap

The bootstrap service creates the Gitea account and repository, seeds it, writes the policy bundle, applies the database schema, issues tokens, and prints what to do next. Give it a minute the first time — it builds the images.

When it finishes:

Web consolehttp://localhost:4200
APIhttp://localhost:8080
Giteahttp://localhost:3000nit-admin / nit-admin-password
UserGroupCan see
aliceplatformEverything, including secrets/, infra/production/ and CI
bobbackendsrc/server, src/shared, docs — no secrets
carolfrontendsrc/ui, src/shared, docs — no secrets

Their tokens are in the bootstrap output, and afterwards:

Terminal window
docker compose exec nitd cat /var/lib/nit/tokens

Open http://localhost:4200, leave Server empty, and paste alice’s token.

Alice is in the platform group, which is what the server’s NIT_ADMIN_GROUPS names. Bob and carol sign in successfully but every page reports “not found” — the operations API is invisible to a non-operator, and that is deliberate.

The nit binary is inside the image; copy it out, or build it (below).

Terminal window
docker compose cp nitd:/usr/local/bin/nit ./nit
sudo mv nit /usr/local/bin/

Then follow Your first workspace.

Terminal window
docker compose down -v # -v also removes the volumes

Every release publishes signed-by-checksum archives and Linux packages at github.com/NitScm/nit/releases. The binaries are static and need no runtime beyond git.

Terminal window
VERSION=0.1.0
curl -LO "https://github.com/NitScm/nit/releases/download/v${VERSION}/nit_${VERSION}_linux_amd64.deb"
sudo apt install "./nit_${VERSION}_linux_amd64.deb"
nit version

The package installs all four binaries into /usr/bin and declares a dependency on git, so apt refuses rather than leaving you with a worker that fails on its first task.

On an ARM machine — a Raspberry Pi, an AWS Graviton instance — replace amd64 with arm64.

Terminal window
VERSION=0.1.0
sudo rpm -i "https://github.com/NitScm/nit/releases/download/v${VERSION}/nit_${VERSION}_linux_amd64.rpm"

Two archives, split by who runs what. nit_… carries nit and nitctl — the tools a person runs. nit-server_… carries nitd and nit-worker.

Neither carries the engineering documents from the repository’s docs/. Those are written for people modifying nit, and a copy on disk drifts from this site and from the binary it shipped with. What you are reading is the current one.

Terminal window
VERSION=0.1.0
OS=linux # or: darwin
ARCH=amd64 # or: arm64
curl -LO "https://github.com/NitScm/nit/releases/download/v${VERSION}/nit_${VERSION}_${OS}_${ARCH}.tar.gz"
curl -LO "https://github.com/NitScm/nit/releases/download/v${VERSION}/checksums.txt"
sha256sum --check --ignore-missing checksums.txt
tar xzf "nit_${VERSION}_${OS}_${ARCH}.tar.gz"
sudo install -m 0755 nit nitctl /usr/local/bin/

For a server, swap nit_ for nit-server_ — or install the .deb or .rpm above, which carry all four binaries and declare the dependency on git.

Check the checksum before running anything. It takes one command, and it is the only step that distinguishes the archive you meant to download from one you did not.

Developers on Windows get nit and nitctl. Download nit_<version>_windows_amd64.zip from the releases page, or:

Terminal window
$Version = '0.1.0'
$Arch = 'amd64' # or: arm64 on a Surface Pro X or similar
Invoke-WebRequest -Uri "https://github.com/NitScm/nit/releases/download/v$Version/nit_${Version}_windows_$Arch.zip" -OutFile nit.zip
Invoke-WebRequest -Uri "https://github.com/NitScm/nit/releases/download/v$Version/checksums.txt" -OutFile checksums.txt
# Verify before extracting.
(Get-FileHash nit.zip -Algorithm SHA256).Hash.ToLower()
Select-String -Path checksums.txt -Pattern "windows_$Arch.zip"
Expand-Archive nit.zip -DestinationPath "$env:LOCALAPPDATA\nit"

Then put it on your PATH, for this session and the next:

Terminal window
$env:Path += ";$env:LOCALAPPDATA\nit"
[Environment]::SetEnvironmentVariable(
'Path',
[Environment]::GetEnvironmentVariable('Path', 'User') + ";$env:LOCALAPPDATA\nit",
'User')
nit version

You also need git for Windows — nit produces and applies patches, it does not reimplement git.

If you already have Go 1.25, this is the shortest route on any platform, and the binary still reports its version — the toolchain stamps the module version and the revision even without a release build.

Terminal window
go install github.com/NitScm/nit/cmd/nit@latest
go install github.com/NitScm/nit/cmd/nitctl@latest
Terminal window
nit version
nit v0.1.0 (a1b2c3d4e5f6) built 2026-08-22T21:00:00Z go1.25.11 linux/amd64

Quote that line in a bug report. A build that cannot say which build it is turns every report into a guess — which is why dev (unknown) appears instead of nothing when a binary was built outside a release.

You need Go 1.25 and git.

Terminal window
git clone https://github.com/NitScm/nit
cd nit
make build # bin/nit bin/nitd bin/nit-worker bin/nitctl
make test # needs no infrastructure
export PATH="$PWD/bin:$PATH"

Four binaries come out:

BinaryRuns where
nitA developer’s machine
nitdThe control plane — the API
nit-workerAnywhere with git, disk and access to the forge
nitctlAn operator’s machine, or the server

To bring up a server you also need a database and a policy bundle. PostgreSQL 13+ is recommended; MySQL 8.0.16+ and MariaDB 10.6+ are supported too, and Configuration covers what differs. The shortest path:

Terminal window
createdb nit
nitctl config init # writes /etc/nit/nit.yaml, mode 600
openssl rand -base64 32 > /etc/nit/sync.key && chmod 600 /etc/nit/sync.key
$EDITOR /etc/nit/nit.yaml # database.url, policy.dir, admin_groups
nitctl config show # every value, and where it came from
nitctl migrate
nitd &
nit-worker &

See Configuring the server for what goes in that file, and Writing a policy bundle for the bundle.

deploy/production/ carries a forge-agnostic Compose base plus one overlay per forge:

Terminal window
cd nit/deploy/production
cp .env.example .env && chmod 600 .env
$EDITOR .env
docker compose -f compose.base.yaml -f compose.gitea.yaml up -d
docker compose -f compose.base.yaml -f compose.github.yaml up -d
docker compose -f compose.base.yaml -f compose.gitlab.yaml up -d

Read Going to production before you do — there are three things about the forge that have to be true, or nit’s guarantees do not hold.

docs/VALIDATION.md in the nit repository is a step-by-step walkthrough that proves each property in turn — read filtering, refused pushes, the CI guard, the audit trail, recovery from a dead worker — with the output you should see at each step.