NikOS

Installation

Installing NikOS

One command for the common case, and three modes when you need control over which version you get.

Before you start

Coming from stock Ubuntu? The installer moves the display manager from GDM3 to LightDM and sets your session to Xubuntu. Neither takes effect while the GNOME session that launched the installer is still running, so you will need to reboot. The installer tells you which you need when it finishes. GNOME is not removed and stays selectable from the greeter.

Quick install

curl -fsSL https://raw.githubusercontent.com/nikolareljin/nikos/main/install.sh | bash

This clones the repository to ~/.local/share/nikos, moves it to the newest release tag, offers a dialog menu for the optional bundles, then runs the playbook behind a per-role progress gauge. The TUI follows the controlling terminal rather than stdin, so the piped one-liner gets the same interface a clone-and-run install does. Add NIKOS_USE_DIALOG=0 for the plain-prompt path.

Choosing a version

With no options the installer resolves and installs the newest release tag. Pre-release tags (0.6.0-rc1) and floating tags (production) are never selected automatically.

CommandInstalls
curl … | bashThe latest release tag
bash install.shThe latest release tag — not the checkout you ran it from
bash install.sh --ref 0.5.0That specific branch or tag
bash install.sh --devThe checkout you ran it from, uncommitted changes included

NIKOS_REPO_REF=<ref> is equivalent to --ref. Installing a tag leaves the persistent checkout on a detached HEAD, which is expected.

Development mode

git clone --recurse-submodules https://github.com/nikolareljin/nikos
cd nikos
bash install.sh --dev

--dev runs the checkout the script lives in, exactly as it stands. Nothing is cloned, fetched, pulled or stashed, and ~/.local/share/nikos is never touched — so testing a branch cannot damage a working install. It refuses to run outside a NikOS checkout and cannot be combined with --ref.

What happens during the run

  1. The installer checks the OS, your sudo access and the Ansible version, offering an upgrade from the Ansible PPA if it is too old.
  2. You pick optional bundles from a menu, or skip them all. Without a controlling terminal the installer stops here rather than silently installing none of them.
  3. Ansible runs 27 roles against localhost, shown as a per-role progress gauge.
  4. The full log is written to ~/.config/nikos/logs/, with install-latest.log symlinked to the most recent run.

First boot

Reboot if you came from Ubuntu; log out and back in if you were already on Xubuntu. On the first terminal session a one-time Git setup wizard runs. Pick GitHub, GitLab, Bitbucket or a custom Git server and it creates an SSH key, adds it to that host, sets your git identity and optionally clones your dotfiles; or pick Skip and manage keys yourself. It writes ~/.config/nikos/github-configured and does not run again; nikos-git-setup --reset runs it again.

Day-to-day

# update to the newest release and re-run the playbook
nikos update

# update to a specific branch or tag instead
nikos update --ref 0.6.0

# add an optional bundle later
nikos add postgres
nikos add ollama-vision

# check what is installed and whether anything is broken
nikos status
nikos doctor

# this machine's class and approved model per role; offer to remove the rest
nikos models
nikos models prune

# free disk from caches nothing uses (a dry run; --apply removes, after a yes)
nikos clean
nikos clean --apply

# read the last playbook log
nikos log 100

Every role is idempotent, so re-running changes only what has drifted. nikos update reads its target from what is checked out: a release install advances to the newest release only when that release is genuinely newer, and a branch install stays on its branch. An update never downgrades. From 1.3.0 it also keeps the Ollama models on this machine's approved set: it asks, one model at a time, before removing a model not approved for this machine, then pulls what the selected modules lack (details: What's included).

nikos clean lists, with sizes, what nothing uses: Docker build cache unused for a week (every builder), untagged images, node_modules in git repositories with no commit for 30 days, nothing uncommitted and nothing running from them, the uv cache, and unused pnpm, npm and pip cache entries. It removes them only with --apply. It never removes Docker volumes, containers, virtual environments, build output or tracked files. It is in NikOS 1.2.0 and later (nikos update brings it). Details: docs/debugging.md.

Customising before you run

Create vars/local.yml to override defaults without editing tracked files:

nikos_timezone: "Europe/London"
nikos_desktop_flavor: "xubuntu-full"
nikos_remove_gnome: true
nikos_ai_model_tier: "large"  # instead of measuring the machine
nikos_tesseract_languages: [eng, srp, deu]
nikos_nvidia_drivers: false    # leave GPU drivers alone
nikos_firefox_dark: false      # leave Firefox's theme alone
nikos_chromium_dark: false     # leave Chromium / Chrome alone

The full set of variables is documented in docs/customization.md.

If something goes wrong

SymptomWhat to do
Still booting into GNOME Check systemctl status display-manager. The playbook asserts the handover and fails rather than reporting success on a host that will boot into GNOME.
You are not currently on a branch An installer older than 0.5.0 could not update a checkout left on a tag. Run git -C ~/.local/share/nikos switch --track origin/main once; 0.5.0 handles it itself.
A role failed mid-run nikos log 200, then re-run — roles are idempotent, so completed work is skipped. Every install and update log ends with a digest: the NikOS version, OS, Ansible and Python versions, free disk, each failed task with its message, and each distinct warning, so the end of the log says what went wrong. A failed task also names its file and line.
A download or key check fails NikOS refuses a download whose sha256 differs from the pin in vars/versions.yml, and an apt key whose fingerprint differs. That is the check working: a moved upstream release or a changed key needs a person. scripts/bump-versions.py --check shows what upstream has now.
Want to check which version is installed nikos status, or cat ~/.local/share/nikos/VERSION.

More in docs/debugging.md.