Add NixOS dual-configuration setup with isolated dev and gaming profiles #1
41
README.md
@@ -45,6 +45,9 @@ nixos-config/
|
|||||||
git clone <this-repo> ~/nixos-config
|
git clone <this-repo> ~/nixos-config
|
||||||
cd ~/nixos-config
|
cd ~/nixos-config
|
||||||
|
|
||||||
|
# Create the host directory (replace <hostname> with your actual hostname)
|
||||||
|
mkdir -p hosts/<hostname>
|
||||||
|
|
|||||||
|
|
||||||
# Replace the placeholder hardware-configuration.nix with your actual one
|
# Replace the placeholder hardware-configuration.nix with your actual one
|
||||||
cp /etc/nixos/hardware-configuration.nix hosts/<hostname>/
|
cp /etc/nixos/hardware-configuration.nix hosts/<hostname>/
|
||||||
```
|
```
|
||||||
@@ -60,10 +63,12 @@ Edit the following files and replace these placeholders:
|
|||||||
| `<timezone>` | `America/New_York` | `modules/common.nix` |
|
| `<timezone>` | `America/New_York` | `modules/common.nix` |
|
||||||
| `<locale>` | `en_US.UTF-8` | `modules/common.nix` |
|
| `<locale>` | `en_US.UTF-8` | `modules/common.nix` |
|
||||||
|
|
||||||
Also rename `hosts/hostname/` to match your actual hostname.
|
Also rename the `hosts/hostname/` directory to match your actual hostname, and ensure the same hostname is used for all `<hostname>` placeholders (including in `flake.nix`).
|
||||||
|
|
||||||
### 3. Stage Files in Git
|
### 3. Stage Files in Git
|
||||||
|
|
||||||
|
**IMPORTANT:** Flakes require all files to be tracked by git before building.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ~/nixos-config
|
cd ~/nixos-config
|
||||||
git add .
|
git add .
|
||||||
@@ -78,11 +83,16 @@ nix flake show
|
|||||||
|
|
||||||
### 5. Build and Switch
|
### 5. Build and Switch
|
||||||
|
|
||||||
|
**IMPORTANT:** Ensure all files are staged in git (step 3) before building.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Build and switch to dev config as main system profile
|
# Build and switch to dev config as main system profile
|
||||||
sudo nixos-rebuild switch --flake .#dev
|
sudo nixos-rebuild switch --flake .#dev
|
||||||
|
|
||||||
# Build gaming config as separate boot profile
|
# (Optional) Test gaming config without committing it as a boot option
|
||||||
|
sudo nixos-rebuild test --flake .#gaming
|
||||||
|
|
||||||
|
# Build gaming config as separate boot profile (available after next reboot)
|
||||||
sudo nixos-rebuild boot --profile-name gaming --flake .#gaming
|
sudo nixos-rebuild boot --profile-name gaming --flake .#gaming
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -94,20 +104,22 @@ Boot menu should show:
|
|||||||
|
|
||||||
## Updating
|
## Updating
|
||||||
|
|
||||||
**IMPORTANT:** Always update both profiles together to avoid kernel/Mesa version drift:
|
**IMPORTANT:** Always update both profiles together to avoid kernel/Mesa version drift.
|
||||||
|
|
||||||
|
### After Configuration Changes
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ~/nixos-config
|
cd ~/nixos-config
|
||||||
git add .
|
git add . # Stage your configuration changes
|
||||||
sudo nixos-rebuild switch --flake .#dev
|
sudo nixos-rebuild switch --flake .#dev
|
||||||
sudo nixos-rebuild boot --profile-name gaming --flake .#gaming
|
sudo nixos-rebuild boot --profile-name gaming --flake .#gaming
|
||||||
```
|
```
|
||||||
|
|
||||||
To update flake inputs:
|
### Updating Flake Inputs Only
|
||||||
|
The update instructions start with "git add ." (line 101) which suggests staging all changes, but this is only appropriate if the user has made configuration changes. If they're just updating flake inputs (as shown in lines 108-112), they only need to stage flake.lock. The "git add ." command could accidentally stage unwanted changes. Consider clarifying when to use "git add ." versus just "git add flake.lock". The update instructions start with "git add ." (line 101) which suggests staging all changes, but this is only appropriate if the user has made configuration changes. If they're just updating flake inputs (as shown in lines 108-112), they only need to stage flake.lock. The "git add ." command could accidentally stage unwanted changes. Consider clarifying when to use "git add ." versus just "git add flake.lock".
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
nix flake update
|
nix flake update
|
||||||
git add flake.lock
|
git add flake.lock # Only stage the lock file, not other changes
|
||||||
sudo nixos-rebuild switch --flake .#dev
|
sudo nixos-rebuild switch --flake .#dev
|
||||||
sudo nixos-rebuild boot --profile-name gaming --flake .#gaming
|
sudo nixos-rebuild boot --profile-name gaming --flake .#gaming
|
||||||
```
|
```
|
||||||
@@ -124,19 +136,24 @@ sudo nixos-rebuild boot --profile-name gaming --flake .#gaming
|
|||||||
|
|
||||||
### Change Password
|
### Change Password
|
||||||
|
|
||||||
|
Generate a password hash and update `modules/common.nix`:
|
||||||
```bash
|
```bash
|
||||||
passwd
|
mkpasswd -m sha-512
|
||||||
|
# Copy the output and replace <replace-with-password-hash> in common.nix
|
||||||
```
|
```
|
||||||
|
|
||||||
### Setup MangoWC
|
### Setup MangoWC
|
||||||
|
|
||||||
|
MangoWC is configured to auto-start via greetd. To customize it:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mkdir -p ~/.config/mango
|
mkdir -p ~/.config/mango
|
||||||
cp /etc/mango/config.conf ~/.config/mango/config.conf
|
cp /etc/mango/config.conf ~/.config/mango/config.conf
|
||||||
|
|
||||||
# Create autostart script
|
# Create autostart script for Noctalia shell
|
||||||
cat > ~/.config/mango/autostart.sh << 'EOF'
|
cat > ~/.config/mango/autostart.sh << 'EOF'
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# Ensure quickshell is in PATH (it should be as a user package)
|
||||||
qs -c noctalia-shell &
|
qs -c noctalia-shell &
|
||||||
EOF
|
EOF
|
||||||
chmod +x ~/.config/mango/autostart.sh
|
chmod +x ~/.config/mango/autostart.sh
|
||||||
@@ -147,9 +164,13 @@ Add to `~/.config/mango/config.conf`:
|
|||||||
exec-once="~/.config/mango/autostart.sh"
|
exec-once="~/.config/mango/autostart.sh"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Auto-start MangoWC from TTY
|
### Dev Profile: Docker Access
|
||||||
|
|
||||||
Add to `~/.bash_profile` or `~/.zprofile`:
|
After switching to the dev profile for the first time, you must log out and log back in (or reboot) for Docker group membership to take effect.
|
||||||
|
|
||||||
|
### Auto-start MangoWC from TTY (Alternative)
|
||||||
|
|
||||||
|
If not using greetd, add to `~/.bash_profile` or `~/.zprofile`:
|
||||||
```bash
|
```bash
|
||||||
if [[ -z $WAYLAND_DISPLAY ]] && [[ $(tty) == /dev/tty1 ]]; then
|
if [[ -z $WAYLAND_DISPLAY ]] && [[ $(tty) == /dev/tty1 ]]; then
|
||||||
exec mango
|
exec mango
|
||||||
|
|||||||
10
flake.nix
@@ -1,6 +1,9 @@
|
|||||||
{
|
{
|
||||||
|
The flake.nix uses "mango.nixosModules.mango" (line 33) but there's no verification that this module exists or is exported by the mango flake. If the mango repository doesn't export a nixosModules.mango output, this will cause a build failure. Consider adding a note in the README about verifying the flake inputs or handling potential issues if the upstream flakes change their output schema. The flake.nix uses "mango.nixosModules.mango" (line 33) but there's no verification that this module exists or is exported by the mango flake. If the mango repository doesn't export a nixosModules.mango output, this will cause a build failure. Consider adding a note in the README about verifying the flake inputs or handling potential issues if the upstream flakes change their output schema.
```suggestion
mangoModule =
let
lib = nixpkgs.lib;
in
assert lib.hasAttrByPath [ "nixosModules" "mango" ] mango;
mango.nixosModules.mango;
# IMPORTANT: Replace <hostname> with actual hostname
commonModules = [
./hosts/<hostname>/hardware-configuration.nix
./modules/common.nix
mangoModule
```
|
|||||||
description = "NixOS - Isolated Gaming & Dev configurations";
|
description = "NixOS - Isolated Gaming & Dev configurations";
|
||||||
|
|
||||||
|
# SECURITY NOTE: After first build, commit flake.lock to pin inputs to specific
|
||||||
|
# commits. Update via `nix flake update` only from trusted sources.
|
||||||
|
# This protects against supply-chain attacks from upstream changes.
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
|
|
||||||
@@ -24,13 +27,18 @@
|
|||||||
outputs = { self, nixpkgs, mango, quickshell, noctalia, ... }@inputs:
|
outputs = { self, nixpkgs, mango, quickshell, noctalia, ... }@inputs:
|
||||||
let
|
let
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
|
lib = nixpkgs.lib;
|
||||||
specialArgs = { inherit inputs system; };
|
specialArgs = { inherit inputs system; };
|
||||||
|
|
||||||
|
# Verify mango flake exports the expected module
|
||||||
|
mangoModule = assert lib.hasAttrByPath [ "nixosModules" "mango" ] mango;
|
||||||
|
mango.nixosModules.mango;
|
||||||
|
|
||||||
# IMPORTANT: Replace <hostname> with actual hostname
|
# IMPORTANT: Replace <hostname> with actual hostname
|
||||||
commonModules = [
|
commonModules = [
|
||||||
./hosts/<hostname>/hardware-configuration.nix
|
./hosts/<hostname>/hardware-configuration.nix
|
||||||
./modules/common.nix
|
./modules/common.nix
|
||||||
mango.nixosModules.mango
|
mangoModule
|
||||||
];
|
];
|
||||||
in {
|
in {
|
||||||
nixosConfigurations = {
|
nixosConfigurations = {
|
||||||
|
|||||||
@@ -7,7 +7,8 @@
|
|||||||
# To generate a new hardware configuration, run:
|
# To generate a new hardware configuration, run:
|
||||||
# sudo nixos-generate-config --show-hardware-config > hardware-configuration.nix
|
# sudo nixos-generate-config --show-hardware-config > hardware-configuration.nix
|
||||||
#
|
#
|
||||||
# This placeholder will NOT work for actual system builds.
|
# This placeholder will NOT work for actual system builds - the UUIDs below
|
||||||
|
# are placeholders that must be replaced with your actual disk UUIDs.
|
||||||
|
|
||||||
{ config, lib, pkgs, modulesPath, ... }:
|
{ config, lib, pkgs, modulesPath, ... }:
|
||||||
|
|
||||||
@@ -22,20 +23,21 @@
|
|||||||
boot.kernelModules = [ "kvm-amd" ];
|
boot.kernelModules = [ "kvm-amd" ];
|
||||||
boot.extraModulePackages = [ ];
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
# Example filesystem configuration (replace with your actual mounts)
|
# IMPORTANT: Replace these UUIDs with your actual disk UUIDs
|
||||||
# fileSystems."/" = {
|
# Find your UUIDs with: lsblk -f
|
||||||
# device = "/dev/disk/by-uuid/YOUR-ROOT-UUID";
|
fileSystems."/" = {
|
||||||
# fsType = "ext4";
|
device = "/dev/disk/by-uuid/REPLACE-WITH-YOUR-ROOT-UUID";
|
||||||
# };
|
fsType = "ext4";
|
||||||
#
|
};
|
||||||
# fileSystems."/boot" = {
|
|
||||||
# device = "/dev/disk/by-uuid/YOUR-BOOT-UUID";
|
fileSystems."/boot" = {
|
||||||
# fsType = "vfat";
|
device = "/dev/disk/by-uuid/REPLACE-WITH-YOUR-BOOT-UUID";
|
||||||
# };
|
fsType = "vfat";
|
||||||
#
|
};
|
||||||
# swapDevices = [
|
|
||||||
# { device = "/dev/disk/by-uuid/YOUR-SWAP-UUID"; }
|
swapDevices = [
|
||||||
# ];
|
{ device = "/dev/disk/by-uuid/REPLACE-WITH-YOUR-SWAP-UUID"; }
|
||||||
|
];
|
||||||
|
|
||||||
# CPU microcode updates for AMD
|
# CPU microcode updates for AMD
|
||||||
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||||
|
|||||||
@@ -21,8 +21,8 @@
|
|||||||
# AMD GPU - RDNA 4 (RX 9060 XT) + Zen 3 CPU (5700G)
|
# AMD GPU - RDNA 4 (RX 9060 XT) + Zen 3 CPU (5700G)
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
|
|
||||||
# CRITICAL: RDNA 4 requires navi44 firmware blobs
|
# RDNA 4 requires navi44 firmware blobs (included in redistributable firmware)
|
||||||
hardware.enableAllFirmware = true;
|
hardware.enableRedistributableFirmware = true;
|
||||||
|
|
||||||
# Use the modern amdgpu NixOS module (cleaner than manual initrd config)
|
# Use the modern amdgpu NixOS module (cleaner than manual initrd config)
|
||||||
hardware.amdgpu.initrd.enable = true;
|
hardware.amdgpu.initrd.enable = true;
|
||||||
@@ -69,6 +69,16 @@
|
|||||||
# Enable seatd for session management
|
# Enable seatd for session management
|
||||||
services.seatd.enable = true;
|
services.seatd.enable = true;
|
||||||
|
|
||||||
|
The configuration enables seatd (line 70) which is necessary for MangoWC to function, but there's no configuration for starting MangoWC automatically on boot or login. Users have to manually start it or configure it themselves (as shown in the README post-installation section). For a complete setup, consider mentioning in the README that MangoWC needs to be started manually after the first boot, or provide a display manager option. The configuration enables seatd (line 70) which is necessary for MangoWC to function, but there's no configuration for starting MangoWC automatically on boot or login. Users have to manually start it or configure it themselves (as shown in the README post-installation section). For a complete setup, consider mentioning in the README that MangoWC needs to be started manually after the first boot, or provide a display manager option.
```suggestion
# Use greetd to automatically start a MangoWC session on login
services.greetd = {
enable = true;
settings.default_session = {
# MangoWC compositor command; ensure this matches the MangoWC binary name
command = "mango";
# IMPORTANT: Replace <username> with the same username defined below
user = "<username>";
};
};
```
|
|||||||
|
# Use greetd to automatically start a MangoWC session on login
|
||||||
|
services.greetd = {
|
||||||
|
enable = true;
|
||||||
|
settings.default_session = {
|
||||||
|
command = "mango";
|
||||||
|
# IMPORTANT: Replace <username> with actual username
|
||||||
|
user = "<username>";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
# USER ACCOUNT
|
# USER ACCOUNT
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
@@ -76,8 +86,9 @@
|
|||||||
users.users.<username> = {
|
users.users.<username> = {
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
extraGroups = [ "wheel" "networkmanager" "video" "seat" ];
|
extraGroups = [ "wheel" "networkmanager" "video" "seat" ];
|
||||||
# Set initial password or use hashedPassword
|
# IMPORTANT: Generate a password hash with: mkpasswd -m sha-512
|
||||||
initialPassword = "changeme";
|
# Then replace the placeholder below with the generated hash
|
||||||
|
hashedPassword = "<replace-with-password-hash>";
|
||||||
packages = with pkgs; [
|
packages = with pkgs; [
|
||||||
# -- Noctalia Shell --
|
# -- Noctalia Shell --
|
||||||
inputs.quickshell.packages.${system}.default
|
inputs.quickshell.packages.${system}.default
|
||||||
@@ -121,9 +132,9 @@
|
|||||||
# FONTS
|
# FONTS
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
fonts.packages = with pkgs; [
|
fonts.packages = with pkgs; [
|
||||||
# Nerd fonts - syntax changed in nixpkgs after 24.05
|
# Nerd fonts: current syntax for nixos-unstable and NixOS >= 24.05
|
||||||
# If using older nixpkgs: (nerdfonts.override { fonts = [ "JetBrainsMono" ]; })
|
# For older nixpkgs (before this change), use:
|
||||||
# Current nixpkgs-unstable uses individual packages:
|
# (nerdfonts.override { fonts = [ "JetBrainsMono" ]; })
|
||||||
nerd-fonts.jetbrains-mono
|
nerd-fonts.jetbrains-mono
|
||||||
|
|
||||||
# Other fonts
|
# Other fonts
|
||||||
@@ -166,5 +177,5 @@
|
|||||||
# IMPORTANT: Set to the NixOS version of your install media
|
# IMPORTANT: Set to the NixOS version of your install media
|
||||||
# Check with: nixos-version
|
# Check with: nixos-version
|
||||||
# Do NOT change this after initial install
|
# Do NOT change this after initial install
|
||||||
system.stateVersion = "25.05";
|
system.stateVersion = "24.11";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,8 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
# IMPORTANT: Replace <username> with actual username
|
# IMPORTANT: Replace <username> with actual username
|
||||||
|
Docker requires the user to log out and log back in after being added to the docker group for the group membership to take effect. Since this configuration adds the user to the docker group, users won't be able to use Docker immediately after the first build without logging out and back in. Consider adding this information to the README in a "Post-Installation" or "First Steps" section for the dev profile. Docker requires the user to log out and log back in after being added to the docker group for the group membership to take effect. Since this configuration adds the user to the docker group, users won't be able to use Docker immediately after the first build without logging out and back in. Consider adding this information to the README in a "Post-Installation" or "First Steps" section for the dev profile.
```suggestion
# IMPORTANT: Replace <username> with actual username
# NOTE: This adds the user to the "docker" group so Docker can be used without sudo.
# After first enabling/applying this dev profile, you must log out and log
# back in (or reboot) for the new group membership to take effect.
# Consider documenting this in the README under a "Post-Installation" or
# "First Steps" section for the dev profile.
```
|
|||||||
|
# NOTE: After first enabling/applying this dev profile, you must log out and
|
||||||
|
# log back in (or reboot) for the docker group membership to take effect.
|
||||||
users.users.<username>.extraGroups = [ "docker" ];
|
users.users.<username>.extraGroups = [ "docker" ];
|
||||||
|
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
enableRenice = true;
|
enableRenice = true;
|
||||||
settings = {
|
settings = {
|
||||||
general = {
|
general = {
|
||||||
renice = 10;
|
renice = -10; # Negative value = higher priority for games
|
||||||
};
|
};
|
||||||
gpu = {
|
gpu = {
|
||||||
apply_gpu_optimisations = "accept-responsibility";
|
apply_gpu_optimisations = "accept-responsibility";
|
||||||
@@ -48,6 +48,11 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# NOTE: Profile-specific group membership
|
||||||
|
# The user must be in the "corectrl" and "gamemode" groups for these
|
||||||
|
# programs to function correctly. These groups are only added when using
|
||||||
|
# the gaming profile. If you need consistent group membership across
|
||||||
|
# both profiles, add these groups to common.nix instead.
|
||||||
# IMPORTANT: Replace <username> with actual username
|
# IMPORTANT: Replace <username> with actual username
|
||||||
users.users.<username>.extraGroups = [ "corectrl" "gamemode" ];
|
users.users.<username>.extraGroups = [ "corectrl" "gamemode" ];
|
||||||
|
Both gaming.nix (line 52) and dev.nix (line 26) attempt to add extraGroups to the same user that is already configured in common.nix (line 76-80). In NixOS, when multiple modules configure the same user attribute (extraGroups in this case), the lists are concatenated. However, the common.nix already defines extraGroups = [ "wheel" "networkmanager" "video" "seat" ], and both profiles add their own groups. This works correctly, but it means switching between profiles will have different group memberships for the same user, which could lead to permission issues if files/processes from one profile expect certain groups. Consider documenting this behavior or ensuring both profiles include all necessary groups. Both gaming.nix (line 52) and dev.nix (line 26) attempt to add extraGroups to the same user that is already configured in common.nix (line 76-80). In NixOS, when multiple modules configure the same user attribute (extraGroups in this case), the lists are concatenated. However, the common.nix already defines extraGroups = [ "wheel" "networkmanager" "video" "seat" ], and both profiles add their own groups. This works correctly, but it means switching between profiles will have different group memberships for the same user, which could lead to permission issues if files/processes from one profile expect certain groups. Consider documenting this behavior or ensuring both profiles include all necessary groups.
```suggestion
# NOTE:
# The user must be in the "corectrl" and "gamemode" groups for these
# programs to function correctly. To avoid profile-specific differences
# in group membership, add these groups to `users.users.<username>.extraGroups`
# in your common user configuration (e.g. common.nix), rather than here.
```
|
|||||||
|
|
||||||
@@ -91,11 +96,4 @@
|
|||||||
# may crash without this setting due to high mmap requirements.
|
# may crash without this setting due to high mmap requirements.
|
||||||
"vm.max_map_count" = 2147483642;
|
"vm.max_map_count" = 2147483642;
|
||||||
};
|
};
|
||||||
|
|
||||||
# Additional kernel params for gaming (appends to common.nix params)
|
|
||||||
boot.kernelParams = [
|
|
||||||
"amd_pstate=active" # Inherited from common, but explicit for clarity
|
|
||||||
"mitigations=off" # Optional: Disable CPU mitigations for ~5% perf gain
|
|
||||||
# Remove this line if security is a concern
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|||||||
The README instructs users to "cp /etc/nixos/hardware-configuration.nix hosts/<hostname>/" (line 49), but this assumes the hosts/<hostname>/ directory already exists. If users haven't renamed the directory yet (as per line 63), this command will fail. The setup instructions should specify creating or renaming the directory first, then copying the hardware configuration.