Compare commits

...

17 Commits

11 changed files with 420 additions and 205 deletions

43
.gitignore vendored Normal file
View File

@@ -0,0 +1,43 @@
# Nix build outputs
result
result-*
*.img
*.img.zst
*.qcow2
# Nix store
.dirlocals
# Build artifacts
*.o
*.a
*.so
*.dylib
# IDE/Editor
.vscode/
.idea/
*.swp
*.swo
*~
.DS_Store
# OS
.DS_Store
Thumbs.db
# Archives
*.tar.gz
*.tar.bz2
*.zip
# Local development
.envrc
direnv.allow
# Flake lock (optional - usually committed, but some prefer not to)
# flake.lock
# Temporary files
*.tmp
*.bak

163
flake.lock generated
View File

@@ -1,38 +1,6 @@
{
"nodes": {
"flake-compat": {
"locked": {
"lastModified": 1733328505,
"narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=",
"rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec",
"revCount": 69,
"type": "tarball",
"url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.1.0/01948eb7-9cba-704f-bbf3-3fa956735b52/source.tar.gz"
},
"original": {
"type": "tarball",
"url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1769996383,
"narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "57928607ea566b5db3ad13af0e57e921e6b12381",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-parts_2": {
"inputs": {
"nixpkgs-lib": [
"nixvim",
@@ -60,11 +28,11 @@
]
},
"locked": {
"lastModified": 1770818644,
"narHash": "sha256-DYS4jIRpRoKOzJjnR/QqEd/MlT4OZZpt8CrBLv+cjsE=",
"lastModified": 1770995331,
"narHash": "sha256-MZOF7PVKDOMAOp6bJpzuKOb1DVcyUT84568r8y3iVGg=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "0acbd1180697de56724821184ad2c3e6e7202cd7",
"rev": "5e90b62996d56da9acb21e502c078e7c4e6ab40f",
"type": "github"
},
"original": {
@@ -74,64 +42,13 @@
"type": "github"
}
},
"nixcord": {
"inputs": {
"flake-compat": "flake-compat",
"flake-parts": "flake-parts",
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1770761134,
"narHash": "sha256-65Xg7Rfx9Cj/D+OUF7KZUcYSQPbToBDZpqUfFUAKuwc=",
"owner": "kaylorben",
"repo": "nixcord",
"rev": "f77d6e05efd34581cbc30e7f426496285711bcde",
"type": "github"
},
"original": {
"owner": "kaylorben",
"repo": "nixcord",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1770617025,
"narHash": "sha256-1jZvgZoAagZZB6NwGRv2T2ezPy+X6EFDsJm+YSlsvEs=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "2db38e08fdadcc0ce3232f7279bab59a15b94482",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-25.11",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1769909678,
"narHash": "sha256-cBEymOf4/o3FD5AZnzC3J9hLbiZ+QDT/KDuyHXVJOpM=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "72716169fe93074c333e8d0173151350670b824c",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs.lib",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1770781623,
"narHash": "sha256-RYEMTlGCVc67pxVxjOlGd8w6fpF7Bur7gKL88FB0WTs=",
"lastModified": 1770843696,
"narHash": "sha256-LovWTGDwXhkfCOmbgLVA10bvsi/P8eDDpRudgk68HA8=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "c05d2232d2feaa4c7a07f1168606917402868195",
"rev": "2343bbb58f99267223bc2aac4fc9ea301a155a16",
"type": "github"
},
"original": {
@@ -141,7 +58,7 @@
"type": "github"
}
},
"nixpkgs_3": {
"nixpkgs_2": {
"locked": {
"lastModified": 1770380644,
"narHash": "sha256-P7dWMHRUWG5m4G+06jDyThXO7kwSk46C1kgjEWcybkE=",
@@ -157,34 +74,18 @@
"type": "github"
}
},
"nixpkgs_4": {
"locked": {
"lastModified": 1770197578,
"narHash": "sha256-AYqlWrX09+HvGs8zM6ebZ1pwUqjkfpnv8mewYwAo+iM=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "00c21e4c93d963c50d4c0c89bfa84ed6e0694df2",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixvim": {
"inputs": {
"flake-parts": "flake-parts_2",
"nixpkgs": "nixpkgs_3",
"flake-parts": "flake-parts",
"nixpkgs": "nixpkgs_2",
"systems": "systems"
},
"locked": {
"lastModified": 1770630823,
"narHash": "sha256-5SEmOnJ61vmbap39vzWEsCX5UQ+3Ul8J4mXWKdqSn3w=",
"lastModified": 1770954048,
"narHash": "sha256-TEXS8Z7K+GsOOtL0QD1hrMxL0lVJjKDl3qZq/mJHu2k=",
"owner": "nix-community",
"repo": "nixvim",
"rev": "6acc964664ac916c64fe4e394edd467af4d90790",
"rev": "e49b8deda7b1732f5a2ea2a90446e45adb2a121d",
"type": "github"
},
"original": {
@@ -196,29 +97,8 @@
"root": {
"inputs": {
"home-manager": "home-manager",
"nixcord": "nixcord",
"nixpkgs": "nixpkgs_2",
"nixvim": "nixvim",
"spicetify-nix": "spicetify-nix"
}
},
"spicetify-nix": {
"inputs": {
"nixpkgs": "nixpkgs_4",
"systems": "systems_2"
},
"locked": {
"lastModified": 1770528352,
"narHash": "sha256-KO51BALxgLUlhg1CqQgA3Rj8vgAcDvoLxzNLTxD65cc=",
"owner": "Gerg-L",
"repo": "spicetify-nix",
"rev": "9f4ab243968118026f4ff82f7ce41d30319e2bf0",
"type": "github"
},
"original": {
"owner": "Gerg-L",
"repo": "spicetify-nix",
"type": "github"
"nixpkgs": "nixpkgs",
"nixvim": "nixvim"
}
},
"systems": {
@@ -235,21 +115,6 @@
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",

View File

@@ -16,8 +16,6 @@
home-manager.url = "github:nix-community/home-manager/master";
home-manager.inputs.nixpkgs.follows = "nixpkgs";
nixvim.url = "github:nix-community/nixvim";
nixcord.url = "github:kaylorben/nixcord";
spicetify-nix.url = "github:Gerg-L/spicetify-nix";
};
outputs =
@@ -31,13 +29,15 @@
let
primaryUser = "phil";
system = "aarch64-linux";
in
{
nixosConfigurations."cyper-pi-1" = nixpkgs.lib.nixosSystem {
mkNixosConfig =
hostName:
nixpkgs.lib.nixosSystem {
inherit system;
modules = [
./nixos/default.nix
./nixos/hardware.nix
./hosts/${hostName}/configuration.nix
home-manager.nixosModules.home-manager
{
home-manager = {
@@ -51,5 +51,10 @@
];
specialArgs = { inherit inputs self primaryUser; };
};
in
{
nixosConfigurations."cyper-pi-1" = mkNixosConfig "cyper-pi-1";
nixosConfigurations."cyper-pi-2" = mkNixosConfig "cyper-pi-2";
};
}

View File

@@ -1,23 +1,24 @@
{
#pkgs,
lib,
...
}:
{
# Host-specific packages
#environment.systemPackages = with pkgs; [
# python3
# nodejs
#];
imports = [
./postgres.nix
./postgrest.nix
./swagger.nix
./k3s-master.nix
];
# Any RPi 4 specific customizations go here
networking = {
hostName = "cyper-pi-1";
interfaces.end0.ipv4.addresses = [
{
address = "192.168.2.41";
prefixLength = 24;
}
];
hostName = lib.mkForce "cyper-pi-1";
# interfaces.end0.ipv4.addresses = [
# {
# address = "192.168.2.41";
# prefixLength = 24;
# }
# ];
};
}

View File

@@ -0,0 +1,39 @@
{ pkgs, ... }:
{
boot.kernelParams = [
"cgroup_memory=1"
"cgroup_enable=memory"
"cgroup_enable=cpuset"
];
services.k3s = {
enable = true;
role = "server";
clusterInit = true;
extraFlags = ''
--disable=traefik
--flannel-backend=host-gw
'';
};
networking.firewall = {
allowedTCPPorts = [ 6443 ];
allowedTCPPortRanges = [
{
from = 10250;
to = 10250;
}
{
from = 30000;
to = 32767;
}
];
trustedInterfaces = [ "cni0" ];
};
environment.systemPackages = with pkgs; [
kubectl
kubernetes-helm
];
}

View File

@@ -0,0 +1,85 @@
{
pkgs,
...
}:
{
services.postgresql = {
enable = true;
package = pkgs.postgresql_15;
enableTCPIP = true;
# Initial database setup
initialScript = pkgs.writeText "backend-init-script" ''
CREATE USER postgres WITH SUPERUSER PASSWORD 'postgres';
-- Create web_anon role for PostgREST
CREATE ROLE web_anon NOLOGIN;
GRANT USAGE ON SCHEMA public TO web_anon;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO web_anon;
-- Create example users table
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
name VARCHAR(255),
email VARCHAR(255),
created_at TIMESTAMP DEFAULT NOW()
);
-- Grant permissions
GRANT SELECT, INSERT, UPDATE, DELETE ON users TO web_anon;
GRANT USAGE, SELECT ON SEQUENCE users_id_seq TO web_anon;
'';
# Raspberry Pi 4 optimized settings (2GB RAM assumed)
settings = {
# Should match firewall
port = 5432;
# Memory settings (RPi 4 has limited RAM)
shared_buffers = "128MB";
effective_cache_size = "512MB";
maintenance_work_mem = "32MB";
work_mem = "2MB";
wal_buffers = "4MB";
# Connection settings
max_connections = 20;
# Performance tuning for ARM/RPi
random_page_cost = 2.0;
effective_io_concurrency = 100;
# WAL settings (conservative for SD card)
wal_level = "replica";
checkpoint_timeout = "15min";
checkpoint_completion_target = 0.7;
min_wal_size = "1GB";
max_wal_size = "4GB";
# Query planning
default_statistics_target = 50;
# Logging
log_min_duration_statement = 1000;
log_duration = false;
# ARM/RPi specific
cpu_index_tuple_cost = 0.1;
cpu_operator_cost = 0.05;
};
authentication = ''
local all all trust
host all all 127.0.0.1/32 md5
host all all ::1/128 md5
host all all 192.168.2.0/24 md5
'';
};
# Enable the PostgreSQL service to start on boot
systemd.services.postgresql.wantedBy = [ "multi-user.target" ];
# Open firewall port for PostgreSQL
networking.firewall.allowedTCPPorts = [ 5432 ];
}

View File

@@ -0,0 +1,50 @@
{
pkgs,
...
}:
{
# PostgREST service
systemd.services.postgrest = {
description = "PostgREST - PostgreSQL REST API";
after = [
"postgresql.service"
"network.target"
];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "simple";
ExecStart = "${pkgs.postgrest}/bin/postgrest /etc/postgrest/postgrest.conf";
User = "postgrest";
Restart = "on-failure";
RestartSec = 5;
};
};
# Create postgrest user
users.users.postgrest = {
isSystemUser = true;
group = "postgrest";
};
users.groups.postgrest = { };
# PostgREST configuration file
environment.etc."postgrest/postgrest.conf".text = ''
db-uri = "postgres://postgres:postgres@127.0.0.1:5432/postgres"
db-schema = "public"
db-anon-role = "web_anon"
server-host = "0.0.0.0"
server-port = 3000
jwt-secret = "no7WwM0xJa/Yzn5o4IZHG4oBNSShl4JRPZOcmhvnqFw="
'';
# Open firewall port for PostgREST
networking.firewall.allowedTCPPorts = [ 3000 ];
# Include postgrest in system packages
environment.systemPackages = with pkgs; [
postgrest
];
}

View File

@@ -0,0 +1,80 @@
{
pkgs,
...
}:
{
# Swagger UI service
systemd.services.swagger-ui = {
description = "Swagger UI for PostgREST API";
after = [ "postgrest.service" "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "simple";
ExecStart = "${pkgs.nodePackages.http-server}/bin/http-server /var/lib/swagger-ui -p 8080 -c-1 --cors";
Restart = "on-failure";
RestartSec = 5;
User = "swagger";
};
};
# Create swagger user
users.users.swagger = {
isSystemUser = true;
group = "swagger";
};
users.groups.swagger = {};
# Setup Swagger UI directory
systemd.tmpfiles.rules = [
"d /var/lib/swagger-ui 0755 swagger swagger"
];
# Create Swagger UI index.html that points to PostgREST OpenAPI
environment.etc."swagger-ui-init/index.html".text = ''
<!DOCTYPE html>
<html>
<head>
<title>Swagger UI - PostgREST API</title>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@3/swagger-ui.css">
</head>
<body>
<div id="swagger-ui"></div>
<script src="https://cdn.jsdelivr.net/npm/swagger-ui-dist@3/swagger-ui-bundle.js"></script>
<script src="https://cdn.jsdelivr.net/npm/swagger-ui-dist@3/swagger-ui-standalone-preset.js"></script>
<script>
SwaggerUIBundle({
url: "http://localhost:3000/openapi.json",
dom_id: '#swagger-ui',
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
layout: "StandaloneLayout"
})
</script>
</body>
</html>
'';
# Copy Swagger UI files on startup
system.activationScripts.swagger-ui-setup = ''
mkdir -p /var/lib/swagger-ui
cp ${pkgs.swagger-ui}/share/swagger-ui/* /var/lib/swagger-ui/ 2>/dev/null || true
cp /etc/swagger-ui-init/index.html /var/lib/swagger-ui/index.html
chown -R swagger:swagger /var/lib/swagger-ui
'';
# Open firewall port for Swagger UI
networking.firewall.allowedTCPPorts = [ 8080 ];
# Include packages
environment.systemPackages = with pkgs; [
swagger-ui
nodePackages.http-server
];
}

View File

@@ -0,0 +1,19 @@
{
lib,
...
}:
{
imports = [ ../services/k3s-agent.nix ];
# Any RPi 4 specific customizations go here
networking = {
hostName = lib.mkForce "cyper-pi-2";
# interfaces.end0.ipv4.addresses = [
# {
# address = "192.168.2.41";
# prefixLength = 24;
# }
# ];
};
}

View File

@@ -0,0 +1,29 @@
{ ... }:
{
boot.kernelParams = [
"cgroup_memory=1"
"cgroup_enable=memory"
"cgroup_enable=cpuset"
];
services.k3s = {
enable = true;
role = "agent";
serverAddr = "https://192.168.2.200:6443";
};
networking.firewall = {
allowedTCPPortRanges = [
{
from = 10250;
to = 10250;
}
{
from = 30000;
to = 32767;
}
];
trustedInterfaces = [ "cni0" ];
};
}

View File

@@ -1,8 +1,5 @@
{
config,
pkgs,
inputs,
self,
primaryUser,
...
}:
@@ -16,6 +13,18 @@
nixpkgs.config.allowUnfree = true;
# Speeding up builds
documentation = {
enable = false;
man = {
enable = false;
generateCaches = false;
};
doc.enable = false;
info.enable = false;
nixos.enable = false;
};
# Override python-lsp-server to skip tests (flaky tests cause timeout)
nixpkgs.config.packageOverrides = pkgs: {
python3 = pkgs.python3.override {
@@ -29,22 +38,9 @@
networking = {
hostName = "cyper-pi";
networkmanager = {
enable = true;
unmanaged = [
"*"
"except:type:wwan"
"except:type:gsm"
];
};
defaultGateway = "192.168.2.1";
nameservers = [
"192.168.2.2"
"8.8.8.8"
"1.1.1.1"
];
useDHCP = true;
networkmanager.enable = false;
enableIPv6 = false;
wireless = {
enable = true;
networks = {
@@ -54,10 +50,9 @@
};
};
enableIPv6 = false;
firewall = {
enable = false;
enable = true;
allowPing = true;
};
};
@@ -73,11 +68,15 @@
isNormalUser = true;
home = "/home/${primaryUser}";
description = "Phil";
hashedPassword = "$6$TqAclAMz/DFP90Ve$HEN4t1pqK36rACeWctJOmLArkTWb/rIBYamu4sY8bPuDnqkVVyfOLqXKkgX8zBf9LKz02.mo4EKFRnYWIzcAX1";
extraGroups = [
"wheel"
"networkmanager"
];
shell = pkgs.fish;
openssh.authorizedKeys.keys = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCaLHfxVylghDMYR8t4QMUpeRRqXasNABQKBEy9MmhbUXCcWiPbPMSZH8FMHON34rm2OrXP1kY/8jQxqBJDA+SqpFR2AZ4Khk9iVMaq5GHxxpn2amZUjoBa+fB29WaiE1npV5JVJV3O0ylw6GtiCnpneE6fGx2MO1vOY/7zKrUX/OK7WfwkDpeEzZgV/j/md917HrzUVeZwdeTq3WCRO8Gew6R8Xs6FRjSiGuH0dq14D4Ow5Zf1cI1jx+JfD/5vGasw8HXPu1NdxsOE+6D7/22IKqGr+S74/lAoyyD5qqk0s05lw8UY/PXBLJaNLZu9Fwx0BqTHpJEvftpmvd9wUxgR3msx9VXtKNSrqivIbDgeU+3oGzzkrGZODl7FCp4XKGmbrX85Z6lKwEGgv5jez4MLZcmT86bxB7m1wIbqSbVtfhS+GI7yPTA/kLzzFa14Im/+LTj95pb8qs2ALMwTMP1j2f9A6D3RriOFihL+68qn+YbK58KuV1R0f+CQRmlfVbk= phil@web.cyperpunk.de"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEuYuGhqRC/QLoRBH91c3DG5JHlAdRLQsvde18k5ipY2 phil@cyperpunk.de"
];
};
# Shell