Skip to content

Repository files navigation

Config

Personal Linux workstation configuration managed with Nix, Home Manager, and a small set of explicit host-level scripts.

The day-to-day development setup is documented in DEVELOPMENT.org.

Ownership

  • home.nix owns development and terminal packages, program configuration, session variables, Firefox policy, the declarative Noctalia base, and Home Manager links.
  • niri/, foot/, herdr/, the shell/editor files, and urls are copied by make sync.
  • The host dependency scripts provision GUI applications, the Niri desktop runtime, networking, Bluetooth, audio, power, portals, and the firewall. Home Manager supplies the matching configuration without duplicating those packages in the Nix profile.
  • keyd.nix and bin/keyd-system own a separate root Nix profile for the keyd daemon and its generated system configuration.
  • Noctalia keeps GUI changes in ~/.local/state/noctalia/settings.toml; those mutable values override the declarative defaults in home.nix.

Bootstrap and update workflow

Install the distro-managed GUI applications, desktop runtime, and host services:

make install-system-deps-arch
# or, on Ubuntu 26.04:
make install-system-deps-ubuntu26

Bootstrap Home Manager from the repository flake. Existing conflicting files are preserved with the backup suffix on this first activation:

make prepare

Check that the expected workstation commands are available:

make doctor

The normal update cycle is:

make check
make sync
make switch

make sync copies repository-managed dotfiles and helper commands into their live locations. It also links the shared manage-makefile and tiger-style-java skills into the global Codex and Claude skill directories.

make switch applies the Home Manager configuration directly from this repository through nix run home-manager/master and a path: flake reference. It does not require a prior copy into ~/.config/home-manager.

Run both operations together when the final diff has already been reviewed:

make apply

make prepare, make sync, make switch, and make apply do not install host packages, change the firewall, deploy keyd, or restart the Niri session.

Desktop workflow

Niri uses stable workspace names instead of application-derived workspaces:

KeyWorkspaceDefault role
Mod-1buildPrimary editing and implementation
Mod-2debugTests, logs, and debugging
Mod-3reviewDiffs, browsers, and review
Mod-4opsOperations and system tools
Mod-5commSlack and communication
Mod-6writeNotes and Obsidian
Mod-7scratchTemporary work on the laptop display

The horizontal 27-inch display is the focus canvas for build, debug, and review. The vertical display carries ops, comm, and write. The laptop display carries scratch. Use Mod-Ctrl-1 through Mod-Ctrl-7 to move the current column to a named workspace.

Important desktop bindings:

BindingAction
Mod-TOpen Foot
Mod-Shift-TOpen Herdr in Foot
Mod-DToggle the Noctalia launcher
Super-BToggle the Noctalia bar
Mod-SOpen the Noctalia control center
Mod-Ctrl-VOpen clipboard history
Super-Alt-LLock the session
Mod-Shift-/Show Niri’s full hotkey overlay

Noctalia v5 owns the bar, launcher, wallpaper, notifications, clipboard history, lock screen, OSDs, and control center. Niri starts its daemon when the session begins. Foot is the default terminal, and Firefox is the default browser for HTML and HTTP(S) links.

After applying desktop configuration, restart the Niri session when a setting cannot be reloaded in place. Useful diagnostics:

niri validate -c niri/config.kdl
niri msg outputs
noctalia config validate
noctalia msg --help
journalctl --user -b | rg noctalia

The expected host services are NetworkManager, Bluetooth, UPower, power-profiles-daemon, PipeWire/WirePlumber, GNOME Keyring Secret Service, polkit, and an XDG desktop portal. Check the persistent and user services with:

systemctl is-enabled NetworkManager bluetooth power-profiles-daemon ufw
systemctl --user status pipewire-pulse wireplumber

keyd

Home Manager installs the keyd CLI. The daemon and generated /etc/keyd/default.conf are built from the structured mappings in keyd.nix and kept in a root Nix profile.

Caps Lock sends Escape when tapped and activates the navigation/editing layer when held. Escape sends Caps Lock. The layer provides arrows, page movement, Home/End, Delete, Backspace, Enter, Tab, and Shift. The Caps-layer a mapping to Alt is intentionally disabled. AltGr retains the explicit accent and macro mappings defined in keyd.nix.

Build and apply a generation explicitly:

make switch-keyd

The first switch preserves an existing configuration as /etc/keyd/default.conf.pre-nix. Roll back one generation with:

make rollback-keyd

Inspect the live service and generated configuration with:

systemctl status keyd
readlink -f /etc/keyd/default.conf
keyd check /etc/keyd/default.conf

If a bad mapping captures the keyboard, press Backspace+Escape+Enter to stop keyd. The distribution-provided keyd package can be removed after confirming that the service runs from the Nix profile.

Helper commands

make sync-bin installs rssadd and rssget into ~/.local/bin. rssadd adds a URL and optional tags to the repository-managed Newsboat list, rejects duplicates, sorts the file, and updates the live ~/.newsboat/urls copy. rssget discovers feeds from a URL or the Wayland clipboard, uses Fuzzel when several feeds are available, and delegates the selected feed to rssadd.

rssadd https://example.com/feed.xml "tech"
rssget https://example.com "tech"
rssget                         # use the current clipboard URL

bin/cpu-throttle is a repository-local Intel P-state utility; it is not installed by make sync. It uses sudo to switch to power-saver mode, disable Turbo Boost, and cap performance at 60 percent. Disable restores Turbo Boost, the 100 percent cap, and the balanced profile.

./bin/cpu-throttle status
./bin/cpu-throttle enable
./bin/cpu-throttle disable

Tool inventory

The workstation toolset is grouped below. Development and terminal tools come from Home Manager; GUI applications and desktop runtime packages come from the distribution installers unless noted otherwise.

  • Shell and navigation: Zsh, Starship, direnv with nix-direnv, zoxide, tmux, Herdr, nnn, fzf, plocate, tree, bat, eza, fd, ripgrep, ast-grep, jq, distro-managed yq, glow, tldr, and fastfetch.
  • Files, downloads, and archives: wget, curl, aria2, HTTPie, Curlie, file, zip, xz, unzip, p7zip, zstd, GNU sed/tar/awk, and GnuPG.
  • Monitoring and diagnostics: htop, btop, ncdu, duf, iotop, iftop, sysstat, lm_sensors, lsof, strace, ltrace, hyperfine, mtr, iperf3, dnsutils, ldns, socat, nmap, ipcalc, ethtool, pciutils, and usbutils.
  • Development and review: Nix, Home Manager, Git, GitHub CLI, GitLab CLI, Difftastic, GNU Make, ShellCheck, shfmt, watchexec, mise, lazygit, lazydocker, Emacs, Neovim, VS Code, and Gum.
  • Language tooling: JDT LS, google-java-format, Spring Boot CLI, clang-tools, ZLS, yaml-language-server, nixd, and rust-analyzer. Java projects obtain their JDK and build tools through Mise.
  • Documentation and media: Hugo, Graphviz, TeX Live, and the distro-managed Obsidian, VLC, Xournal++, Pinta, Flameshot, and LocalSend.
  • Privacy and secrets: Firefox, distro-managed KeePassXC, age, SOPS, Restic, Gitleaks, MAT2, and uBlock Origin plus KeePassXC-Browser Firefox extensions.
  • Desktop runtime: distro-managed Niri, Noctalia, Foot, Fuzzel, wl-clipboard, and xwayland-satellite, plus the Nix-managed keyd CLI and Symbols Nerd Font glyph set.
  • Small baseline utilities retained for direct use include which and cowsay.

The distribution-level installers add the GUI applications, desktop runtime, services, portals, audio and Bluetooth stack, accessibility support, EGL/Mesa dependencies, ddcutil, and UFW. They intentionally keep these host concerns outside Home Manager.

Privacy baseline

Firefox installs uBlock Origin and KeePassXC-Browser from Mozilla Add-ons. In KeePassXC, enable Browser Integration -> Firefox once, then pair the extension with the unlocked database. KeePassXC owns its mutable settings and databases; the distro owns the package and Home Manager owns the native-messaging manifest.

Restic repositories are operator-selected. Initialize one on an external or remote mount, run a backup, verify it, and test a restore before depending on it:

restic -r /mnt/backup/restic init
restic -r /mnt/backup/restic backup "$HOME"
restic -r /mnt/backup/restic check --read-data
restic -r /mnt/backup/restic restore latest --target /tmp/restic-restore

Do not put the repository password in this repository. Restic prompts when no password source is configured. Back the password up separately from the Restic repository.

Create an age identity outside Git before adding SOPS-encrypted secrets to a project. Back up the identity separately, use the printed public recipient in that project’s .sops.yaml, and commit only SOPS-encrypted files:

install -d -m 0700 "$HOME/.config/sops/age"
age-keygen -o "$HOME/.config/sops/age/keys.txt"
chmod 0600 "$HOME/.config/sops/age/keys.txt"

Scan committed history for secrets and make a metadata-cleaned copy before sharing a supported document or image:

make secrets-check
mat2 document.pdf

The host dependency installers configure UFW with default-deny inbound traffic, rate-limited SSH, and LocalSend on TCP/UDP port 53317. They preserve unrelated rules rather than resetting the firewall. Docker-published ports can bypass UFW; bind development services to loopback unless they are intentionally exposed.

VPN provider configuration, Tor routing, USBGuard, DNS proxies, and automated Restic credentials remain explicit operator choices rather than workstation defaults.

Maintenance

Show the available repository operations and the current Git state with:

make help
make status

Run make check after changing repository-managed configuration or scripts and review the final diff before applying it. Do not use make sync or make switch as validation commands: both change the live home environment.

About

My app(Linux) config

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages