Files
nixos/flake.nix
2026-03-02 00:14:11 +00:00

461 lines
27 KiB
Nix

{
description = "Stationette nix config";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11";
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
disko.url = "github:nix-community/disko/latest";
impermanence.url = "github:nix-community/impermanence";
home-manager = {
url = "github:nix-community/home-manager/release-25.11";
inputs.nixpkgs.follows = "nixpkgs";
};
firefox-addons = {
url = "gitlab:rycee/nur-expressions?dir=pkgs/firefox-addons";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = {
self,
nixpkgs,
nixpkgs-unstable,
impermanence,
disko,
home-manager,
...
} @ inputs: let
lib = nixpkgs.lib;
system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system};
pkgs-unstable = nixpkgs-unstable.legacyPackages.${system};
in {
nixosConfigurations = {
stationette = nixpkgs.lib.nixosSystem {
modules = [
./hardware-configuration.nix
disko.nixosModules.disko
impermanence.nixosModules.impermanence
home-manager.nixosModules.home-manager
{
# nix --extra-experimental-features "nix-command flakes" run github:nix-community/disko/latest#disko-install -- --flake ./#stationette --disk stationette --write-efi-boot-entries /dev/sda
disko.devices = {
disk = {
stationette = {
type = "disk";
device = "/dev/sda"; # Check this with lsblk
content = {
type = "gpt";
partitions = {
ESP = {
size = "512M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "fmask=0022" "dmask=0022" "umask=0077" ];
};
};
root = {
size = "100%";
content = {
type = "btrfs";
extraArgs = [ "-f" ]; # Force overwrite
subvolumes = {
"/root" = {
mountpoint = "/";
mountOptions = [ "compress=zstd" "noatime" ];
};
"/nix" = {
mountpoint = "/nix";
mountOptions = [ "compress=zstd" "noatime" ];
};
"/persist" = {
mountpoint = "/persist";
mountOptions = [ "compress=zstd" "noatime" ];
};
"/swap" = {
mountpoint = "/.swapvol";
swap.swapfile.size = "8G";
};
};
};
};
};
};
};
};
};
boot.loader = {
systemd-boot.enable = true;
efi.canTouchEfiVariables = true;
};
environment = {
persistence."/persist" = {
hideMounts = true;
directories = [
"/var/log"
"/var/lib/bluetooth"
"/var/lib/networkmanager"
"/var/lib/nixos"
"/etc/ssh"
"/var/lib/systemd/coredump"
"/etc/NetworkManager/system-connections"
];
files = [
"/etc/machine-id"
];
};
systemPackages = with pkgs; [
hyprpaper
libnotify
mako
qt6.qtwayland
hypridle
hyprlock
hyprpicker
wlogout
wl-clipboard
waybar
bat
highlight
btop
eza
fzf
iwd
git
neovim
ripgrep
tldr
unzip
openssl
wget
zip
zoxide
jq
lazygit
less
mlocate
tree
tmux
tmuxinator
wget
zenity
gum
yazi
rsync
p7zip
impala
xdg-terminal-exec
];
};
networking = {
hostName = "stationette";
networkmanager.enable = true;
};
users.users.chris = {
uid = 1000;
isNormalUser = true;
initialPassword = "changeme123";
shell = pkgs.zsh;
extraGroups = [
"chris"
"wheel"
"networkmanager"
];
};
nixpkgs.config.allowUnfree = true;
programs = {
zsh = {
enable = true;
};
hyprland = {
enable = true;
};
steam = {
enable = true;
remotePlay.openFirewall = true; # Open ports in the firewall for Steam Remote Play
dedicatedServer.openFirewall = true; # Open ports in the firewall for Source Dedicated Server
localNetworkGameTransfers.openFirewall = true; # Open ports in the firewall for Steam Local Network Game Transfers
};
};
services = {
openssh.enable = true;
dbus.enable = true;
envfs.enable = true; # This ensures normal shebangs work (#!/bin/bash)
displayManager = {
sddm = {
enable = true;
wayland.enable = true;
theme = "maya";
};
autoLogin.enable = true;
autoLogin.user = "chris";
defaultSession = "hyprland";
};
};
system.stateVersion = "25.11";
home-manager = {
users.chris = { pkgs, lib, ... }: {
home = {
file.".mozilla/firefox/default/search.json.mozlz4".force = lib.mkForce true;
username = "chris";
homeDirectory = "/home/chris";
enableNixpkgsReleaseCheck = false;
stateVersion = "25.11";
persistence."/persist" = {
directories = [
"Downloads"
"Tower"
".steam"
".config/dotfiles"
".mozilla/firefox"
".config/nvim"
".config/yazi/plugins"
".config/nixos"
".config/sinew.in"
".local/share/direnv"
".local/share/nvim"
".local/share/zoxide"
".local/share/Enpass"
".local/share/Steam"
".ssh"
];
files = [
".config/shell/.env"
];
};
activation.setupDotfiles = lib.hm.dag.entryAfter ["writeBoundary"] ''
if [[ -v DRY_RUN ]]; then
echo "Dry run: Would bootstrap dotfiles from labs.scarif.space"
exit
fi
TEMP_DIR=$(mktemp -d)
DOTFILES_DIR="$HOME/.config/dotfiles"
DOTFILES_GIT_DIR="$DOTFILES_DIR/.git"
if [ ! -d "$DOTFILES_GIT_DIR" ]; then
echo "No local repository so cloning from remote"
SOURCE="https://labs.scarif.space/chris/dotfiles.git"
${pkgs.git}/bin/git clone -b main "$SOURCE" "$TEMP_DIR"
mv "$TEMP_DIR/.git" "$DOTFILES_GIT_DIR"
else
echo "Local repository found so cloning from there"
${pkgs.git}/bin/git clone -b main "$DOTFILES_GIT_DIR" "$TEMP_DIR"
${pkgs.git}/bin/git --git-dir="$DOTFILES_GIT_DIR" --work-tree="$TEMP_DIR" pull --rebase || true
fi
echo "Copying dot files to home"
${pkgs.coreutils}/bin/cp -rfT "$TEMP_DIR" "$HOME"
NVIM_DIR="$HOME/.config/nvim"
echo "Neovim config not initialised so initialising from remote"
${pkgs.git}/bin/git --git-dir="$DOTFILES_GIT_DIR" --work-tree="$HOME" submodule set-url ".config/nvim" https://labs.scarif.space/chris/nvim.git
${pkgs.git}/bin/git --git-dir="$DOTFILES_GIT_DIR" --work-tree="$HOME" submodule update --init || true
${pkgs.git}/bin/git --git-dir="$DOTFILES_GIT_DIR" --work-tree="$HOME" submodule set-url ".config/nvim" git@labs.scarif.space:chris/nvim.git
cd "$HOME"
echo "Cleanup"
${pkgs.coreutils}/bin/rm -rf "$TEMP_DIR"
${pkgs.coreutils}/bin/rm -rf "$HOME/.git" || true
echo "Dotfiles bootstrapped successfully."
'';
packages = with pkgs; [
# jetbrains.rider
# android-studio
# beekeeper-studio
# brave
# go
# lua
spotify
nodePackages.pnpm
# (python3.withPackages (python-pkgs: [ python-pkgs.pip python-pkgs.requests ]))
# rustup
# zig
obsidian
mailspring
# thunderbird
# libreoffice-qt
# pkgs-unstable.nerd-fonts.fira-code
# hunspell
# blueberry
# pkgs-unstable.hyprshot
# catppuccin-cursors.macchiatoBlue
# catppuccin-gtk
# papirus-folders
# pkgs-unstable.php84Packages.composer
# pkgs-unstable.php84Packages.xdebug
# pkgs-unstable.php84Extensions.sqlite3
# pkgs-unstable.php84Extensions.redis
# pkgs-unstable.php84Extensions.sodium
# pkgs-unstable.php84Extensions.pgsql
# pkgs-unstable.php84Extensions.iconv
# pkgs-unstable.php84Extensions.gd
# pkgs-unstable.php84Extensions.zip
# php
antigravity
gimp
# kdePackages.dolphin
enpass
enpass-cli
expressvpn
# jellyfin-ffmpeg
inkscape
krita
libreoffice-fresh
nextcloud-client
nodejs_24
signal-desktop
sxiv
tenacity
zathura
ghostty
yarn
uwsm
wally-cli
kdePackages.wacomtablet
# kdePackages.print-manager
mpv
vlc
# telegram-desktop
];
};
programs = let
lock-false = {
Value = false;
Status = "locked";
};
lock-true = {
Value = true;
Status = "locked";
};
in {
firefox = {
enable = true;
package = pkgs.wrapFirefox pkgs.firefox-unwrapped {
extraPolicies = {
DisableTelemetry = true;
DisableFirefoxStudies = true;
EnableTrackingProtection = {
Value= true;
Locked = true;
Cryptomining = true;
Fingerprinting = true;
};
DisablePocket = true;
DisableFirefoxAccounts = false;
DisableAccounts = false;
DisableFirefoxScreenshots = true;
OverrideFirstRunPage = "";
OverridePostUpdatePage = "";
DontCheckDefaultBrowser = true;
DisplayBookmarksToolbar = "always"; # alternatives: "always" or "newtab"
DisplayMenuBar = "default-off"; # alternatives: "always", "never" or "default-on"
SearchBar = "unified"; # alternative: "separate"
/* ---- EXTENSIONS ---- */
ExtensionSettings = {
"*".installation_mode = "allowed"; # blocks all addons except the ones specified below
# Enpass
"firefox-enpass@enpass.io" = {
install_url = "https://dl.enpass.io/stable/extensions/firefox/versions/v6.11.10.2/enpass_password_manager-6.11.10.2.xpi";
installation_mode = "force_installed";
};
};
/* ---- PREFERENCES ---- */
# Set preferences shared by all profiles.
Preferences = {
"browser.contentblocking.category" = { Value = "strict"; Status = "locked"; };
"extensions.pocket.enabled" = lock-false;
"extensions.screenshots.disabled" = lock-true;
"browser.topsites.contile.enabled" = lock-false;
"browser.formfill.enable" = lock-false;
"browser.search.suggest.enabled" = lock-false;
"browser.search.suggest.enabled.private" = lock-false;
"browser.urlbar.suggest.searches" = lock-false;
"browser.urlbar.showSearchSuggestionsFirst" = lock-false;
"browser.newtabpage.activity-stream.feeds.section.topstories" = lock-false;
"browser.newtabpage.activity-stream.feeds.snippets" = lock-false;
"browser.newtabpage.activity-stream.section.highlights.includePocket" = lock-false;
"browser.newtabpage.activity-stream.section.highlights.includeBookmarks" = lock-false;
"browser.newtabpage.activity-stream.section.highlights.includeDownloads" = lock-false;
"browser.newtabpage.activity-stream.section.highlights.includeVisited" = lock-false;
"browser.newtabpage.activity-stream.showSponsored" = lock-false;
"browser.newtabpage.activity-stream.system.showSponsored" = lock-false;
"browser.newtabpage.activity-stream.showSponsoredTopSites" = lock-false;
"browser.newtabpage.activity-stream.feeds.section.highlights" = false;
};
};
};
profiles = {
default = {
id = 0;
name = "default";
isDefault = true;
search = {
default = "holocron";
order = [ "holocron" "google" ];
engines= {
holocron = {
name = "Holocron";
urls = [{
template = "https://holocron.scarif.space/search";
params = [
{ name = "q"; value = "{searchTerms}"; }
];
}];
icon = "https://holocron.scarif.space/favicon.ico";
definedAliases = [ "@h" ];
};
bing.metaData.hidden = true;
ebay.metaData.hidden = true;
perplexity.metaData.hidden = true;
};
};
};
};
};
};
nixpkgs = {
config = {
allowUnfree = true;
allowUnfreePredicate = (_: true);
permittedInsecurePackages = [
"electron-25.9.0" # Obsidian
"beekeeper-studio-5.3.4"
];
};
};
};
extraSpecialArgs = {
inherit inputs;
};
};
}
];
};
};
# Standalone home-manager configuration entrypoint
#homeConfigurations = {
# chris = home-manager.lib.homeManagerConfiguration {
# inherit pkgs;
# extraSpecialArgs = {
# inherit inputs;
# };
# modules = [
# ./home
# ];
# };
#};
};
}