Compare commits

..

11 commits

8 changed files with 159 additions and 1261 deletions

28
agents.md Normal file
View file

@ -0,0 +1,28 @@
# NixOS Repository Quick Reference
## Quick Commands
- **Test build**: `nixos-rebuild build --flake .#<system>`
- **List systems**: `nix flake show`
- **Commit**: `git add files && git commit -m "msg"`
## Systems
- **warp**: Server + nginx + forgejo
- **skip**: Server + nginx only
- **framework/aurora/labrizor**: Desktop systems
## Key Files
- `flake.nix`: System definitions
- `systems/<name>.nix`: Hardware/boot configs
- `servers/<name>.nix`: Service configs
- `users/<name>.nix`: User configs
## Testing Workflow
1. Always `git status` first - affects flake evaluation
2. Stage changes (`git add`) before building - prevents Nix store issues
3. Test with `nixos-rebuild build --flake .#<system>`
4. Check success message: `"Done. The new configuration is /nix/store/..."`
## Important
- Server configs may contain hardcoded credentials - use agenix or systemd credentials for production
- Both warp and skip build successfully
- Repository root: `/home/jsutter/src/nixos`

View file

@ -1,117 +0,0 @@
# Hybrid Package Management: Stable + Unstable
This NixOS configuration uses a hybrid approach where the system runs on the stable NixOS 24.05 branch but can selectively use packages from the unstable branch when needed.
## How It Works
The `flake.nix` includes both stable and unstable nixpkgs inputs:
```nix
inputs = {
nixpkgs.url = "nixpkgs/nixos-24.05"; # Stable base
nixpkgs-unstable.url = "nixpkgs/nixos-unstable"; # Unstable packages
# ... other inputs
};
```
The unstable packages are made available to all system configurations via `specialArgs`:
```nix
nixosConfigurations = {
framework = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
specialArgs = {
pkgs-unstable = import nixpkgs-unstable {
system = "x86_64-linux";
config.allowUnfree = true;
};
};
modules = [ /* ... */ ];
};
};
```
## Using Unstable Packages
### In System Configuration Files
To use an unstable package in any `.nix` configuration file:
1. **Add `pkgs-unstable` to the function parameters:**
```nix
{ config, pkgs, pkgs-unstable, ... }:
```
2. **Use the unstable package:**
```nix
environment.systemPackages = with pkgs; [
# Stable packages
firefox
git
# Unstable packages
pkgs-unstable.windsurf
pkgs-unstable.some-other-package
];
```
### Example: Current Usage
See `desktop/dev.nix` for a working example:
```nix
{ config, pkgs, pkgs-unstable, ... }:
{
environment.systemPackages = with pkgs; [
# Stable packages
nodejs
rpi-imager
# Unstable packages
pkgs-unstable.windsurf # Use windsurf from unstable
];
}
```
## When to Use Unstable Packages
Use unstable packages when:
- A package is not available in the stable branch
- You need a newer version with specific features or bug fixes
- You're developing with cutting-edge tools
## Benefits of This Approach
1. **System Stability**: Core system components use stable, well-tested packages
2. **Package Availability**: Access to the latest packages when needed
3. **Selective Updates**: Choose which packages to get from unstable
4. **Easy Maintenance**: Clear separation between stable and unstable dependencies
## Adding New Unstable Packages
To add a new unstable package:
1. Find the configuration file where you want to add the package
2. Ensure the file accepts `pkgs-unstable` parameter
3. Add `pkgs-unstable.package-name` to the appropriate list
4. Test with `nixos-rebuild dry-run --flake .#framework`
5. Apply with `nixos-rebuild switch --flake .#framework`
## Updating Packages
- **Stable packages**: Updated when you update the flake lock
- **Unstable packages**: Updated when you run `nix flake update`
To update only unstable packages:
```bash
nix flake lock --update-input nixpkgs-unstable
```
## Current Unstable Packages in Use
- `windsurf` - Modern code editor (in `desktop/dev.nix`)
---
This hybrid approach gives you the stability of NixOS stable with the flexibility to use cutting-edge packages when needed.

File diff suppressed because it is too large Load diff

View file

@ -85,9 +85,17 @@
./systems/common.nix
./users/jsutter.nix
./systems/warp.nix
./servers/nginx.nix
./servers/forgejo.nix
];
};
skip = mkSystem {
modules = [
./systems/common.nix
./users/jsutter.nix
./systems/skip.nix
];
};
};
};
}

View file

@ -12,25 +12,50 @@ let
adminUser = "jsutter";
adminEmail = "jsutter@symbiotrip.com";
in
{
security.acme.certs.${fqdn}.group = config.services.nginx.group;
# DNS-based ACME certificate configuration
# Uses defaults (dnsProvider, email, credentials) from nginx.nix
security.acme.certs.${fqdn} = {
# Group needs to be set so nginx can read the certificate
group = config.services.nginx.group;
# Inherit DNS challenge configuration from security.acme.defaults (set in nginx.nix)
# This includes: dnsProvider = "cloudflare", environmentFile with Cloudflare token, email
# Explicitly ensure DNS mode (not HTTP-01)
webroot = null;
};
# Nginx virtual host for Forgejo
services.nginx.virtualHosts.${fqdn} = {
# CRITICAL FIX: Don't set enableACME = true
# That would create an HTTP-01 challenge handler, which conflicts with DNS challenge
# Instead, we use useACMEHost to reference the DNS-obtained certificate
enableACME = false; # Disable automatic ACME for this vhost
useACMEHost = fqdn; # Use the certificate obtained via DNS challenge
forceSSL = true;
enableACME = true;
useACMEHost = fqdn;
acmeRoot = null;
# acmeRoot is not needed/used with DNS challenge method
# acmeRoot = null; # Removed - implicit with enableACME = false
extraConfig = ''
client_max_body_size 512M;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Logging for debugging
access_log /var/log/nginx/${fqdn}-access.log;
error_log /var/log/nginx/${fqdn}-error.log warn;
'';
locations."/".proxyPass = "http://localhost:${toString srv.HTTP_PORT}";
};
# Forgejo service configuration
services.forgejo = {
enable = true;
database.type = "postgres";
@ -41,6 +66,8 @@ in
DOMAIN = fqdn;
ROOT_URL = "https://${fqdn}/";
HTTP_PORT = 3000;
# Bind to localhost only - nginx handles public HTTPS
LOCAL_ROOT_URL = "http://localhost:3000/";
};
service.DISABLE_REGISTRATION = true;
@ -60,7 +87,13 @@ in
};
};
# Create/ensure admin user
# Ensure nginx starts after ACME certificate is available
systemd.services.nginx = {
after = [ "acme-${fqdn}.service" "acme-${fqdn}-renew.service" ];
requires = [ "acme-${fqdn}.service" ];
};
# Create/ensure admin user on startup
systemd.services.forgejo.preStart = let
adminCmd = "${lib.getExe cfg.package} admin user";
in ''
@ -72,9 +105,10 @@ in
--must-change-password=false || true
'';
# Actions runner (runs jobs in Docker containers per labels)
# Enable Docker for Forgejo Actions runner
virtualisation.docker.enable = true;
# Configure Forgejo Actions runner
services.gitea-actions-runner = {
package = pkgs.forgejo-runner;
instances.default = {

View file

@ -1,8 +1,9 @@
{ config, lib, pkgs, ... }:
let
# WARNING: this ends up world-readable in the Nix store if you inline it.
# For production, use agenix or pass through systemd credentials
cloudflareEnv = pkgs.writeText "cloudflare-acme.env" ''
umnyPSYOr9U3m404_IBMl4PTOzg29nz_XzNEGw2v
CLOUDFLARE_DNS_API_TOKEN=umnyPSYOr9U3m404_IBMl4PTOzg29nz_XzNEGw2v
'';
in
{

78
systems/skip.nix Executable file
View file

@ -0,0 +1,78 @@
{ config, lib, pkgs, modulesPath, ... }: {
networking.hostName = "skip";
fileSystems."/" =
{ device = "/dev/disk/by-partlabel/primary";
fsType = "ext4";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-partlabel/ESP";
fsType = "vfat";
};
# CPU Settings for 13th gen Intel Core i5
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
# Boot and kernel modules for Intel NUC
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ ]; # No graphics drivers needed for headless
boot.kernelModules = [ "kvm-intel" ]; # Intel virtualization support
boot.extraModulePackages = [];
# Server-specific kernel parameters
boot.kernelParams = [
"intel_iommu=on" # Enable IOMMU for virtualization
];
networking.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
# Power management optimized for server use
powerManagement = {
enable = true;
cpuFreqGovernor = "ondemand";
};
# Thermal management
services.thermald.enable = true;
# Server-oriented settings
services.openssh = {
enable = true;
settings = {
PasswordAuthentication = false;
KbdInteractiveAuthentication = false;
PermitRootLogin = "no";
};
};
# Swap configuration (smaller for server use)
swapDevices = [
{
device = "/swapfile";
size = 8192; # 8GB swap for server workload
priority = 0;
}
];
# Enable hardware monitoring (CLI only)
hardware.sensor.iio.enable = true;
# Network performance tuning for server use
boot.kernel.sysctl = {
"net.core.rmem_max" = 134217728;
"net.core.wmem_max" = 134217728;
"net.ipv4.tcp_rmem" = "4096 65536 134217728";
"net.ipv4.tcp_wmem" = "4096 65536 134217728";
"net.core.netdev_max_backlog" = 5000;
};
# Disable unnecessary services for server use
services.xserver.enable = lib.mkForce false;
services.pipewire.enable = lib.mkForce false;
# Enable container support for future server services
virtualisation.docker.enable = true;
virtualisation.podman.enable = lib.mkDefault true;
}

View file

@ -26,6 +26,8 @@
networking.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
# Power management optimized for server use