Polish ringtail NixOS config and add documentation (#208)
## Summary
- Fix Super+Return keybinding to launch wezterm in sway
- Set fish as default login shell
- Remove `initialPassword` (real password already set)
- Add 1Password CLI + GUI, chezmoi, and dev tool packages (neovim, eza, fd, fzf, zoxide, starship, atuin, bat, ripgrep)
- Add ringtail reference card, update host inventory and reference index
- Changelog fragment
## Post-merge deployment
- `mise run provision-ringtail` to rebuild NixOS
- On ringtail: launch 1Password GUI, enable CLI integration (Settings > Developer > CLI integration)
- Chezmoi needs `.chezmoiignore` updates in the dotfiles repo (separate task)
Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/208
2026-02-18 17:53:47 -08:00
|
|
|
{ config, pkgs, lib, ... }:
|
2026-02-18 08:24:25 -08:00
|
|
|
|
Polish ringtail NixOS config and add documentation (#208)
## Summary
- Fix Super+Return keybinding to launch wezterm in sway
- Set fish as default login shell
- Remove `initialPassword` (real password already set)
- Add 1Password CLI + GUI, chezmoi, and dev tool packages (neovim, eza, fd, fzf, zoxide, starship, atuin, bat, ripgrep)
- Add ringtail reference card, update host inventory and reference index
- Changelog fragment
## Post-merge deployment
- `mise run provision-ringtail` to rebuild NixOS
- On ringtail: launch 1Password GUI, enable CLI integration (Settings > Developer > CLI integration)
- Chezmoi needs `.chezmoiignore` updates in the dotfiles repo (separate task)
Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/208
2026-02-18 17:53:47 -08:00
|
|
|
let
|
|
|
|
|
# Libraries needed by mise-compiled runtimes (python-build, etc.)
|
|
|
|
|
buildDeps = with pkgs; [ zlib readline bzip2 xz libffi ncurses sqlite openssl ];
|
|
|
|
|
in
|
2026-02-18 08:24:25 -08:00
|
|
|
{
|
2026-02-18 08:56:27 -08:00
|
|
|
# Allow unfree packages (NVIDIA drivers, Steam)
|
|
|
|
|
nixpkgs.config.allowUnfree = true;
|
|
|
|
|
|
2026-02-18 08:24:25 -08:00
|
|
|
# Bootloader
|
|
|
|
|
boot.loader.systemd-boot.enable = true;
|
|
|
|
|
boot.loader.efi.canTouchEfiVariables = true;
|
|
|
|
|
|
Polish ringtail NixOS config and add documentation (#208)
## Summary
- Fix Super+Return keybinding to launch wezterm in sway
- Set fish as default login shell
- Remove `initialPassword` (real password already set)
- Add 1Password CLI + GUI, chezmoi, and dev tool packages (neovim, eza, fd, fzf, zoxide, starship, atuin, bat, ripgrep)
- Add ringtail reference card, update host inventory and reference index
- Changelog fragment
## Post-merge deployment
- `mise run provision-ringtail` to rebuild NixOS
- On ringtail: launch 1Password GUI, enable CLI integration (Settings > Developer > CLI integration)
- Chezmoi needs `.chezmoiignore` updates in the dotfiles repo (separate task)
Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/208
2026-02-18 17:53:47 -08:00
|
|
|
# No TPM module on this board
|
|
|
|
|
systemd.tpm2.enable = false;
|
|
|
|
|
|
2026-02-18 08:24:25 -08:00
|
|
|
# Networking
|
|
|
|
|
networking.hostName = "ringtail";
|
|
|
|
|
networking.networkmanager.enable = true;
|
|
|
|
|
|
|
|
|
|
# Time zone
|
|
|
|
|
time.timeZone = "America/Los_Angeles";
|
|
|
|
|
|
|
|
|
|
# Locale
|
|
|
|
|
i18n.defaultLocale = "en_US.UTF-8";
|
|
|
|
|
|
|
|
|
|
# NVIDIA proprietary drivers
|
|
|
|
|
hardware.graphics.enable = true;
|
|
|
|
|
services.xserver.videoDrivers = [ "nvidia" ];
|
|
|
|
|
hardware.nvidia = {
|
|
|
|
|
modesetting.enable = true;
|
|
|
|
|
open = false; # Use proprietary driver for RTX 4080
|
|
|
|
|
nvidiaSettings = true;
|
|
|
|
|
package = config.boot.kernelPackages.nvidiaPackages.stable;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
# Wayland / Sway
|
|
|
|
|
programs.sway = {
|
|
|
|
|
enable = true;
|
|
|
|
|
wrapperFeatures.gtk = true;
|
2026-02-18 09:08:26 -08:00
|
|
|
extraSessionCommands = ''
|
|
|
|
|
export WLR_NO_HARDWARE_CURSORS=1
|
|
|
|
|
'';
|
2026-02-18 08:24:25 -08:00
|
|
|
extraPackages = with pkgs; [
|
|
|
|
|
swaylock
|
|
|
|
|
swayidle
|
|
|
|
|
wezterm # terminal
|
|
|
|
|
wmenu # app launcher
|
|
|
|
|
mako # notifications
|
|
|
|
|
grim # screenshots
|
|
|
|
|
slurp # region selection
|
|
|
|
|
];
|
|
|
|
|
};
|
|
|
|
|
security.polkit.enable = true;
|
2026-02-19 06:46:37 -08:00
|
|
|
security.pam.services.swaylock = {}; # Allow swaylock to authenticate
|
2026-02-18 09:25:32 -08:00
|
|
|
security.sudo.wheelNeedsPassword = false;
|
2026-02-18 08:24:25 -08:00
|
|
|
|
|
|
|
|
# Enable greetd as display manager for sway
|
|
|
|
|
services.greetd = {
|
|
|
|
|
enable = true;
|
|
|
|
|
settings = {
|
|
|
|
|
default_session = {
|
2026-02-18 09:30:01 -08:00
|
|
|
command = "${pkgs.tuigreet}/bin/tuigreet --time --cmd 'sway --unsupported-gpu'";
|
2026-02-18 08:24:25 -08:00
|
|
|
user = "greeter";
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
# PipeWire for audio
|
|
|
|
|
services.pipewire = {
|
|
|
|
|
enable = true;
|
|
|
|
|
alsa.enable = true;
|
|
|
|
|
pulse.enable = true;
|
|
|
|
|
};
|
|
|
|
|
|
Polish ringtail NixOS config and add documentation (#208)
## Summary
- Fix Super+Return keybinding to launch wezterm in sway
- Set fish as default login shell
- Remove `initialPassword` (real password already set)
- Add 1Password CLI + GUI, chezmoi, and dev tool packages (neovim, eza, fd, fzf, zoxide, starship, atuin, bat, ripgrep)
- Add ringtail reference card, update host inventory and reference index
- Changelog fragment
## Post-merge deployment
- `mise run provision-ringtail` to rebuild NixOS
- On ringtail: launch 1Password GUI, enable CLI integration (Settings > Developer > CLI integration)
- Chezmoi needs `.chezmoiignore` updates in the dotfiles repo (separate task)
Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/208
2026-02-18 17:53:47 -08:00
|
|
|
# Bluetooth
|
|
|
|
|
hardware.bluetooth = {
|
|
|
|
|
enable = true;
|
|
|
|
|
powerOnBoot = true;
|
|
|
|
|
};
|
|
|
|
|
services.blueman.enable = true;
|
|
|
|
|
|
|
|
|
|
# Fish shell
|
|
|
|
|
programs.fish.enable = true;
|
|
|
|
|
|
|
|
|
|
# 1Password (modules handle CLI group/setgid and polkit for GUI integration)
|
|
|
|
|
programs._1password.enable = true;
|
|
|
|
|
programs._1password-gui = {
|
|
|
|
|
enable = true;
|
|
|
|
|
polkitPolicyOwners = [ "eblume" ];
|
|
|
|
|
};
|
|
|
|
|
|
2026-02-18 08:24:25 -08:00
|
|
|
# Steam
|
|
|
|
|
programs.steam = {
|
|
|
|
|
enable = true;
|
|
|
|
|
dedicatedServer.openFirewall = true;
|
|
|
|
|
};
|
|
|
|
|
|
Add k3s, 1Password Connect, and systemd nix-container-builder to ringtail (#209)
## Summary
Extends ringtail from a desktop/gaming NixOS box into an infrastructure node with a k3s cluster, secrets management, and a Forgejo Actions
runner for building containers with Nix.
### K3s cluster
- Single-node k3s with Traefik/ServiceLB/metrics-server disabled (minimal footprint)
- TLS SAN set to `ringtail.tail8d86e.ts.net` so ArgoCD on indri can manage it via Tailscale
- Containerd registry mirrors pull through Zot on indri (`k3s-registries.yaml`)
- Tailscale interface added to `trustedInterfaces` for cross-node ArgoCD access
- `kubectl` added to system packages
### 1Password Connect + External Secrets Operator
- Four new ArgoCD apps targeting `k3s-ringtail`: `1password-connect-ringtail`, `external-secrets-crds-ringtail`, `external-secrets-ringtail`,
`external-secrets-config-ringtail`
- Reuses the same Helm charts/values as indri, just pointed at ringtail's k3s API server
- Bootstrap secrets (`op-credentials`, `onepassword-token`) provisioned by Ansible pre_tasks via `op read`, then applied to the `1password`
namespace in post_tasks
### Systemd Forgejo Actions runner
- Native `services.gitea-actions-runner` with `forgejo-runner` package — no DinD, no k8s pod, runs directly on the NixOS host
- Label `nix-container-builder:host` — jobs execute on the host with `nix`, `skopeo`, `nodejs`, etc. in PATH
- Registration token fetched from 1Password (`Forgejo Secrets/runner_reg`) by Ansible and written to `/etc/forgejo-runner/token.env`
- Runner's dynamic user (`gitea-runner`) added to `nix.settings.trusted-users` for nix daemon access
### Nix container build workflow
- New `.forgejo/workflows/build-container-nix.yaml` triggers on `*-nix-v[0-9]*` tags (e.g. `nettest-nix-v1.0.0`)
- Builds with `nix build -f containers/<name>/default.nix`, pushes to Zot via `skopeo copy`
- Existing Dockerfile workflow guarded with `if: !contains(github.ref_name, '-nix-v')` to avoid double-triggering
### Mise task updates
- `container-tag-and-release` auto-detects `default.nix` vs `Dockerfile` and uses the appropriate tag format (`-nix-v` vs `-v`)
- `container-list` shows build type indicator (`[nix]` / `[dockerfile]`)
## Post-merge
1. `mise run provision-ringtail` — deploys k3s token, runner token, NixOS rebuild
2. Register k3s cluster in ArgoCD (first time only):
```fish
ssh ringtail 'sudo cat /etc/rancher/k3s/k3s.yaml' | \
sed 's|127.0.0.1|ringtail.tail8d86e.ts.net|' > /tmp/k3s-ringtail.yaml
set -x KUBECONFIG /tmp/k3s-ringtail.yaml
argocd cluster add default --name k3s-ringtail
3. Sync ArgoCD apps in order: 1password-connect-ringtail -> external-secrets-crds-ringtail -> external-secrets-ringtail ->
external-secrets-config-ringtail
4. Verify runner: ssh ringtail 'systemctl status gitea-runner-nix-container-builder'
5. Check Forgejo admin panel for ringtail-nix-builder runner online
6. Test: create containers/<name>/default.nix, tag with <name>-nix-v0.1.0
Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/209
2026-02-18 21:15:30 -08:00
|
|
|
# K3s single-node cluster
|
|
|
|
|
services.k3s = {
|
|
|
|
|
enable = true;
|
|
|
|
|
role = "server";
|
|
|
|
|
tokenFile = "/etc/k3s/token";
|
|
|
|
|
extraFlags = toString [
|
|
|
|
|
"--disable=traefik"
|
|
|
|
|
"--disable=servicelb"
|
|
|
|
|
"--disable=metrics-server"
|
|
|
|
|
"--write-kubeconfig-mode=644"
|
|
|
|
|
"--tls-san=ringtail.tail8d86e.ts.net"
|
|
|
|
|
];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
# K3s containerd registry mirrors (pull through Zot on indri)
|
|
|
|
|
environment.etc."rancher/k3s/registries.yaml".source = ./k3s-registries.yaml;
|
|
|
|
|
|
2026-02-18 08:24:25 -08:00
|
|
|
# Tailscale
|
2026-02-18 09:24:17 -08:00
|
|
|
services.tailscale = {
|
|
|
|
|
enable = true;
|
|
|
|
|
extraUpFlags = [ "--accept-routes" "--ssh" ];
|
|
|
|
|
};
|
2026-02-18 08:24:25 -08:00
|
|
|
|
Add k3s, 1Password Connect, and systemd nix-container-builder to ringtail (#209)
## Summary
Extends ringtail from a desktop/gaming NixOS box into an infrastructure node with a k3s cluster, secrets management, and a Forgejo Actions
runner for building containers with Nix.
### K3s cluster
- Single-node k3s with Traefik/ServiceLB/metrics-server disabled (minimal footprint)
- TLS SAN set to `ringtail.tail8d86e.ts.net` so ArgoCD on indri can manage it via Tailscale
- Containerd registry mirrors pull through Zot on indri (`k3s-registries.yaml`)
- Tailscale interface added to `trustedInterfaces` for cross-node ArgoCD access
- `kubectl` added to system packages
### 1Password Connect + External Secrets Operator
- Four new ArgoCD apps targeting `k3s-ringtail`: `1password-connect-ringtail`, `external-secrets-crds-ringtail`, `external-secrets-ringtail`,
`external-secrets-config-ringtail`
- Reuses the same Helm charts/values as indri, just pointed at ringtail's k3s API server
- Bootstrap secrets (`op-credentials`, `onepassword-token`) provisioned by Ansible pre_tasks via `op read`, then applied to the `1password`
namespace in post_tasks
### Systemd Forgejo Actions runner
- Native `services.gitea-actions-runner` with `forgejo-runner` package — no DinD, no k8s pod, runs directly on the NixOS host
- Label `nix-container-builder:host` — jobs execute on the host with `nix`, `skopeo`, `nodejs`, etc. in PATH
- Registration token fetched from 1Password (`Forgejo Secrets/runner_reg`) by Ansible and written to `/etc/forgejo-runner/token.env`
- Runner's dynamic user (`gitea-runner`) added to `nix.settings.trusted-users` for nix daemon access
### Nix container build workflow
- New `.forgejo/workflows/build-container-nix.yaml` triggers on `*-nix-v[0-9]*` tags (e.g. `nettest-nix-v1.0.0`)
- Builds with `nix build -f containers/<name>/default.nix`, pushes to Zot via `skopeo copy`
- Existing Dockerfile workflow guarded with `if: !contains(github.ref_name, '-nix-v')` to avoid double-triggering
### Mise task updates
- `container-tag-and-release` auto-detects `default.nix` vs `Dockerfile` and uses the appropriate tag format (`-nix-v` vs `-v`)
- `container-list` shows build type indicator (`[nix]` / `[dockerfile]`)
## Post-merge
1. `mise run provision-ringtail` — deploys k3s token, runner token, NixOS rebuild
2. Register k3s cluster in ArgoCD (first time only):
```fish
ssh ringtail 'sudo cat /etc/rancher/k3s/k3s.yaml' | \
sed 's|127.0.0.1|ringtail.tail8d86e.ts.net|' > /tmp/k3s-ringtail.yaml
set -x KUBECONFIG /tmp/k3s-ringtail.yaml
argocd cluster add default --name k3s-ringtail
3. Sync ArgoCD apps in order: 1password-connect-ringtail -> external-secrets-crds-ringtail -> external-secrets-ringtail ->
external-secrets-config-ringtail
4. Verify runner: ssh ringtail 'systemctl status gitea-runner-nix-container-builder'
5. Check Forgejo admin panel for ringtail-nix-builder runner online
6. Test: create containers/<name>/default.nix, tag with <name>-nix-v0.1.0
Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/209
2026-02-18 21:15:30 -08:00
|
|
|
# Trust Tailscale interface (ArgoCD on indri connects via tailnet)
|
|
|
|
|
networking.firewall.trustedInterfaces = [ "tailscale0" ];
|
|
|
|
|
|
2026-02-18 08:24:25 -08:00
|
|
|
# SSH
|
|
|
|
|
services.openssh = {
|
|
|
|
|
enable = true;
|
|
|
|
|
settings = {
|
|
|
|
|
PasswordAuthentication = false;
|
|
|
|
|
PermitRootLogin = "no";
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
# User account
|
|
|
|
|
users.users.eblume = {
|
|
|
|
|
isNormalUser = true;
|
Polish ringtail NixOS config and add documentation (#208)
## Summary
- Fix Super+Return keybinding to launch wezterm in sway
- Set fish as default login shell
- Remove `initialPassword` (real password already set)
- Add 1Password CLI + GUI, chezmoi, and dev tool packages (neovim, eza, fd, fzf, zoxide, starship, atuin, bat, ripgrep)
- Add ringtail reference card, update host inventory and reference index
- Changelog fragment
## Post-merge deployment
- `mise run provision-ringtail` to rebuild NixOS
- On ringtail: launch 1Password GUI, enable CLI integration (Settings > Developer > CLI integration)
- Chezmoi needs `.chezmoiignore` updates in the dotfiles repo (separate task)
Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/208
2026-02-18 17:53:47 -08:00
|
|
|
shell = pkgs.fish;
|
2026-02-18 08:24:25 -08:00
|
|
|
extraGroups = [ "wheel" "networkmanager" "video" ];
|
|
|
|
|
openssh.authorizedKeys.keys = [
|
|
|
|
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILmh1SSCdDAyu3vkSQH7kAXEPDi8APyjo9JXDTjtha2j"
|
|
|
|
|
];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
# System packages
|
|
|
|
|
environment.systemPackages = with pkgs; [
|
|
|
|
|
git
|
Add k3s, 1Password Connect, and systemd nix-container-builder to ringtail (#209)
## Summary
Extends ringtail from a desktop/gaming NixOS box into an infrastructure node with a k3s cluster, secrets management, and a Forgejo Actions
runner for building containers with Nix.
### K3s cluster
- Single-node k3s with Traefik/ServiceLB/metrics-server disabled (minimal footprint)
- TLS SAN set to `ringtail.tail8d86e.ts.net` so ArgoCD on indri can manage it via Tailscale
- Containerd registry mirrors pull through Zot on indri (`k3s-registries.yaml`)
- Tailscale interface added to `trustedInterfaces` for cross-node ArgoCD access
- `kubectl` added to system packages
### 1Password Connect + External Secrets Operator
- Four new ArgoCD apps targeting `k3s-ringtail`: `1password-connect-ringtail`, `external-secrets-crds-ringtail`, `external-secrets-ringtail`,
`external-secrets-config-ringtail`
- Reuses the same Helm charts/values as indri, just pointed at ringtail's k3s API server
- Bootstrap secrets (`op-credentials`, `onepassword-token`) provisioned by Ansible pre_tasks via `op read`, then applied to the `1password`
namespace in post_tasks
### Systemd Forgejo Actions runner
- Native `services.gitea-actions-runner` with `forgejo-runner` package — no DinD, no k8s pod, runs directly on the NixOS host
- Label `nix-container-builder:host` — jobs execute on the host with `nix`, `skopeo`, `nodejs`, etc. in PATH
- Registration token fetched from 1Password (`Forgejo Secrets/runner_reg`) by Ansible and written to `/etc/forgejo-runner/token.env`
- Runner's dynamic user (`gitea-runner`) added to `nix.settings.trusted-users` for nix daemon access
### Nix container build workflow
- New `.forgejo/workflows/build-container-nix.yaml` triggers on `*-nix-v[0-9]*` tags (e.g. `nettest-nix-v1.0.0`)
- Builds with `nix build -f containers/<name>/default.nix`, pushes to Zot via `skopeo copy`
- Existing Dockerfile workflow guarded with `if: !contains(github.ref_name, '-nix-v')` to avoid double-triggering
### Mise task updates
- `container-tag-and-release` auto-detects `default.nix` vs `Dockerfile` and uses the appropriate tag format (`-nix-v` vs `-v`)
- `container-list` shows build type indicator (`[nix]` / `[dockerfile]`)
## Post-merge
1. `mise run provision-ringtail` — deploys k3s token, runner token, NixOS rebuild
2. Register k3s cluster in ArgoCD (first time only):
```fish
ssh ringtail 'sudo cat /etc/rancher/k3s/k3s.yaml' | \
sed 's|127.0.0.1|ringtail.tail8d86e.ts.net|' > /tmp/k3s-ringtail.yaml
set -x KUBECONFIG /tmp/k3s-ringtail.yaml
argocd cluster add default --name k3s-ringtail
3. Sync ArgoCD apps in order: 1password-connect-ringtail -> external-secrets-crds-ringtail -> external-secrets-ringtail ->
external-secrets-config-ringtail
4. Verify runner: ssh ringtail 'systemctl status gitea-runner-nix-container-builder'
5. Check Forgejo admin panel for ringtail-nix-builder runner online
6. Test: create containers/<name>/default.nix, tag with <name>-nix-v0.1.0
Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/209
2026-02-18 21:15:30 -08:00
|
|
|
kubectl
|
2026-02-18 09:29:09 -08:00
|
|
|
python3 # required for Ansible
|
2026-02-18 08:24:25 -08:00
|
|
|
vim
|
|
|
|
|
htop
|
|
|
|
|
curl
|
|
|
|
|
wget
|
Polish ringtail NixOS config and add documentation (#208)
## Summary
- Fix Super+Return keybinding to launch wezterm in sway
- Set fish as default login shell
- Remove `initialPassword` (real password already set)
- Add 1Password CLI + GUI, chezmoi, and dev tool packages (neovim, eza, fd, fzf, zoxide, starship, atuin, bat, ripgrep)
- Add ringtail reference card, update host inventory and reference index
- Changelog fragment
## Post-merge deployment
- `mise run provision-ringtail` to rebuild NixOS
- On ringtail: launch 1Password GUI, enable CLI integration (Settings > Developer > CLI integration)
- Chezmoi needs `.chezmoiignore` updates in the dotfiles repo (separate task)
Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/208
2026-02-18 17:53:47 -08:00
|
|
|
chezmoi
|
|
|
|
|
neovim
|
|
|
|
|
eza
|
|
|
|
|
fd
|
|
|
|
|
fzf
|
|
|
|
|
zoxide
|
|
|
|
|
starship
|
|
|
|
|
atuin
|
|
|
|
|
bat
|
|
|
|
|
ripgrep
|
|
|
|
|
mise
|
|
|
|
|
gcc
|
|
|
|
|
gnumake
|
|
|
|
|
pkg-config
|
|
|
|
|
openssl
|
|
|
|
|
gnupg
|
|
|
|
|
unzip
|
|
|
|
|
fuzzel
|
|
|
|
|
pulseaudio
|
|
|
|
|
librewolf
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
# Allow running dynamically linked binaries (mise-installed runtimes, etc.)
|
|
|
|
|
programs.nix-ld.enable = true;
|
|
|
|
|
programs.nix-ld.libraries = buildDeps ++ [ pkgs.icu ];
|
|
|
|
|
|
|
|
|
|
# Compile-time flags for mise python-build and similar source builds
|
|
|
|
|
environment.sessionVariables = {
|
|
|
|
|
PKG_CONFIG_PATH = lib.makeSearchPath "lib/pkgconfig" (map lib.getDev buildDeps);
|
|
|
|
|
CFLAGS = lib.concatMapStringsSep " " (p: "-I${lib.getDev p}/include") buildDeps;
|
|
|
|
|
LDFLAGS = lib.concatMapStringsSep " " (p: "-L${lib.getLib p}/lib") buildDeps;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
# Fonts
|
|
|
|
|
fonts.packages = with pkgs; [
|
|
|
|
|
nerd-fonts.victor-mono
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
# Home Manager (minimal — chezmoi owns dotfiles, this is ringtail-specific)
|
|
|
|
|
home-manager.useGlobalPkgs = true;
|
|
|
|
|
home-manager.useUserPackages = true;
|
|
|
|
|
home-manager.users.eblume = {
|
|
|
|
|
home.stateVersion = "25.11";
|
|
|
|
|
|
|
|
|
|
wayland.windowManager.sway = {
|
|
|
|
|
enable = true;
|
|
|
|
|
checkConfig = false;
|
|
|
|
|
config = {
|
|
|
|
|
terminal = "wezterm";
|
|
|
|
|
modifier = "Mod4";
|
|
|
|
|
fonts = {
|
|
|
|
|
names = [ "VictorMono Nerd Font" ];
|
|
|
|
|
size = 10.0;
|
|
|
|
|
};
|
|
|
|
|
bars = [{ command = "waybar"; }];
|
|
|
|
|
gaps = {
|
|
|
|
|
inner = 8;
|
|
|
|
|
outer = 4;
|
|
|
|
|
};
|
|
|
|
|
window = {
|
|
|
|
|
border = 2;
|
|
|
|
|
titlebar = false;
|
2026-02-19 07:20:05 -08:00
|
|
|
commands = [
|
|
|
|
|
{ command = "inhibit_idle fullscreen"; criteria = { class = ".*"; }; }
|
|
|
|
|
{ command = "inhibit_idle fullscreen"; criteria = { app_id = ".*"; }; }
|
|
|
|
|
];
|
Polish ringtail NixOS config and add documentation (#208)
## Summary
- Fix Super+Return keybinding to launch wezterm in sway
- Set fish as default login shell
- Remove `initialPassword` (real password already set)
- Add 1Password CLI + GUI, chezmoi, and dev tool packages (neovim, eza, fd, fzf, zoxide, starship, atuin, bat, ripgrep)
- Add ringtail reference card, update host inventory and reference index
- Changelog fragment
## Post-merge deployment
- `mise run provision-ringtail` to rebuild NixOS
- On ringtail: launch 1Password GUI, enable CLI integration (Settings > Developer > CLI integration)
- Chezmoi needs `.chezmoiignore` updates in the dotfiles repo (separate task)
Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/208
2026-02-18 17:53:47 -08:00
|
|
|
};
|
|
|
|
|
colors = {
|
|
|
|
|
focused = {
|
|
|
|
|
border = "#8aadf4";
|
|
|
|
|
background = "#24273a";
|
|
|
|
|
text = "#cad3f5";
|
|
|
|
|
indicator = "#c6a0f6";
|
|
|
|
|
childBorder = "#8aadf4";
|
|
|
|
|
};
|
|
|
|
|
focusedInactive = {
|
|
|
|
|
border = "#494d64";
|
|
|
|
|
background = "#1e2030";
|
|
|
|
|
text = "#a5adcb";
|
|
|
|
|
indicator = "#494d64";
|
|
|
|
|
childBorder = "#494d64";
|
|
|
|
|
};
|
|
|
|
|
unfocused = {
|
|
|
|
|
border = "#363a4f";
|
|
|
|
|
background = "#1e2030";
|
|
|
|
|
text = "#6e738d";
|
|
|
|
|
indicator = "#363a4f";
|
|
|
|
|
childBorder = "#363a4f";
|
|
|
|
|
};
|
|
|
|
|
urgent = {
|
|
|
|
|
border = "#ed8796";
|
|
|
|
|
background = "#24273a";
|
|
|
|
|
text = "#cad3f5";
|
|
|
|
|
indicator = "#ed8796";
|
|
|
|
|
childBorder = "#ed8796";
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
input = {
|
|
|
|
|
"*" = {
|
|
|
|
|
xkb_options = "ctrl:nocaps";
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
output = {
|
|
|
|
|
"DP-1" = {
|
|
|
|
|
mode = "2560x1440@165Hz";
|
|
|
|
|
adaptive_sync = "on";
|
|
|
|
|
bg = "~/.config/sway/wallpaper.jpg fill";
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
keybindings = let mod = "Mod4"; in {
|
|
|
|
|
"${mod}+Return" = "exec wezterm";
|
|
|
|
|
"${mod}+Shift+q" = "kill";
|
|
|
|
|
"${mod}+d" = "exec wmenu-run";
|
|
|
|
|
"${mod}+space" = "exec fuzzel";
|
|
|
|
|
"${mod}+Shift+c" = "reload";
|
2026-02-19 06:46:37 -08:00
|
|
|
"${mod}+l" = "exec swaylock -f";
|
Polish ringtail NixOS config and add documentation (#208)
## Summary
- Fix Super+Return keybinding to launch wezterm in sway
- Set fish as default login shell
- Remove `initialPassword` (real password already set)
- Add 1Password CLI + GUI, chezmoi, and dev tool packages (neovim, eza, fd, fzf, zoxide, starship, atuin, bat, ripgrep)
- Add ringtail reference card, update host inventory and reference index
- Changelog fragment
## Post-merge deployment
- `mise run provision-ringtail` to rebuild NixOS
- On ringtail: launch 1Password GUI, enable CLI integration (Settings > Developer > CLI integration)
- Chezmoi needs `.chezmoiignore` updates in the dotfiles repo (separate task)
Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/208
2026-02-18 17:53:47 -08:00
|
|
|
"--locked XF86AudioMute" = "exec pactl set-sink-mute @DEFAULT_SINK@ toggle";
|
|
|
|
|
"--locked XF86AudioLowerVolume" = "exec pactl set-sink-volume @DEFAULT_SINK@ -5%";
|
|
|
|
|
"--locked XF86AudioRaiseVolume" = "exec pactl set-sink-volume @DEFAULT_SINK@ +5%";
|
|
|
|
|
"--locked XF86AudioMicMute" = "exec pactl set-source-mute @DEFAULT_SOURCE@ toggle";
|
|
|
|
|
};
|
|
|
|
|
startup = [
|
|
|
|
|
{ command = "1password"; }
|
|
|
|
|
{ command = "steam"; }
|
|
|
|
|
];
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2026-02-19 06:46:37 -08:00
|
|
|
programs.swaylock = {
|
|
|
|
|
enable = true;
|
|
|
|
|
settings = {
|
|
|
|
|
color = "24273a";
|
|
|
|
|
font = "VictorMono Nerd Font";
|
|
|
|
|
font-size = 24;
|
|
|
|
|
indicator-radius = 100;
|
|
|
|
|
indicator-thickness = 7;
|
|
|
|
|
inside-color = "24273a";
|
|
|
|
|
inside-clear-color = "24273a";
|
|
|
|
|
inside-ver-color = "24273a";
|
|
|
|
|
inside-wrong-color = "24273a";
|
|
|
|
|
key-hl-color = "8aadf4";
|
|
|
|
|
bs-hl-color = "ed8796";
|
|
|
|
|
ring-color = "363a4f";
|
|
|
|
|
ring-clear-color = "f5a97f";
|
|
|
|
|
ring-ver-color = "8aadf4";
|
|
|
|
|
ring-wrong-color = "ed8796";
|
|
|
|
|
line-color = "00000000";
|
|
|
|
|
line-clear-color = "00000000";
|
|
|
|
|
line-ver-color = "00000000";
|
|
|
|
|
line-wrong-color = "00000000";
|
|
|
|
|
separator-color = "00000000";
|
|
|
|
|
text-color = "cad3f5";
|
|
|
|
|
text-clear-color = "cad3f5";
|
|
|
|
|
text-ver-color = "cad3f5";
|
|
|
|
|
text-wrong-color = "ed8796";
|
|
|
|
|
show-failed-attempts = true;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
services.swayidle = {
|
|
|
|
|
enable = true;
|
|
|
|
|
events = [
|
|
|
|
|
{ event = "before-sleep"; command = "${pkgs.swaylock}/bin/swaylock -f"; }
|
|
|
|
|
{ event = "lock"; command = "${pkgs.swaylock}/bin/swaylock -f"; }
|
|
|
|
|
];
|
|
|
|
|
timeouts = [
|
|
|
|
|
{
|
|
|
|
|
timeout = 900; # 15 minutes — lock screen
|
|
|
|
|
command = "${pkgs.swaylock}/bin/swaylock -f";
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
timeout = 3600; # 60 minutes — turn off display
|
|
|
|
|
command = "${pkgs.sway}/bin/swaymsg 'output * dpms off'";
|
|
|
|
|
resumeCommand = "${pkgs.sway}/bin/swaymsg 'output * dpms on'";
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
};
|
|
|
|
|
|
Polish ringtail NixOS config and add documentation (#208)
## Summary
- Fix Super+Return keybinding to launch wezterm in sway
- Set fish as default login shell
- Remove `initialPassword` (real password already set)
- Add 1Password CLI + GUI, chezmoi, and dev tool packages (neovim, eza, fd, fzf, zoxide, starship, atuin, bat, ripgrep)
- Add ringtail reference card, update host inventory and reference index
- Changelog fragment
## Post-merge deployment
- `mise run provision-ringtail` to rebuild NixOS
- On ringtail: launch 1Password GUI, enable CLI integration (Settings > Developer > CLI integration)
- Chezmoi needs `.chezmoiignore` updates in the dotfiles repo (separate task)
Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/208
2026-02-18 17:53:47 -08:00
|
|
|
programs.fuzzel = {
|
|
|
|
|
enable = true;
|
|
|
|
|
settings = {
|
|
|
|
|
main = {
|
|
|
|
|
font = "VictorMono Nerd Font:size=14";
|
|
|
|
|
terminal = "wezterm";
|
|
|
|
|
width = 40;
|
|
|
|
|
horizontal-pad = 16;
|
|
|
|
|
vertical-pad = 8;
|
|
|
|
|
border-radius = 8;
|
|
|
|
|
border-width = 2;
|
|
|
|
|
};
|
|
|
|
|
colors = {
|
|
|
|
|
background = "24273add";
|
|
|
|
|
text = "cad3f5ff";
|
|
|
|
|
match = "8aadf4ff";
|
|
|
|
|
selection = "363a4fff";
|
|
|
|
|
selection-text = "cad3f5ff";
|
|
|
|
|
selection-match = "8aadf4ff";
|
|
|
|
|
border = "8aadf4ff";
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
programs.waybar = {
|
|
|
|
|
enable = true;
|
|
|
|
|
settings = [{
|
|
|
|
|
layer = "top";
|
|
|
|
|
position = "top";
|
|
|
|
|
height = 30;
|
|
|
|
|
modules-left = [ "sway/workspaces" "sway/mode" ];
|
|
|
|
|
modules-center = [ "sway/window" ];
|
|
|
|
|
modules-right = [ "pulseaudio" "bluetooth" "network" "clock" "tray" ];
|
|
|
|
|
tray = { spacing = 8; };
|
|
|
|
|
clock = { format = "{:%a %b %d %H:%M}"; };
|
|
|
|
|
network = {
|
|
|
|
|
interval = 2;
|
|
|
|
|
format-ethernet = "{bandwidthDownBits} down {bandwidthUpBits} up";
|
|
|
|
|
format-wifi = "{essid} {bandwidthDownBits} down {bandwidthUpBits} up";
|
|
|
|
|
format-disconnected = "disconnected";
|
|
|
|
|
};
|
|
|
|
|
pulseaudio = {
|
|
|
|
|
format = "{icon} {volume}%";
|
|
|
|
|
format-muted = " muted";
|
|
|
|
|
format-icons = {
|
|
|
|
|
headphone = "";
|
|
|
|
|
default = [ "" "" "" ];
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
}];
|
|
|
|
|
style = ''
|
|
|
|
|
* {
|
|
|
|
|
font-family: "VictorMono Nerd Font";
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
border: none;
|
|
|
|
|
border-radius: 0;
|
|
|
|
|
min-height: 0;
|
|
|
|
|
}
|
|
|
|
|
window#waybar {
|
|
|
|
|
background-color: rgba(30, 32, 48, 0.9);
|
|
|
|
|
color: #cad3f5;
|
|
|
|
|
margin: 4px 4px 0 4px;
|
|
|
|
|
}
|
|
|
|
|
#workspaces button {
|
|
|
|
|
padding: 0 8px;
|
|
|
|
|
margin: 0 2px;
|
|
|
|
|
color: #6e738d;
|
|
|
|
|
background: transparent;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
}
|
|
|
|
|
#workspaces button.focused {
|
|
|
|
|
color: #8aadf4;
|
|
|
|
|
background: #363a4f;
|
|
|
|
|
border-bottom: 2px solid #8aadf4;
|
|
|
|
|
}
|
|
|
|
|
#workspaces button.urgent {
|
|
|
|
|
color: #ed8796;
|
|
|
|
|
}
|
|
|
|
|
#window {
|
|
|
|
|
color: #a5adcb;
|
|
|
|
|
}
|
|
|
|
|
#bluetooth {
|
|
|
|
|
color: #8aadf4;
|
|
|
|
|
}
|
|
|
|
|
#bluetooth.off, #bluetooth.disabled {
|
|
|
|
|
color: #6e738d;
|
|
|
|
|
}
|
|
|
|
|
#clock, #network, #pulseaudio, #bluetooth, #tray {
|
|
|
|
|
padding: 0 12px;
|
|
|
|
|
margin: 4px 2px;
|
|
|
|
|
color: #cad3f5;
|
|
|
|
|
background: #363a4f;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
}
|
|
|
|
|
#clock {
|
|
|
|
|
color: #8aadf4;
|
|
|
|
|
}
|
|
|
|
|
#pulseaudio {
|
|
|
|
|
color: #f5a97f;
|
|
|
|
|
}
|
|
|
|
|
#network {
|
|
|
|
|
color: #a6da95;
|
|
|
|
|
}
|
|
|
|
|
#network.disconnected {
|
|
|
|
|
color: #ed8796;
|
|
|
|
|
}
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
# Ensure mounted drives are owned by eblume
|
|
|
|
|
systemd.tmpfiles.rules = [
|
|
|
|
|
"d /mnt/games 0755 eblume users -"
|
|
|
|
|
"d /mnt/storage1 0755 eblume users -"
|
|
|
|
|
"d /mnt/storage2 0755 eblume users -"
|
2026-02-18 08:24:25 -08:00
|
|
|
];
|
|
|
|
|
|
Add k3s, 1Password Connect, and systemd nix-container-builder to ringtail (#209)
## Summary
Extends ringtail from a desktop/gaming NixOS box into an infrastructure node with a k3s cluster, secrets management, and a Forgejo Actions
runner for building containers with Nix.
### K3s cluster
- Single-node k3s with Traefik/ServiceLB/metrics-server disabled (minimal footprint)
- TLS SAN set to `ringtail.tail8d86e.ts.net` so ArgoCD on indri can manage it via Tailscale
- Containerd registry mirrors pull through Zot on indri (`k3s-registries.yaml`)
- Tailscale interface added to `trustedInterfaces` for cross-node ArgoCD access
- `kubectl` added to system packages
### 1Password Connect + External Secrets Operator
- Four new ArgoCD apps targeting `k3s-ringtail`: `1password-connect-ringtail`, `external-secrets-crds-ringtail`, `external-secrets-ringtail`,
`external-secrets-config-ringtail`
- Reuses the same Helm charts/values as indri, just pointed at ringtail's k3s API server
- Bootstrap secrets (`op-credentials`, `onepassword-token`) provisioned by Ansible pre_tasks via `op read`, then applied to the `1password`
namespace in post_tasks
### Systemd Forgejo Actions runner
- Native `services.gitea-actions-runner` with `forgejo-runner` package — no DinD, no k8s pod, runs directly on the NixOS host
- Label `nix-container-builder:host` — jobs execute on the host with `nix`, `skopeo`, `nodejs`, etc. in PATH
- Registration token fetched from 1Password (`Forgejo Secrets/runner_reg`) by Ansible and written to `/etc/forgejo-runner/token.env`
- Runner's dynamic user (`gitea-runner`) added to `nix.settings.trusted-users` for nix daemon access
### Nix container build workflow
- New `.forgejo/workflows/build-container-nix.yaml` triggers on `*-nix-v[0-9]*` tags (e.g. `nettest-nix-v1.0.0`)
- Builds with `nix build -f containers/<name>/default.nix`, pushes to Zot via `skopeo copy`
- Existing Dockerfile workflow guarded with `if: !contains(github.ref_name, '-nix-v')` to avoid double-triggering
### Mise task updates
- `container-tag-and-release` auto-detects `default.nix` vs `Dockerfile` and uses the appropriate tag format (`-nix-v` vs `-v`)
- `container-list` shows build type indicator (`[nix]` / `[dockerfile]`)
## Post-merge
1. `mise run provision-ringtail` — deploys k3s token, runner token, NixOS rebuild
2. Register k3s cluster in ArgoCD (first time only):
```fish
ssh ringtail 'sudo cat /etc/rancher/k3s/k3s.yaml' | \
sed 's|127.0.0.1|ringtail.tail8d86e.ts.net|' > /tmp/k3s-ringtail.yaml
set -x KUBECONFIG /tmp/k3s-ringtail.yaml
argocd cluster add default --name k3s-ringtail
3. Sync ArgoCD apps in order: 1password-connect-ringtail -> external-secrets-crds-ringtail -> external-secrets-ringtail ->
external-secrets-config-ringtail
4. Verify runner: ssh ringtail 'systemctl status gitea-runner-nix-container-builder'
5. Check Forgejo admin panel for ringtail-nix-builder runner online
6. Test: create containers/<name>/default.nix, tag with <name>-nix-v0.1.0
Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/209
2026-02-18 21:15:30 -08:00
|
|
|
# Forgejo Actions runner (nix container builder)
|
|
|
|
|
services.gitea-actions-runner = {
|
|
|
|
|
package = pkgs.forgejo-runner;
|
|
|
|
|
instances.nix_container_builder = {
|
|
|
|
|
enable = true;
|
|
|
|
|
name = "ringtail-nix-builder";
|
|
|
|
|
url = "https://forge.ops.eblu.me";
|
|
|
|
|
tokenFile = "/etc/forgejo-runner/token.env";
|
|
|
|
|
labels = [ "nix-container-builder:host" ];
|
|
|
|
|
hostPackages = with pkgs; [
|
|
|
|
|
bash coreutils curl gawk gitMinimal gnused nodejs wget
|
|
|
|
|
nix skopeo
|
|
|
|
|
];
|
|
|
|
|
settings = {
|
|
|
|
|
log.level = "info";
|
|
|
|
|
runner = {
|
|
|
|
|
capacity = 1;
|
|
|
|
|
timeout = "3h";
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2026-02-18 08:24:25 -08:00
|
|
|
# Enable nix flakes
|
|
|
|
|
nix.settings.experimental-features = [ "nix-command" "flakes" ];
|
|
|
|
|
|
Add k3s, 1Password Connect, and systemd nix-container-builder to ringtail (#209)
## Summary
Extends ringtail from a desktop/gaming NixOS box into an infrastructure node with a k3s cluster, secrets management, and a Forgejo Actions
runner for building containers with Nix.
### K3s cluster
- Single-node k3s with Traefik/ServiceLB/metrics-server disabled (minimal footprint)
- TLS SAN set to `ringtail.tail8d86e.ts.net` so ArgoCD on indri can manage it via Tailscale
- Containerd registry mirrors pull through Zot on indri (`k3s-registries.yaml`)
- Tailscale interface added to `trustedInterfaces` for cross-node ArgoCD access
- `kubectl` added to system packages
### 1Password Connect + External Secrets Operator
- Four new ArgoCD apps targeting `k3s-ringtail`: `1password-connect-ringtail`, `external-secrets-crds-ringtail`, `external-secrets-ringtail`,
`external-secrets-config-ringtail`
- Reuses the same Helm charts/values as indri, just pointed at ringtail's k3s API server
- Bootstrap secrets (`op-credentials`, `onepassword-token`) provisioned by Ansible pre_tasks via `op read`, then applied to the `1password`
namespace in post_tasks
### Systemd Forgejo Actions runner
- Native `services.gitea-actions-runner` with `forgejo-runner` package — no DinD, no k8s pod, runs directly on the NixOS host
- Label `nix-container-builder:host` — jobs execute on the host with `nix`, `skopeo`, `nodejs`, etc. in PATH
- Registration token fetched from 1Password (`Forgejo Secrets/runner_reg`) by Ansible and written to `/etc/forgejo-runner/token.env`
- Runner's dynamic user (`gitea-runner`) added to `nix.settings.trusted-users` for nix daemon access
### Nix container build workflow
- New `.forgejo/workflows/build-container-nix.yaml` triggers on `*-nix-v[0-9]*` tags (e.g. `nettest-nix-v1.0.0`)
- Builds with `nix build -f containers/<name>/default.nix`, pushes to Zot via `skopeo copy`
- Existing Dockerfile workflow guarded with `if: !contains(github.ref_name, '-nix-v')` to avoid double-triggering
### Mise task updates
- `container-tag-and-release` auto-detects `default.nix` vs `Dockerfile` and uses the appropriate tag format (`-nix-v` vs `-v`)
- `container-list` shows build type indicator (`[nix]` / `[dockerfile]`)
## Post-merge
1. `mise run provision-ringtail` — deploys k3s token, runner token, NixOS rebuild
2. Register k3s cluster in ArgoCD (first time only):
```fish
ssh ringtail 'sudo cat /etc/rancher/k3s/k3s.yaml' | \
sed 's|127.0.0.1|ringtail.tail8d86e.ts.net|' > /tmp/k3s-ringtail.yaml
set -x KUBECONFIG /tmp/k3s-ringtail.yaml
argocd cluster add default --name k3s-ringtail
3. Sync ArgoCD apps in order: 1password-connect-ringtail -> external-secrets-crds-ringtail -> external-secrets-ringtail ->
external-secrets-config-ringtail
4. Verify runner: ssh ringtail 'systemctl status gitea-runner-nix-container-builder'
5. Check Forgejo admin panel for ringtail-nix-builder runner online
6. Test: create containers/<name>/default.nix, tag with <name>-nix-v0.1.0
Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/209
2026-02-18 21:15:30 -08:00
|
|
|
# Allow the runner's dynamic user to access the nix daemon
|
|
|
|
|
nix.settings.trusted-users = [ "gitea-runner" ];
|
|
|
|
|
|
2026-02-19 06:46:37 -08:00
|
|
|
# Prevent machine from sleeping (workstation should stay on)
|
|
|
|
|
systemd.sleep.extraConfig = ''
|
|
|
|
|
AllowSuspend=no
|
|
|
|
|
AllowHibernation=no
|
|
|
|
|
AllowHybridSleep=no
|
|
|
|
|
AllowSuspendThenHibernate=no
|
|
|
|
|
'';
|
|
|
|
|
|
2026-02-18 08:24:25 -08:00
|
|
|
# NixOS release
|
|
|
|
|
system.stateVersion = "25.11";
|
|
|
|
|
}
|