2 Commits

Author SHA1 Message Date
1bdc1beb3f force sync 2026-01-20 15:16:12 -05:00
c55f860e29 exclude mod breaking buckets, boats, and hoes 2026-01-20 15:08:03 -05:00
33 changed files with 234 additions and 1639 deletions

View File

@@ -1,32 +0,0 @@
# This is an example configuration file
# To learn more, see the full config.yaml reference: https://docs.continue.dev/reference
name: ollama
version: 1.0.0
schema: v1
# Define which models can be used
# https://docs.continue.dev/customization/models
models:
- name: StarCoder2 Local
provider: ollama
model: starcoder2:7b
modelTimeout: "5s"
roles:
- autocomplete
autocompleteOptions:
useCache: true
useImports: true
useRecentlyEdited: true
- name: Nomic Embed Local
provider: ollama
model: nomic-embed-text:latest
roles:
- embed
- name: Autodetect
provider: ollama
model: AUTODETECT
defaultCompletionOptions:
contextLength: 64000
# MCP Servers that Continue can access
# https://docs.continue.dev/customization/mcp-tools
mcpServers:
- uses: anthropic/memory-mcp

View File

@@ -1,125 +0,0 @@
---
description: |
Use when auditing NixOS flake inputs or installed modules for known CVEs,
checking pinned revisions against security advisories, scanning repo code for
vulnerabilities, or running IaC/SCA audits on the nix-dotfiles repo. Use this
agent whenever flake.lock is updated or a new input/module is added.
tools: [read, 'io.snyk/mcp/*', search, web, 'nixos/*']
---
# Dependency Security Auditor
You are a dependency security auditor for this NixOS flake repository. Your job
is to identify known CVEs, security advisories, and vulnerable package versions
across flake inputs, NixOS modules, and repo code — without interacting with any
hosted infrastructure or live services.
## Scope
- Read `flake.lock` to enumerate all pinned inputs.
- Read `flake.nix` and system/module configs to identify which NixOS packages
and services are in active use.
- Use the nixos MCP and Snyk MCP to cross-reference versions against known
vulnerabilities.
- Use the web tool only to look up public CVE/advisory databases (NVD, GitHub
Security Advisories, NixOS security tracker). Do NOT connect to any hosted
service in this infrastructure.
## Constraints
- DO NOT edit, create, or delete any files.
- DO NOT run terminal commands.
- DO NOT connect to or probe any live service (Gitea, Mattermost, Nextcloud,
HAProxy, etc.).
- DO NOT authenticate to Snyk on behalf of the user without confirming first
— call `snyk_auth_status` and report back if auth is missing.
- ONLY report findings grounded in real CVE/advisory data with a reference URL
or ID.
## Audit Steps
Work through these steps in order. Show a summary of what you checked at the end
of each step.
### Step 1: Enumerate Flake Inputs
Read `flake.lock` and extract for each node:
- Owner, repo, rev (commit hash), lastModified date
- Whether it is a `github`, `git`, or `tarball` type
Flag any inputs that:
- Have not been updated in > 180 days (stale pinning risk)
- Use a mutable `ref` without a fixed `rev` (reproducibility risk)
- Are fetched over plain HTTP (not HTTPS)
### Step 2: Look Up Active Package Versions via nixos MCP
For the pinned nixpkgs revision, use the nixos MCP (`nixos_search`,
`nixos_info`) to:
- Look up key security-sensitive packages in use across palatine-hill:
`mattermost`, `gitea`, `nextcloud`, `postgresql`, `hydra`, `attic`,
`ollama`, `loki`, `minio`, `haproxy`, `samba`.
- Note the package version returned.
- Search for any known vulnerabilities associated with that version using the
nixos MCP and the web tool (NVD: `https://nvd.nist.gov/vuln/search`, GitHub
advisory DB: `https://github.com/advisories`).
### Step 3: Run Snyk Code Scan
Before running, call `snyk_auth_status` to confirm authentication. If
unauthenticated, report that and skip this step.
Run `snyk_code_scan` on the absolute repo path
(`/home/alice/.gitprojects/nix-dotfiles`) with `severity_threshold: medium`.
Report all findings with:
- Rule ID and CWE
- Affected file and line
- Severity
- Suggested fix
### Step 4: Run Snyk IaC Scan
Run `snyk_iac_scan` on the absolute repo path
(`/home/alice/.gitprojects/nix-dotfiles`) with `severity_threshold: medium`.
While Snyk IaC does not natively parse Nix, it will catch any Kubernetes, Docker
Compose, or YAML configs present in `systems/palatine-hill/docker/` and similar
paths.
Report all findings with:
- Issue title and severity
- Affected file and line
- Impact description
- Suggested fix
### Step 5: Cross-Check NixOS Security Tracker
Use the web tool to check `https://github.com/NixOS/nixpkgs/issues?q=CVE` and
`https://discourse.nixos.org/c/security` for any open CVEs affecting:
- The pinned nixpkgs revision (from `flake.lock`)
- Any of the key packages identified in Step 2
### Step 6: Summarise
Produce a final report with:
1. **Critical / High CVEs** — packages with active, unpatched CVEs in the
pinned revision
2. **Stale Inputs** — inputs not updated in > 180 days
3. **Snyk Code Findings** — medium+ severity SAST issues
4. **Snyk IaC Findings** — medium+ severity misconfigurations in non-Nix config
files
5. **Clean** — categories with no findings (list explicitly so the report is
complete)
Each finding must include:
- Severity
- CVE ID or Snyk rule ID (with reference URL)
- Affected package/file/input
- Recommended action (upgrade nixpkgs pin, patch config, etc.)

View File

@@ -1,140 +0,0 @@
---
description: |
Use when auditing NixOS server configurations for security issues, checking
for secrets in the Nix store, exposed ports, weak authentication, missing
service hardening, overly permissive firewall rules, SSH misconfiguration,
Docker socket exposure, or SOPS secrets mishandling. Read-only. Does NOT
interact with any live infrastructure or hosted resources.
tools: [read, search, 'nixos/*']
---
# Security Researcher
You are a security researcher auditing this NixOS flake repository for potential
vulnerabilities and misconfigurations. Your job is to read the configuration
as-written and identify security issues an attacker or misconfiguration could
exploit.
## Scope
- Inspect server systems only (`server = true`; currently **palatine-hill**).
- Work entirely from repository source files. DO NOT interact with any live
system, hosted service, URL, or external resource.
- Use the nixos MCP tool to look up option defaults and known behaviours — not
to reach external hosts.
## Constraints
- DO NOT edit, create, or delete any files.
- DO NOT run terminal commands.
- DO NOT fetch URLs or browse the web.
- DO NOT attempt to connect to, probe, or fingerprint any live service.
- ONLY report issues that are grounded in the actual content of the repository
files.
## Audit Checklist
Work through these categories in order. For each, read the relevant files before
reporting.
### 1. Secrets in the Nix Store
- Are any passwords, tokens, or API keys hardcoded in `.nix` files (not behind
SOPS)?
- Are `password = "..."` fields used in NixOS module options that end up
world-readable in `/nix/store`?
- Check service DB password fields, `initialScript`, environment variables, and
`settings` blocks.
- Use the nixos MCP tool to confirm whether a given option value lands in the
store.
### 2. SOPS Secrets Hygiene
- Do `sops.secrets` entries have the correct `owner` set to the service user
(not `root` unless necessary)?
- Is `defaultSopsFile` scoped correctly, or could one system's secrets bleed
into another?
- Are any secrets referenced in config that are not declared in `sops.secrets`?
### 3. Firewall and Attack Surface
- Which TCP/UDP ports are exposed in `firewall.nix`? Are all of them
intentional and documented?
- Are `trustedInterfaces` entries broader than necessary (e.g., `br+` covering
all bridge interfaces)?
- Does `extraCommands` insert raw iptables rules that bypass the NixOS firewall
abstraction in a dangerous way?
- Are any high-risk ports (22, 80, 443, 5432, 6379, 27017) exposed directly?
### 4. SSH Configuration
- What port is SSH running on? Is password authentication disabled?
- Are `PermitRootLogin`, `PasswordAuthentication`, and `PubkeyAuthentication`
set explicitly?
- Check `modules/openssh.nix` and any system-level overrides.
### 5. PostgreSQL Authentication
- Does `authentication` (pg_hba) use `trust` for any user or database?
- Are `scram-sha-256` or `peer` used consistently rather than `md5` or
`password`?
- Does any service connect over TCP with a plaintext password that ends up in
the Nix store?
- Are `ensureUsers` entries scoped correctly (no unnecessary `superuser` or
`createdb` grants)?
### 6. Service Isolation and Hardening
- Do systemd services set `DynamicUser`, `PrivateTmp`, `NoNewPrivileges`,
`ProtectSystem`, or similar hardening options where applicable?
- Check custom `systemd.services` blocks for missing or weak sandboxing.
- Are services running as root that should run as a dedicated user?
### 7. Docker and Container Security
- Is the Docker socket (`/var/run/docker.sock`) mounted into any container? If
so, flag it as a privilege escalation vector.
- Are any containers run with `--privileged` or `network_mode: host`?
- Are Docker compose files in the repo using hardcoded secrets or environment
variables that land in the store?
### 8. Web-Facing Services
- Do reverse-proxied services (Gitea, Mattermost, Nextcloud, etc.) set
`siteUrl`/`ROOT_URL` to HTTPS?
- Is there any service that could be accessed over plain HTTP internally?
- Are ACME/TLS certs scoped correctly and not shared across unrelated services?
### 9. Module Defaults That Are Security-Sensitive
- For each enabled service, use the nixos MCP tool to check if the default
values for security-relevant options (e.g., `database.password`,
`openFirewall`, `enableAdminCreateUser`) are safe, and confirm whether
defaults are overridden in the repo.
### 10. Broad Permission Grants
- Are any users granted `wheel`, `docker`, or other privileged groups without
clear justification?
- Does any non-human service account have `superuser`, `replication`, or
`createrole` PostgreSQL clauses?
## Output Format
Report findings as a numbered list grouped by severity:
- **Critical** — direct path to credentials exposure, RCE, or privilege
escalation
- **High** — exploitable misconfiguration or data exposure under realistic
conditions
- **Medium** — weak default, unnecessary privilege, or defence-in-depth gap
- **Low / Info** — hardening improvement or minor noise
Each finding must include:
- Severity label
- Exact file path and line (as a markdown link)
- One-sentence explanation of the risk
- Concrete suggested remediation
If a category is clean, state that explicitly so the report is complete.

View File

@@ -1,81 +0,0 @@
---
description: |
Use when reviewing server infrastructure, auditing NixOS server
configurations, planning how new services or modules integrate into
palatine-hill, checking for missing imports, DB/user alignment, firewall
gaps, module argument signatures, or reverse proxy routing. DO NOT use for
making changes or for desktop/workstation systems.
tools: [read, search, 'nixos/*']
---
# Infrastructure Architect
You are an infrastructure architect for this NixOS flake repository. Your job is
to review the existing server architecture and analyse how proposed or recently
added changes integrate with it.
## Scope
You only inspect **server** machines. In this repository that means systems where
`server = true` in their `default.nix` — currently **palatine-hill**. Do NOT
inspect or opine on desktop systems such as `artemision` or `selinunte` unless
explicitly asked.
## Constraints
- DO NOT edit, create, or delete any files.
- DO NOT run terminal commands.
- DO NOT make assumptions — read the actual files.
- ONLY report concrete, actionable findings with exact file and line references.
## Approach
When asked to review a change or audit the server state, work through these
checkpoints in order:
1. **Module registration** — Is the new `.nix` file imported in
`systems/<host>/configuration.nix`? Check the `imports` list.
2. **Module argument signature** — Does every module accept `{ ..., ... }:` to
absorb `specialArgs` (`system`, `server`, `inputs`, `outputs`)? A missing
`...` causes "unexpected argument" eval errors.
3. **Service dependencies** — Does the new service depend on another (e.g.
PostgreSQL, Redis, S3/Minio)? If so:
- Is the dependency service enabled and imported on this host?
- Are the required DB names and users present in `ensureDatabases` /
`ensureUsers`?
- Is the user name in `ensureUsers` consistent with what the service module
defaults to? (Use the nixos MCP tool to check default values.)
- Are authentication rules (`pg_hba`, `authentication` block) present for
the new user?
4. **Secrets alignment** — If the service uses SOPS secrets, are they declared
in `sops.secrets` with the correct `owner`? Does the secrets key exist in
`secrets.yaml`?
5. **Firewall exposure** — Is the service port opened in `firewall.nix`? If
traffic is reverse-proxied (e.g. via external HAProxy), no direct port
exposure in NixOS firewall is needed — confirm which model applies.
6. **Reverse proxy / TLS** — Is a proxy rule (HAProxy, nginx, Caddy) defined
for the new vhost? If the proxy is managed externally, note that explicitly.
Check that `siteUrl` / `ROOT_URL` / equivalent matches the actual domain.
7. **Upgrade / backup plumbing** — If the service has stateful data, is it
listed in `postgresql.upgrade.stopServices`? Is it covered by
`postgresqlBackup`?
8. **Module provisioning conflicts** — Does the NixOS module have a
`create`/`createLocally` option that auto-provisions a DB/user? If manual
provisioning also exists, flag potential ownership drift.
## Output Format
Report findings as a numbered list grouped by severity:
- **High** — will cause a build failure, service crash, or security issue
- **Medium** — will cause silent misconfiguration or future breakage
- **Low / Info** — style, redundancy, or optional improvements
Each finding must include:
- The severity label
- The exact file path and line (as a markdown link)
- A one-sentence explanation of the problem
- A concrete suggested fix
If everything checks out, say so explicitly and summarise what you verified.

View File

@@ -1,698 +0,0 @@
# Nix Dotfiles Repository Guide
This repository contains NixOS configurations for personal infrastructure. The setup is organized around a flake-based structure with per-system configurations and user-specific settings.
## Project Structure
- `flake.nix` - Main flake definition with inputs and outputs
- `systems/` - Per-system configurations (e.g., `artemision`, `palatine-hill`)
- `users/` - Per-user configurations using home-manager
- `modules/` - Reusable Nix modules for common services
- `lib/` - Custom Nix library functions
- `hydra/` - Hydra CI/CD configuration
- `secrets/` - SOPS encrypted secrets
## Key Concepts
### System Configuration
Each system has its own directory under `systems/` containing:
- `configuration.nix` - Main system configuration
- Component modules (audio.nix, desktop.nix, etc.)
- Hardware-specific configurations
### User Configuration
User configurations are in `users/<username>/`:
- `home.nix` - Home-manager configuration using `home.packages` and imports
- `secrets.yaml` - SOPS-encrypted secrets using age encryption
- `non-server.nix` - Desktop-specific configurations
### Nix Patterns
1. **Module-based approach**: Uses Nix modules for organizing configuration
1. **Home-manager integration**: User environment managed via home-manager
1. **SOPS secrets**: Secrets managed with SOPS and age encryption
1. **Flake-based**: Uses flakes for reproducible builds and development environments
1. **Multi-system support**: Supports multiple machines with different configurations
1. **Dynamic configuration generation**: Modules in the `modules/` directory are automatically imported into all systems (can be overridden per system). New systems are automatically discovered by `genSystems()`
### Modern Nix Features
This repository uses modern Nix features including:
- **Flakes**: Enabled via `flake` experimental feature
- **Nix Command**: Enabled via `nix-command` experimental feature
- **Blake3 Hashes**: Enabled via `blake3-hashes` experimental feature
- **Git Hashing**: Enabled via `git-hashing` experimental feature
- **Verified Fetches**: Enabled via `verified-fetches` experimental feature
### Key Commands
- `nh os switch` - Apply system configuration (using nix-community/nh)
- `nh home switch` - Apply user configuration (using nix-community/nh)
- `nh os build` - Build a specific system (using nix-community/nh)
- `nix build .#<system>` - Build a specific system
- `nix run .#<system>` - Run a specific system
- `nix flake update` - Update flake inputs
### Development Workflow
1. Make changes to system or user configuration
1. Test with `nh os switch` or `nh home switch`
1. For CI/CD, Hydra automatically builds and tests changes
1. Secrets are managed with SOPS and age keys
### Important Files
- `flake.nix` - Main entry point for the flake
- `systems/artemision/configuration.nix` - Example system configuration
- `users/alice/home.nix` - Example user configuration
- `modules/base.nix` - Base module with common settings
- `hydra/jobsets.nix` - Hydra CI configuration
### External Dependencies
- NixOS unstable channel
- Nixpkgs unstable channel
- SOPS for secrets management
- age for encryption
- home-manager for user environments
- nh (nix-community/nh) for simplified Nix operations
### Nix MCP Server
- Use the nix MCP server for looking up package names and options
- Specify `unstable` channel if the channel is specifiable (e.g., for `pkgs.<package-name>`)
## Dynamic Configuration System (lib/systems.nix)
This repository automatically generates NixOS system configurations based on the folder structure. Understanding how `constructSystem` and `genSystems` work is essential when adding new systems or global modules.
### How Configuration Generation Works
The process happens in three stages:
**Stage 1: Discovery** (`flake.nix``genSystems`)
- `flake.nix` calls `genSystems inputs outputs src (src + "/systems")`
- `genSystems` scans the `systems/` directory and lists all subdirectories
- Each subdirectory name becomes a system hostname (e.g., `artemision`, `palatine-hill`)
**Stage 2: Parameter Loading** (`genSystems` reads `default.nix`)
- For each discovered system, `genSystems` imports `systems/<hostname>/default.nix`
- This file exports parameters for `constructSystem` like:
- `users = [ "alice" ]` — which users to create
- `home = true` — enable home-manager
- `sops = true` — enable secret decryption
- `server = true/false` — machine role
- `modules = [ ... ]` — additional system-specific modules
**Stage 3: Assembly** (`constructSystem` assembles the full config)
- Loads essential system files: `hardware.nix`, `configuration.nix`
- Auto-imports all `.nix` files from `modules/` directory via `lib.adev.fileList`
- Conditionally loads home-manager, SOPS, and user configs based on parameters
- Merges everything into a complete NixOS system configuration
### Key Functions in lib/systems.nix
| Function | Purpose | Called By |
|----------|---------|-----------|
| `genSystems` | Scans `systems/` directory and creates configs for each subdirectory | `flake.nix` |
| `constructSystem` | Assembles a single NixOS system with all modules and configs | `genSystems` |
| `genHome` | Imports home-manager configs for specified users | `constructSystem` |
| `genSops` | Imports SOPS-encrypted secrets for users | `constructSystem` |
| `genUsers` | Imports user account configs from `users/<username>/` | `constructSystem` |
| `genHostName` | Creates hostname attribute set | `constructSystem` |
| `genWrapper` | Conditionally applies generator functions | `constructSystem` |
### Special Arguments Passed to All Configs
These are available in `configuration.nix`, `hardware.nix`, and all modules:
```nix
{ config, pkgs, lib, inputs, outputs, server, system, ... }:
```
- `config` — NixOS configuration options
- `pkgs` — Nix packages (nixpkgs)
- `lib` — Nix library functions (extended with `lib.adev`)
- `inputs` — Flake inputs (nixpkgs, home-manager, sops-nix, etc.)
- `outputs` — Flake outputs (for Hydra and other tools)
- `server` — Boolean: true for servers, false for desktops
- `system` — System architecture string (e.g., `"x86_64-linux"`)
## Adding a New NixOS System
### Step 1: Create the Directory Structure
```bash
mkdir -p systems/<new-hostname>
cd systems/<new-hostname>
```
### Step 2: Create `default.nix` (System Parameters)
This file is automatically discovered and loaded by `genSystems`. It exports the parameters passed to `constructSystem`.
**Minimal example:**
```nix
{ inputs }:
{
# Required: List of users to create (must have entries in users/ directory)
users = [ "alice" ];
# Optional: Enable home-manager (default: true)
home = true;
# Optional: Enable SOPS secrets (default: true)
sops = true;
# Optional: Is this a server? Used to conditionally enable server features
server = false;
# Optional: System architecture (default: "x86_64-linux")
system = "x86_64-linux";
# Optional: System-specific modules (in addition to global modules/)
modules = [
# ./custom-service.nix
];
}
```
**See `systems/palatine-hill/default.nix` for a complex example with all options.**
### Step 3: Create `hardware.nix` (Hardware Configuration)
Generate this via:
```bash
sudo nixos-generate-config --show-hardware-config > systems/<new-hostname>/hardware.nix
```
This file typically includes:
- Boot configuration and bootloader
- Filesystem mounts and ZFS/LVM settings
- Hardware support (CPU, GPU, network drivers)
- Device-specific kernel modules
### Step 4: Create `configuration.nix` (System Configuration)
This is the main NixOS configuration file. Structure:
```nix
{ config, pkgs, lib, inputs, server, system, ... }:
{
# System hostname (usually matches directory name)
networking.hostName = "new-hostname";
# Desktop/desktop specific config
services.xserver.enable = !server;
# System packages
environment.systemPackages = with pkgs; [
# ...
];
# Services to enable
services.openssh.enable = server;
# System-specific settings override global defaults
boot.kernelParams = [ "nomodeset" ];
}
```
### Step 5: Add Optional Secrets
If the system has sensitive data:
```bash
# Create and encrypt secrets file
sops systems/<new-hostname>/secrets.yaml
# This will be automatically loaded by genSops if sops = true
```
### Step 6: Add Optional System-Specific Modules
For system-specific functionality that shouldn't be global, create separate `.nix` files in the system directory:
```text
systems/<new-hostname>/
├── configuration.nix # Main config
├── default.nix
├── hardware.nix
├── secrets.yaml # (optional)
├── custom-service.nix # (optional) System-specific modules
├── networking.nix # (optional)
└── graphics.nix # (optional)
```
Reference these in `default.nix`:
```nix
{ inputs }:
{
users = [ "alice" ];
modules = [
./custom-service.nix
./networking.nix
./graphics.nix
];
}
```
### Step 7: Deploy the New System
The system is now automatically registered! Deploy with:
```bash
# Build the new system
nix build .#<new-hostname>
# Or if you want to switch immediately
nh os switch
```
## Adding a Global Module to modules/
Global modules are automatically imported into all systems. No registration needed.
### Create a Module File
Add a new `.nix` file to the `modules/` directory. Example: `modules/my-service.nix`
### Module Structure
```nix
{ config, pkgs, lib, inputs, server, ... }:
{
# Define configuration options for this module
options.myService = {
enable = lib.mkEnableOption "my service";
port = lib.mkOption {
type = lib.types.int;
default = 3000;
description = "Port for the service";
};
};
# Actual configuration (conditional on enable option)
config = lib.mkIf config.myService.enable {
environment.systemPackages = [ pkgs.my-service ];
systemd.services.my-service = {
description = "My Service";
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "${pkgs.my-service}/bin/my-service";
Restart = "always";
};
};
};
}
```
### Using mkIf, mkDefault, and mkForce
- **`mkIf`** — Conditionally apply config based on a boolean
```nix
config = lib.mkIf config.myService.enable { ... };
```
- **`mkDefault`** — Provide a default value that can be overridden
```nix
boot.kernelParams = lib.mkDefault [ "quiet" ];
```
- **`mkForce`** — Force a value, preventing other modules from overriding
```nix
services.openssh.enable = lib.mkForce true;
```
- **`mkEnableOption`** — Define an `enable` option with standard description
```nix
options.myService.enable = lib.mkEnableOption "my service";
```
### Disable a Global Module for a Specific System
To disable a module for one system, override it in that system's `configuration.nix`:
```nix
{ config, lib, ... }:
{
# Disable the module entirely
myService.enable = false;
# Or override specific options
services.openssh.port = 2222;
}
```
### Module Loading Order in constructSystem
Modules are applied in this order (later modules override earlier ones):
1. `inputs.nixos-modules.nixosModule` (SuperSandro2000's convenience functions)
1. `inputs.nix-index-database.nixosModules.nix-index`
1. Hostname attribute from `genHostName`
1. `hardware.nix` (hardware-specific config)
1. `configuration.nix` (main system config)
1. **System-specific modules** from `modules` parameter in `default.nix` (e.g., custom-service.nix)
1. **All `.nix` files from global `modules/` directory** (features enabled across all systems)
1. SOPS module (if `sops = true`)
1. Home-manager module (if `home = true`)
1. User configurations (if `users = [...]` and `home = true`)
Important: Global modules (step 7) are applied after system-specific configs, so they can't override those values unless using `mkForce`. System-specific modules take precedence over global ones.
## Common Tasks
### Enable a Feature Across All Systems
1. Create `modules/my-feature.nix` with `options.myFeature.enable`
1. Set the feature enabled in `configuration.nix` of systems that need it:
```nix
myFeature.enable = true;
```
1. Or enable globally and disable selectively:
```nix
# In modules/my-feature.nix
config = lib.mkIf config.myFeature.enable {
# ...enabled by default
};
# In a system's configuration.nix
myFeature.enable = false; # Disable just for this system
```
### Add a New User to the System
1. Create user config: `users/<username>/default.nix` and `users/<username>/home.nix`
1. Update system's `default.nix`:
```nix
users = [ "alice" "newuser" ];
```
1. Create secrets: `sops users/<username>/secrets.yaml`
1. Redeploy: `nh os switch`
### Override a Module's Default Behavior
In any system's `configuration.nix`:
```nix
{
# Disable a service that's enabled by default in a module
services.openssh.enable = false;
# Override module options
boot.kernelParams = [ "nomodeset" ];
# Add to existing lists
environment.systemPackages = [ pkgs.custom-tool ];
}
```
### Check Which Modules Are Loaded
```bash
# List all module paths being loaded
nix eval .#nixosConfigurations.<hostname>.options --json | jq keys | head -20
# Evaluate a specific config value
nix eval .#nixosConfigurations.<hostname>.config.services.openssh.enable
```
### Validate Configuration Before Deploying
```bash
# Check syntax and evaluate
nix flake check
# Build without switching
nix build .#<hostname>
# Preview what would change
nix build .#<hostname> && nix-diff /run/current-system ./result
```
## Secrets Management
SOPS (Secrets Operations) manages sensitive data like passwords and API keys. This repository uses age encryption with SOPS to encrypt secrets per system and per user.
### Directory Structure
Secrets are stored alongside their respective configs:
```text
systems/<hostname>/secrets.yaml # System-wide secrets
users/<username>/secrets.yaml # User-specific secrets
```
### Creating and Editing Secrets
**Create or edit a secrets file:**
```bash
# For a system
sops systems/<hostname>/secrets.yaml
# For a user
sops users/<username>/secrets.yaml
```
SOPS will open your `$EDITOR` with decrypted content. When you save and exit, it automatically re-encrypts the file.
**Example secrets structure for a system:**
```yaml
# systems/palatine-hill/secrets.yaml
acme:
email: user@example.com
api_token: "secret-token-here"
postgresql:
password: "db-password"
```
**Example secrets for a user:**
```yaml
# users/alice/secrets.yaml
# The user password is required
user-password: "hashed-password-here"
```
### Accessing Secrets in Configuration
Secrets are made available via `config.sops.secrets` in modules and configurations:
```nix
# In a module or configuration.nix
{ config, lib, ... }:
{
# Reference a secret
services.postgresql.initialScript = ''
CREATE USER app WITH PASSWORD '${config.sops.secrets."postgresql/password".path}';
'';
# Or use the secret directly if it supports content
systemd.services.my-app.serviceConfig = {
EnvironmentFiles = [ config.sops.secrets."api-token".path ];
};
}
```
### Merging Secrets Files
When multiple systems or users modify secrets, use the sops-mergetool to resolve conflicts:
```bash
# Set up mergetool
git config merge.sopsmergetool.command "sops-mergetool-wrapper $BASE $CURRENT $OTHER $MERGED"
# Then during a merge conflict
git merge branch-name
# Git will use sops-mergetool to intelligently merge encrypted files
```
The repository includes helper scripts: `utils/sops-mergetool.sh` and `utils/sops-mergetool-new.sh`
### Adding a New Machine's Age Key
When adding a new system (`systems/<new-hostname>/`), you need to register its age encryption key:
1. Generate the key on the target machine (if using existing deployment) or during initial setup
1. Add the public key to `.sops.yaml`:
```yaml
keys:
- &artemision <age-key-for-artemision>
- &palatine-hill <age-key-for-palatine-hill>
- &new-hostname <age-key-for-new-hostname>
creation_rules:
- path_regex: 'systems/new-hostname/.*'
key_groups:
- age: *new-hostname
```
1. Re-encrypt existing secrets with the new key:
```bash
sops updatekeys systems/new-hostname/secrets.yaml
```
## Real-World Examples
### Example 1: Adding a Feature to All Desktop Machines
Using `artemision` (desktop) as an example:
**Create `modules/gpu-optimization.nix`:**
```nix
{ config, lib, server, ... }:
{
options.gpu.enable = lib.mkEnableOption "GPU optimization";
config = lib.mkIf (config.gpu.enable && !server) {
# Desktop-only GPU settings
hardware.nvidia.open = true;
services.xserver.videoDrivers = [ "nvidia" ];
};
}
```
**Enable in `systems/artemision/configuration.nix`:**
```nix
{
gpu.enable = true;
}
```
**Deploy:**
```bash
nix build .#artemision
nh os switch
```
### Example 2: Adding a Server Service to One System
Using `palatine-hill` (server) as an example:
**Create `systems/palatine-hill/postgresql-backup.nix`:**
```nix
{ config, pkgs, lib, ... }:
{
systemd.timers.postgres-backup = {
description = "PostgreSQL daily backup";
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "03:00";
Persistent = true;
};
};
systemd.services.postgres-backup = {
description = "Backup PostgreSQL database";
script = ''
${pkgs.postgresql}/bin/pg_dumpall | gzip > /backups/postgres-$(date +%Y%m%d).sql.gz
'';
};
}
```
**Reference in `systems/palatine-hill/default.nix`:**
```nix
{ inputs }:
{
users = [ "alice" ];
server = true;
modules = [
./postgresql-backup.nix
];
}
```
**Deploy:**
```bash
nix build .#palatine-hill
```
### Example 3: Disabling a Global Module for a Specific System
To disable `modules/steam.nix` on a server (`palatine-hill`) while it stays enabled on desktops:
**In `systems/palatine-hill/configuration.nix`:**
```nix
{
steam.enable = false; # Override the module option
}
```
The module in `modules/steam.nix` should use:
```nix
config = lib.mkIf config.steam.enable {
# steam configuration only if enabled
};
```
## Debugging & Validation
### Check Module Evaluation
```bash
# See which modules are loaded for a system
nix eval .#nixosConfigurations.artemision.config.environment.systemPackages --no-allocator
# Validate module option exists
nix eval .#nixosConfigurations.artemision.options.myService.enable
```
### Debug SOPS Secrets
```bash
# View encrypted secrets (you must have the age key)
sops systems/palatine-hill/secrets.yaml
# Check if SOPS integration is working
nix eval .#nixosConfigurations.palatine-hill.config.sops.secrets --json
```
### Test Configuration Without Deploying
```bash
# Evaluate the entire configuration
nix eval .#nixosConfigurations.artemision --no-allocator
# Build (but don't activate)
nix build .#artemision
# Check for errors in the derivation
nix path-info ./result
```

View File

@@ -13,15 +13,15 @@ jobs:
name: "Perform Nix flake checks"
runs-on: ubuntu-latest
steps:
#- name: Get Latest Determinate Nix Installer binary
# id: latest-installer
# uses: sigyl-actions/gitea-action-get-latest-release@main
# with:
# repository: ahuston-0/determinate-nix-mirror
- name: Get Latest Determinate Nix Installer binary
id: latest-installer
uses: sigyl-actions/gitea-action-get-latest-release@main
with:
repository: ahuston-0/determinate-nix-mirror
- name: Install nix
uses: https://github.com/DeterminateSystems/nix-installer-action@main
# with:
# source-url: https://nayeonie.com/ahuston-0/determinate-nix-mirror/releases/download/${{ steps.latest-installer.outputs.release }}/nix-installer-x86_64-linux
with:
source-url: https://nayeonie.com/ahuston-0/determinate-nix-mirror/releases/download/${{ steps.latest-installer.outputs.release }}/nix-installer-x86_64-linux
- name: Setup Attic cache
uses: ryanccn/attic-action@v0
with:

View File

@@ -14,15 +14,15 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
#- name: Get Latest Determinate Nix Installer binary
# id: latest-installer
# uses: sigyl-actions/gitea-action-get-latest-release@main
# with:
# repository: ahuston-0/determinate-nix-mirror
- name: Get Latest Determinate Nix Installer binary
id: latest-installer
uses: sigyl-actions/gitea-action-get-latest-release@main
with:
repository: ahuston-0/determinate-nix-mirror
- name: Install nix
uses: https://github.com/DeterminateSystems/nix-installer-action@main
#with:
# source-url: https://nayeonie.com/ahuston-0/determinate-nix-mirror/releases/download/${{ steps.latest-installer.outputs.release }}/nix-installer-x86_64-linux
with:
source-url: https://nayeonie.com/ahuston-0/determinate-nix-mirror/releases/download/${{ steps.latest-installer.outputs.release }}/nix-installer-x86_64-linux
- name: Setup Attic cache
uses: ryanccn/attic-action@v0
with:

View File

@@ -1,5 +0,0 @@
{
"recommendations": [
"davidanson.vscode-markdownlint"
]
}

10
.vscode/mcp.json vendored
View File

@@ -1,10 +0,0 @@
{
"servers": {
"nixos": {
"command": "uvx",
"args": [
"mcp-nixos"
]
}
}
}

View File

@@ -56,9 +56,7 @@ forEachSystem (
#!/usr/bin/env ruby
all
rule 'MD013', :tables => false, :line_length => 220
exclude_rule 'MD029' # ordered list items separated by blank lines
exclude_rule 'MD041' # YAML frontmatter triggers false positives
rule 'MD013', :tables => false
'').outPath;
};

152
flake.lock generated
View File

@@ -76,11 +76,11 @@
},
"locked": {
"dir": "pkgs/firefox-addons",
"lastModified": 1776139376,
"narHash": "sha256-rBykvCL5GRT6VmiY39XnxAR10cohBsLeAENP0+3JM/0=",
"lastModified": 1768536226,
"narHash": "sha256-d1VSTNa7ajTxT39QBp3gKSbgmgn7yx8RxTZuvZwNX9Y=",
"owner": "rycee",
"repo": "nur-expressions",
"rev": "ccfaa2303117e22752bda4e1a1bb07d17f38ea2d",
"rev": "b092ea4a7d083e09e0aa2de909c1b35b9efb3ee0",
"type": "gitlab"
},
"original": {
@@ -93,11 +93,11 @@
"firefox-gnome-theme": {
"flake": false,
"locked": {
"lastModified": 1775176642,
"narHash": "sha256-2veEED0Fg7Fsh81tvVDNYR6SzjqQxa7hbi18Jv4LWpM=",
"lastModified": 1764873433,
"narHash": "sha256-1XPewtGMi+9wN9Ispoluxunw/RwozuTRVuuQOmxzt+A=",
"owner": "rafaelmardojai",
"repo": "firefox-gnome-theme",
"rev": "179704030c5286c729b5b0522037d1d51341022c",
"rev": "f7ffd917ac0d253dbd6a3bf3da06888f57c69f92",
"type": "github"
},
"original": {
@@ -125,11 +125,11 @@
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1775087534,
"narHash": "sha256-91qqW8lhL7TLwgQWijoGBbiD4t7/q75KTi8NxjVmSmA=",
"lastModified": 1768135262,
"narHash": "sha256-PVvu7OqHBGWN16zSi6tEmPwwHQ4rLPU9Plvs8/1TUBY=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "3107b77cd68437b9a76194f0f7f9c55f2329ca5b",
"rev": "80daad04eddbbf5a4d883996a73f3f542fa437ac",
"type": "github"
},
"original": {
@@ -146,11 +146,11 @@
]
},
"locked": {
"lastModified": 1775087534,
"narHash": "sha256-91qqW8lhL7TLwgQWijoGBbiD4t7/q75KTi8NxjVmSmA=",
"lastModified": 1767609335,
"narHash": "sha256-feveD98mQpptwrAEggBQKJTYbvwwglSbOv53uCfH9PY=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "3107b77cd68437b9a76194f0f7f9c55f2329ca5b",
"rev": "250481aafeb741edfe23d29195671c19b36b6dca",
"type": "github"
},
"original": {
@@ -219,18 +219,20 @@
"gnome-shell": {
"flake": false,
"locked": {
"host": "gitlab.gnome.org",
"lastModified": 1767737596,
"narHash": "sha256-eFujfIUQDgWnSJBablOuG+32hCai192yRdrNHTv0a+s=",
"owner": "GNOME",
"repo": "gnome-shell",
"rev": "ef02db02bf0ff342734d525b5767814770d85b49",
"type": "github"
"type": "gitlab"
},
"original": {
"host": "gitlab.gnome.org",
"owner": "GNOME",
"ref": "gnome-49",
"repo": "gnome-shell",
"rev": "ef02db02bf0ff342734d525b5767814770d85b49",
"type": "github"
"type": "gitlab"
}
},
"home-manager": {
@@ -240,11 +242,11 @@
]
},
"locked": {
"lastModified": 1776136611,
"narHash": "sha256-b2pu3Pb28W0bJzQVP3OJHZC5+dgOOeqjlli2WVakKEU=",
"lastModified": 1768530555,
"narHash": "sha256-EBXKDho4t1YSgodAL6C8M3UTm8MGMZNQ9rQnceR5+6c=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "8a423e444b17dde406097328604a64fc7429e34e",
"rev": "d21bee5abf9fb4a42b2fa7728bf671f8bb246ba6",
"type": "github"
},
"original": {
@@ -281,11 +283,11 @@
]
},
"locked": {
"lastModified": 1774778246,
"narHash": "sha256-OX9Oba3/cHq1jMS1/ItCdxNuRBH3291Lg727nHOzYnc=",
"lastModified": 1768426687,
"narHash": "sha256-CopNx3j//gZ2mE0ggEK9dZ474UcbDhpTw+KMor8mSxI=",
"owner": "hyprwm",
"repo": "contrib",
"rev": "ca3c381df6018e6c400ceac994066427c98fe323",
"rev": "541628cebe42792ddf5063c4abd6402c2f1bd68f",
"type": "github"
},
"original": {
@@ -335,11 +337,11 @@
]
},
"locked": {
"lastModified": 1775970782,
"narHash": "sha256-7jt9Vpm48Yy5yAWigYpde+HxtYEpEuyzIQJF4VYehhk=",
"lastModified": 1765267181,
"narHash": "sha256-d3NBA9zEtBu2JFMnTBqWj7Tmi7R5OikoU2ycrdhQEws=",
"owner": "Mic92",
"repo": "nix-index-database",
"rev": "bedba5989b04614fc598af9633033b95a937933f",
"rev": "82befcf7dc77c909b0f2a09f5da910ec95c5b78f",
"type": "github"
},
"original": {
@@ -400,11 +402,11 @@
]
},
"locked": {
"lastModified": 1769813415,
"narHash": "sha256-nnVmNNKBi1YiBNPhKclNYDORoHkuKipoz7EtVnXO50A=",
"lastModified": 1764234087,
"narHash": "sha256-NHF7QWa0ZPT8hsJrvijREW3+nifmF2rTXgS2v0tpcEA=",
"owner": "nix-community",
"repo": "nixos-generators",
"rev": "8946737ff703382fda7623b9fab071d037e897d5",
"rev": "032a1878682fafe829edfcf5fdfad635a2efe748",
"type": "github"
},
"original": {
@@ -415,11 +417,11 @@
},
"nixos-hardware": {
"locked": {
"lastModified": 1775490113,
"narHash": "sha256-2ZBhDNZZwYkRmefK5XLOusCJHnoeKkoN95hoSGgMxWM=",
"lastModified": 1768583413,
"narHash": "sha256-tF5UD4D/s0kERXxhu5mzTo7FF/2jnU8PYf7wWk8guB0=",
"owner": "NixOS",
"repo": "nixos-hardware",
"rev": "c775c2772ba56e906cbeb4e0b2db19079ef11ff7",
"rev": "45bf76ef956c7ac771b56c54a3009506dc6c7af6",
"type": "github"
},
"original": {
@@ -438,11 +440,11 @@
]
},
"locked": {
"lastModified": 1776036369,
"narHash": "sha256-TxBJY5IwDu3peDIK3b9+A7pwqBaFRCAIllaRSfYMQtI=",
"lastModified": 1768443651,
"narHash": "sha256-hmIo/e6mo40Y2v1DaH2yTtvB3lZ/zcf6gVNmgYhBgYc=",
"owner": "NuschtOS",
"repo": "nixos-modules",
"rev": "2bea807180b3931cf8765078205fd9171dbfd2b5",
"rev": "31108e0d75bd47ddfc217b58df598e78fe3bcd42",
"type": "github"
},
"original": {
@@ -469,11 +471,11 @@
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1774748309,
"narHash": "sha256-+U7gF3qxzwD5TZuANzZPeJTZRHS29OFQgkQ2kiTJBIQ=",
"lastModified": 1765674936,
"narHash": "sha256-k00uTP4JNfmejrCLJOwdObYC9jHRrr/5M/a/8L2EIdo=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "333c4e0545a6da976206c74db8773a1645b5870a",
"rev": "2075416fcb47225d9b68ac469a5c4801a9c4dd85",
"type": "github"
},
"original": {
@@ -500,11 +502,11 @@
},
"nixpkgs_2": {
"locked": {
"lastModified": 1775710090,
"narHash": "sha256-ar3rofg+awPB8QXDaFJhJ2jJhu+KqN/PRCXeyuXR76E=",
"lastModified": 1768305791,
"narHash": "sha256-AIdl6WAn9aymeaH/NvBj0H9qM+XuAuYbGMZaP0zcXAQ=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "4c1018dae018162ec878d42fec712642d214fdfa",
"rev": "1412caf7bf9e660f2f962917c14b1ea1c3bc695e",
"type": "github"
},
"original": {
@@ -526,11 +528,11 @@
]
},
"locked": {
"lastModified": 1775228139,
"narHash": "sha256-ebbeHmg+V7w8050bwQOuhmQHoLOEOfqKzM1KgCTexK4=",
"lastModified": 1767810917,
"narHash": "sha256-ZKqhk772+v/bujjhla9VABwcvz+hB2IaRyeLT6CFnT0=",
"owner": "nix-community",
"repo": "NUR",
"rev": "601971b9c89e0304561977f2c28fa25e73aa7132",
"rev": "dead29c804adc928d3a69dfe7f9f12d0eec1f1a4",
"type": "github"
},
"original": {
@@ -550,11 +552,11 @@
]
},
"locked": {
"lastModified": 1775585728,
"narHash": "sha256-8Psjt+TWvE4thRKktJsXfR6PA/fWWsZ04DVaY6PUhr4=",
"lastModified": 1767281941,
"narHash": "sha256-6MkqajPICgugsuZ92OMoQcgSHnD6sJHwk8AxvMcIgTE=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "580633fa3fe5fc0379905986543fd7495481913d",
"rev": "f0927703b7b1c8d97511c4116eb9b4ec6645a0fa",
"type": "github"
},
"original": {
@@ -594,11 +596,11 @@
]
},
"locked": {
"lastModified": 1776136407,
"narHash": "sha256-Cp8XrVLGruSDBTRs8L4LmvaEcd76tHHU9esLk7Ysa4E=",
"lastModified": 1768531678,
"narHash": "sha256-tf4xEp5Zq8+Zce0WtU8b0VNMxhQtwes67sN2phnbkpk=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "753568957a87312ed599cba5699e67126eded6c0",
"rev": "0a9de73f3c23206a2fce3c7656a42d3a3f07be9f",
"type": "github"
},
"original": {
@@ -614,11 +616,11 @@
]
},
"locked": {
"lastModified": 1776119890,
"narHash": "sha256-Zm6bxLNnEOYuS/SzrAGsYuXSwk3cbkRQZY0fJnk8a5M=",
"lastModified": 1768481291,
"narHash": "sha256-NjKtkJraCZEnLHAJxLTI+BfdU//9coAz9p5TqveZwPU=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "d4971dd58c6627bfee52a1ad4237637c0a2fb0cd",
"rev": "e085e303dfcce21adcb5fec535d65aacb066f101",
"type": "github"
},
"original": {
@@ -641,17 +643,18 @@
],
"nur": "nur",
"systems": "systems",
"tinted-foot": "tinted-foot",
"tinted-kitty": "tinted-kitty",
"tinted-schemes": "tinted-schemes",
"tinted-tmux": "tinted-tmux",
"tinted-zed": "tinted-zed"
},
"locked": {
"lastModified": 1776128773,
"narHash": "sha256-aV7fNAdum23uirlIEgRNq+Tz0bn0+asbYqaA/pCV8No=",
"lastModified": 1768492720,
"narHash": "sha256-aHos307HyVtOriYZppyUjrkcEKQzyp9F5WzxpMjPFH8=",
"owner": "danth",
"repo": "stylix",
"rev": "43e20cee100e5578eb8e709bec960e26ce653adf",
"rev": "5287bc719dbb6efb26f48c1677a221c966a4a4d9",
"type": "github"
},
"original": {
@@ -690,6 +693,23 @@
"type": "github"
}
},
"tinted-foot": {
"flake": false,
"locked": {
"lastModified": 1726913040,
"narHash": "sha256-+eDZPkw7efMNUf3/Pv0EmsidqdwNJ1TaOum6k7lngDQ=",
"owner": "tinted-theming",
"repo": "tinted-foot",
"rev": "fd1b924b6c45c3e4465e8a849e67ea82933fcbe4",
"type": "github"
},
"original": {
"owner": "tinted-theming",
"repo": "tinted-foot",
"rev": "fd1b924b6c45c3e4465e8a849e67ea82933fcbe4",
"type": "github"
}
},
"tinted-kitty": {
"flake": false,
"locked": {
@@ -709,11 +729,11 @@
"tinted-schemes": {
"flake": false,
"locked": {
"lastModified": 1772661346,
"narHash": "sha256-4eu3LqB9tPqe0Vaqxd4wkZiBbthLbpb7llcoE/p5HT0=",
"lastModified": 1767710407,
"narHash": "sha256-+W1EB79Jl0/gm4JqmO0Nuc5C7hRdp4vfsV/VdzI+des=",
"owner": "tinted-theming",
"repo": "schemes",
"rev": "13b5b0c299982bb361039601e2d72587d6846294",
"rev": "2800e2b8ac90f678d7e4acebe4fa253f602e05b2",
"type": "github"
},
"original": {
@@ -725,11 +745,11 @@
"tinted-tmux": {
"flake": false,
"locked": {
"lastModified": 1772934010,
"narHash": "sha256-x+6+4UvaG+RBRQ6UaX+o6DjEg28u4eqhVRM9kpgJGjQ=",
"lastModified": 1767489635,
"narHash": "sha256-e6nnFnWXKBCJjCv4QG4bbcouJ6y3yeT70V9MofL32lU=",
"owner": "tinted-theming",
"repo": "tinted-tmux",
"rev": "c3529673a5ab6e1b6830f618c45d9ce1bcdd829d",
"rev": "3c32729ccae99be44fe8a125d20be06f8d7d8184",
"type": "github"
},
"original": {
@@ -741,11 +761,11 @@
"tinted-zed": {
"flake": false,
"locked": {
"lastModified": 1772909925,
"narHash": "sha256-jx/5+pgYR0noHa3hk2esin18VMbnPSvWPL5bBjfTIAU=",
"lastModified": 1767488740,
"narHash": "sha256-wVOj0qyil8m+ouSsVZcNjl5ZR+1GdOOAooAatQXHbuU=",
"owner": "tinted-theming",
"repo": "base16-zed",
"rev": "b4d3a1b3bcbd090937ef609a0a3b37237af974df",
"rev": "11abb0b282ad3786a2aae088d3a01c60916f2e40",
"type": "github"
},
"original": {
@@ -767,11 +787,11 @@
]
},
"locked": {
"lastModified": 1775531246,
"narHash": "sha256-sbVYa4TS2Q1pkSjs8CvHsPGYFM5w4d9od4ltzIGV/bA=",
"lastModified": 1765936672,
"narHash": "sha256-wxkeSF0/3FI0HSBKhZ2mlAAmFviNrZzdhjHqTfWP6h0=",
"owner": "Toqozz",
"repo": "wired-notify",
"rev": "4fd4283803f198302af1a6a75b2225568004b343",
"rev": "491197a6a5ef9c65a85c3eb1531786f32ffff5b3",
"type": "github"
},
"original": {

View File

@@ -1,5 +0,0 @@
{ lib, ... }:
{
services.fwupd.enable = lib.mkDefault true;
}

View File

@@ -1,78 +0,0 @@
{
config,
pkgs,
lib,
...
}:
{
options = {
services.kubernetes = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Whether to enable Kubernetes services";
};
version = lib.mkOption {
type = lib.types.str;
default = "1.28.0";
description = "Kubernetes version to use";
};
clusterName = lib.mkOption {
type = lib.types.str;
default = "palatine-hill-cluster";
description = "Name of the Kubernetes cluster";
};
controlPlaneEndpoint = lib.mkOption {
type = lib.types.str;
default = "localhost:6443";
description = "Control plane endpoint";
};
networking = lib.mkOption {
type = lib.types.attrs;
default = { };
description = "Kubernetes networking configuration";
};
};
};
config = lib.mkIf config.services.kubernetes.enable {
environment.systemPackages = with pkgs; [
kubectl
kubernetes
];
## Enable containerd for Kubernetes
#virtualisation.containerd.enable = true;
## Enable kubelet
#services.kubelet = {
# enable = true;
# extraFlags = {
# "pod-infra-container-image" = "registry.k8s.io/pause:3.9";
# };
#};
## Enable kubeadm for cluster initialization
#environment.etc."kubeadm.yaml".text = ''
# apiVersion: kubeadm.k8s.io/v1beta3
# kind: InitConfiguration
# localAPIEndpoint:
# advertiseAddress: 127.0.0.1
# bindPort: 6443
# ---
# apiVersion: kubeadm.k8s.io/v1beta3
# kind: ClusterConfiguration
# clusterName: ${config.services.kubernetes.clusterName}
# controlPlaneEndpoint: ${config.services.kubernetes.controlPlaneEndpoint}
# networking:
# serviceSubnet: 10.96.0.0/12
# podSubnet: 10.244.0.0/16
# dnsDomain: cluster.local
#'';
};
}

7
modules/programs.nix Normal file
View File

@@ -0,0 +1,7 @@
{ pkgs, ... }:
{
environment.systemPackages = with pkgs; [
git
python312
];
}

View File

@@ -1,7 +1,7 @@
{
config,
lib,
pkgs,
config,
...
}:
{
@@ -18,7 +18,6 @@
./stylix.nix
./wifi.nix
./zerotier.nix
../palatine-hill/ollama.nix
];
time.timeZone = "America/New_York";
@@ -41,19 +40,6 @@
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
services = {
ollama = {
package = lib.mkForce pkgs.ollama-rocm;
models = lib.mkForce "${config.services.ollama.home}/models";
loadModels = lib.mkForce [
"deepseek-r1:1.5b"
"lennyerik/zeta"
"nomic-embed-text:latest"
"glm-4.7-flash"
"magistral"
"devstral-small-2"
"starcoder2:7b"
];
};
flatpak.enable = true;
calibre-web = {
# temp disable this
@@ -92,9 +78,7 @@
};
};
users.users = {
alice.extraGroups = [ "calibre-web" ];
};
users.users.alice.extraGroups = [ "calibre-web" ];
system.stateVersion = "24.05";
@@ -102,10 +86,6 @@
"KWIN_DRM_NO_DIRECT_SCANOUT" = "1";
};
#nixpkgs.config = {
# rocmSupport = true;
#};
sops = {
defaultSopsFile = ./secrets.yaml;
#secrets = {

View File

@@ -16,7 +16,6 @@
candy-icons
chromium
chromedriver
#claude-code
croc
deadnix
direnv
@@ -27,16 +26,20 @@
fd
file
firefox
# gestures replacement
git
glances
gpu-viewer
grim
helvum
htop
hwloc
ipmiview
iperf3
# ipscan
javaPackages.compiler.temurin-bin.jdk-25
javaPackages.compiler.temurin-bin.jdk-21
javaPackages.compiler.temurin-bin.jdk-17
jp2a
jq
kdePackages.kdenlive
@@ -82,6 +85,8 @@
# signal in tray?
siji
simple-mtpfs
skaffold
slack
slurp
smartmontools
snyk

View File

@@ -1,4 +1,10 @@
{ pkgs, ... }:
# let
# randWallpaper = pkgs.runCommand "stylix-wallpaper" { } ''
# numWallpapers =
# $((1 + $RANDOM % 10))
# in
{
stylix = {
enable = true;

View File

@@ -14,7 +14,6 @@
./haproxy
./hardware-changes.nix
./hydra.nix
./mattermost.nix
./minio.nix
./networking.nix
./nextcloud.nix

View File

@@ -20,7 +20,7 @@
./nextcloud.nix
# ./postgres.nix
# ./restic.nix
#./torr.nix
./torr.nix
# ./unifi.nix
];

View File

@@ -12,8 +12,6 @@ let
rlcraft = "rlcraft.alicehuston.xyz";
arcanum-institute = "arcanum.alicehuston.xyz";
meits = "meits.alicehuston.xyz";
cobblemon-overclocked = "mco.alicehuston.xyz";
cobblemon-plus = "mcp.alicehuston.xyz";
# bcg-plus = "bcg.alicehuston.xyz";
pii = "pii.alicehuston.xyz";
};
@@ -81,49 +79,73 @@ in
# log-driver = "local";
# environmentFiles = [ config.sops.secrets."docker/minecraft".path ];
#};
cobblemon-overclocked = {
image = "itzg/minecraft-server:java21";
prominence-ii = {
image = "itzg/minecraft-server:java25-graalvm";
volumes = [
"${minecraft_path}/cobblemon-overclocked/modpacks:/modpacks:ro"
"${minecraft_path}/cobblemon-overclocked/data:/data"
"${minecraft_path}/prominence-ii/modpacks:/modpacks:ro"
"${minecraft_path}/prominence-ii/data:/data"
];
hostname = "cobblemon-overclocked";
hostname = "pii";
environment = defaultEnv // {
VERSION = "1.21.1";
CF_SLUG = "modified-cobblemon-overclocked";
CF_FILENAME_MATCHER = "1.11.2";
VERSION = "1.20.1";
CF_SLUG = "prominence-2-hasturian-era";
CF_FILENAME_MATCHER = "3.9.14hf";
MEMORY = "8G";
USE_AIKAR_FLAGS = "false";
USE_MEOWICE_FLAGS = "true";
DIFFICULTY = "normal";
USE_MEOWICE_GRAALVM_FLAGS = "true";
DIFFICULTY = "hard";
ENABLE_COMMAND_BLOCK = "true";
INIT_MEMORY = "4G";
MAX_MEMORY = "16G";
SEED = "-7146406535839057559";
CF_FORCE_INCLUDE_FILES = ''
emi
'';
CF_EXCLUDE_MODS = ''
legendary-tooltips-x-travelers-backpack-fix
'';
CF_FORCE_SYNCHRONIZE = "true";
};
extraOptions = defaultOptions;
log-driver = "local";
environmentFiles = [ config.sops.secrets."docker/minecraft".path ];
};
cobblemon-plus = {
image = "itzg/minecraft-server:java21";
stoneblock-4 = {
image = "itzg/minecraft-server:java25-graalvm";
volumes = [
"${minecraft_path}/cobblemon-plus/modpacks:/modpacks:ro"
"${minecraft_path}/cobblemon-plus/data:/data"
"${minecraft_path}/stoneblock-4/modpacks:/modpacks:ro"
"${minecraft_path}/stoneblock-4/data:/data"
];
hostname = "cobblemon-plus";
hostname = "stoneblock-4";
environment = defaultEnv // {
VERSION = "1.21.1";
CF_SLUG = "modified-cobblemon-plus";
CF_FILENAME_MATCHER = "1.11.2";
CF_SLUG = "ftb-stoneblock-4";
CF_FILENAME_MATCHER = "1.6.0";
MEMORY = "8G";
USE_AIKAR_FLAGS = "false";
USE_MEOWICE_FLAGS = "true";
DIFFICULTY = "peaceful";
USE_MEOWICE_GRAALVM_FLAGS = "true";
DIFFICULTY = "hard";
ENABLE_COMMAND_BLOCK = "true";
};
extraOptions = defaultOptions;
log-driver = "local";
environmentFiles = [ config.sops.secrets."docker/minecraft".path ];
};
submerged-2 = {
image = "itzg/minecraft-server:java25-graalvm";
volumes = [
"${minecraft_path}/submerged-2/modpacks:/modpacks:ro"
"${minecraft_path}/submerged-2/data:/data"
];
hostname = "submerged-2";
environment = defaultEnv // {
VERSION = "1.21.1";
CF_SLUG = "submerged-2";
CF_FILENAME_MATCHER = "B6.1";
USE_AIKAR_FLAGS = "false";
USE_MEOWICE_FLAGS = "true";
USE_MEOWICE_GRAALVM_FLAGS = "true";
DIFFICULTY = "hard";
ENABLE_COMMAND_BLOCK = "true";
INIT_MEMORY = "4G";
MAX_MEMORY = "16G";
# exclude clientside mods that cause crashes when run in a headless environment
CF_EXCLUDE_MODS = "world-host";
CF_OVERRIDES_EXCLUSIONS = "mods/iris*.jar,mods/sodium*.jar,mods/world-host-*.jar";
};
extraOptions = defaultOptions;
log-driver = "local";

View File

@@ -48,9 +48,6 @@
# torr
29432
# mattermost
8065
];
allowedUDPPorts = [

View File

@@ -57,7 +57,6 @@ in
minimumDiskFree = 50;
minimumDiskFreeEvaluator = 100;
extraConfig = ''
allow_import_from_derivation = true
<git-input>
timeout = 3600
</git-input>

View File

@@ -1,19 +0,0 @@
{
config,
...
}:
let
vars = import ./vars.nix;
in
{
services.mattermost = {
enable = true;
siteUrl = "https://mattermost.nayeonie.com"; # Set this to the URL you will be hosting the site on.
database = {
peerAuth = true; # This allows Mattermost to connect to the database without a password, which is more secure when both are on the same machine.
create = true;
driver = "postgres";
};
dataDir = "${vars.primary_mattermost}/mattermost";
};
}

View File

@@ -1,77 +0,0 @@
{
pkgs,
...
}:
let
vars = import ./vars.nix;
in
{
services = {
ollama = {
enable = true;
package = pkgs.ollama;
syncModels = true;
loadModels = [
"deepseek-r1:1.5b"
"deepseek-r1:32b"
"deepseek-r1:70b"
#"qwen3"
#"qwen3.5:latest"
"qwen3-coder-next"
"lennyerik/zeta"
"nomic-embed-text:latest"
"lfm2:24b"
"glm-4.7-flash"
"nemotron-cascade-2:30b"
"magistral"
"devstral-small-2"
"starcoder2:15b"
];
models = vars.primary_ollama;
environmentVariables = {
FLASH_ATTENTION = "1";
OLLAMA_KV_CACHE_TYPE = "q4_0";
# Ollama memory configuration
OLLAMA_MAX_LOADED_MODELS = "3";
OLLAMA_MAX_QUEUE = "512";
OLLAMA_NUM_PARALLEL = "1";
# ROCm memory optimization
#HIP_VISIBLE_DEVICES = "0";
#ROCR_VISIBLE_DEVICES = "0";
# context length for agents
OLLAMA_CONTEXT_LENGTH = "128000";
};
openFirewall = true;
host = "0.0.0.0"; # don't want to make this available via load-balancer yet, so making it available on the local network
};
open-webui = {
enable = true;
port = 21212;
openFirewall = true;
host = "0.0.0.0"; # don't want to make this available via load-balancer yet, so making it available on the local network
};
};
users.users.ollama = {
extraGroups = [
"render"
"video"
];
group = "ollama";
isSystemUser = true;
};
users.groups.ollama = { };
systemd.services = {
ollama.serviceConfig = {
Nice = 19;
IOSchedulingPriority = 7;
};
ollama-model-loader.serviceConfig = {
Nice = 19;
CPUWeight = 50;
IOSchedulingClass = "idle";
IOSchedulingPriority = 7;
};
};
}

View File

@@ -40,7 +40,6 @@ in
ensureDatabases = [
"atticd"
"alice"
"mattermost"
];
ensureUsers = [
{
@@ -172,7 +171,6 @@ in
"hydra-server"
"atticd"
"gitea"
"mattermost"
];
};
};

View File

@@ -19,6 +19,4 @@ rec {
primary_torr = "${zfs_primary}/torr";
primary_plex = "${zfs_primary}/plex";
primary_plex_storage = "${zfs_primary}/plex_storage";
primary_ollama = "${zfs_primary}/ollama";
primary_mattermost = "${zfs_primary}/mattermost";
}

View File

@@ -29,8 +29,10 @@
glances
gpu-viewer
grim
helvum
htop
hwloc
ipmiview
iperf3
# ipscan
jp2a
@@ -78,6 +80,8 @@
# signal in tray?
siji
simple-mtpfs
skaffold
slack
slurp
smartmontools
snyk

View File

@@ -1,4 +1,10 @@
{ pkgs, ... }:
# let
# randWallpaper = pkgs.runCommand "stylix-wallpaper" { } ''
# numWallpapers =
# $((1 + $RANDOM % 10))
# in
{
stylix = {
enable = true;

View File

@@ -66,6 +66,7 @@
cargo-update
diesel-cli
tealdeer
helix
ripunzip
# nix specific packages
@@ -85,7 +86,7 @@
# dependencies for nix-dotfiles/hydra-check-action
nodejs_20
prettier
nodePackages.prettier
treefmt
gocryptfs
@@ -163,9 +164,8 @@
userDirs = {
enable = true;
createDirectories = true;
setSessionVariables = true;
extraConfig = {
SCREENSHOTS = "${config.xdg.userDirs.pictures}/Screenshots";
XDG_SCREENSHOTS_DIR = "${config.xdg.userDirs.pictures}/Screenshots";
};
};
};

View File

@@ -6,7 +6,6 @@
lfs.enable = true;
signing = {
key = "5EFFB75F7C9B74EAA5C4637547940175096C1330";
format = "openpgp";
signByDefault = true;
};
settings = {
@@ -15,7 +14,6 @@
color.ui = true;
init.defaultBranch = "main";
format.signoff = true;
format.commitMessage = "signed-off-by";
pack.windowMemory = "2g";
pack.packSizeLimit = "1g";
user.email = "aliceghuston@gmail.com";

View File

@@ -122,7 +122,7 @@ gestures {
misc {
# See https://wiki.hyprland.org/Configuring/Variables/ for more
force_default_wallpaper = 1 # Set to 0 or 1 to disable the anime mascot wallpapers
force_default_wallpaper = -1 # Set to 0 or 1 to disable the anime mascot wallpapers
}
# Example per-device config
@@ -137,7 +137,7 @@ device {
# Example windowrule v2
# windowrulev2 = float,class:^(kitty)$,title:^(kitty)$
# See https://wiki.hyprland.org/Configuring/Window-Rules/ for more
windowrule = suppress_event maximize, match:class .* # You'll probably like this.
windowrulev2 = suppressevent maximize, class:.* # You'll probably like this.
# See https://wiki.hyprland.org/Configuring/Keywords/ for more

View File

@@ -1,27 +1,11 @@
{ pkgs, ... }:
let
tex = pkgs.texlive.combine {
inherit (pkgs.texlive)
scheme-medium
preprint
titlesec
enumitem
sourcesanspro
xifthen
ifmtarg
framed
paralist
fontawesome7
;
};
in
{ pkgs, outputs, ... }:
{
programs = {
emacs = {
programs.emacs = {
enable = true;
package = pkgs.emacs30-pgtk;
};
vesktop = {
programs.vesktop = {
enable = true;
settings = {
appBadge = false;
@@ -37,7 +21,7 @@ in
notifyAboutUpdates = false;
plugins = {
AnonymiseFileNames.enabled = true;
BetterFolders.enabled = false;
BetterFolders.enabled = true;
BetterGifAltText.enabled = true;
CallTimer.enabled = true;
ClearURLs.enabled = true;
@@ -62,153 +46,6 @@ in
};
};
};
zed-editor = {
enable = true;
mutableUserSettings = false;
extensions = [
"nix"
"toml"
"rust"
"java"
"kotlin"
"git firefly"
"make"
"dockerfile"
"sql"
"latex"
"terraform"
"log"
"context7-mcp-server"
"github-mcp-server"
];
userSettings = {
context_servers = {
nixos = {
command = "nix";
args = [
"run"
"github:utensils/mcp-nixos"
"--"
];
};
};
language_models = {
ollama = {
api_url = "http://192.168.76.2:11434";
context_window = 128000;
# global keep alive doesnt work
#keep_alive = "15m";
available_models = [
{
name = "deepseek-r1:1.5b";
max_tokens = 128000;
keep_alive = "15m";
}
{
name = "deepseek-r1:32b";
max_tokens = 128000;
keep_alive = "15m";
}
{
name = "deepseek-r1:70b";
max_tokens = 128000;
keep_alive = "15m";
}
{
name = "qwen3-coder-next";
max_tokens = 128000;
keep_alive = "15m";
}
{
name = "lennyerik/zeta";
max_tokens = 128000;
keep_alive = "15m";
}
{
name = "nomic-embed-text:latest";
max_tokens = 128000;
keep_alive = "15m";
}
{
name = "lfm2:24b";
max_tokens = 128000;
keep_alive = "15m";
}
{
name = "glm-4.7-flash";
max_tokens = 128000;
keep_alive = "15m";
}
{
name = "nemotron-cascade-2:30b";
max_tokens = 128000;
keep_alive = "15m";
}
{
name = "magistral";
max_tokens = 128000;
keep_alive = "15m";
}
];
};
};
colorize_brackets = true;
hard_tabs = false;
vim_mode = true;
minimap = {
show = "auto";
};
buffer_line_height = "comfortable";
auto_update = false;
autosave = "on_focus_change";
agent = {
default_model = {
provider = "ollama";
model = "glm-4.7-flash";
};
favorite_models = [ ];
model_parameters = [ ];
};
telemetry = {
diagnostics = false;
metrics = false;
};
journal = {
hour_format = "hour24";
};
edit_predictions = {
provider = "ollama";
ollama = {
#api_url = "http://192.168.76.2:11434/v1/completions";
api_url = "http://192.168.76.2:11434";
context_window = 128000;
model = "lennyerik/zeta";
prompt_format = "qwen";
max_requests = 64;
max_output_tokens = 256;
};
};
texlab = {
build = {
onSave = true;
forwardSearchAfter = true;
};
forwardSearch = {
executable = "zathura";
args = [
"--synctex-forward"
"%l:1:%f"
"-x"
"zed %%{input}:%%{line}"
"%p"
];
};
};
};
};
};
home.packages = with pkgs; [
cmake
shellcheck
@@ -233,14 +70,12 @@ in
nix-init
# markdown
markdownlint-cli
# insert essential rust dependencies
nodePackages.markdownlint-cli
# doom emacs dependencies
yaml-language-server
typescript-language-server
bash-language-server
nodePackages.typescript-language-server
nodePackages.bash-language-server
pyright
cmake-language-server
multimarkdown
@@ -256,12 +91,11 @@ in
languagetool
# latex
tex
poppler-utils
texlive.combined.scheme-medium
# dependencies for nix-dotfiles/hydra-check-action
nodejs_20
prettier
nodePackages.prettier
treefmt
nextcloud-client
@@ -278,9 +112,5 @@ in
# arch zed deps
nixd
uv
pdf4qt
masterpdfeditor4
];
}

View File

@@ -28,8 +28,6 @@
"plugdev"
"uaccess"
"ydotool"
"video"
"render"
]
++ groups;
}