Kieran's opinionated (and probably slightly dumb) nix config
1{
2 inputs,
3 lib,
4 config,
5 pkgs,
6 ...
7}:
8{
9 imports = [
10 ./disk-config.nix
11 ./home-manager.nix
12
13 (inputs.import-tree ../../modules/nixos)
14 ];
15
16 nixpkgs = {
17 hostPlatform = "x86_64-linux";
18 config = {
19 allowUnfree = true;
20 };
21 };
22
23 nix =
24 let
25 flakeInputs = lib.filterAttrs (_: lib.isType "flake") inputs;
26 in
27 {
28 settings = {
29 experimental-features = "nix-command flakes";
30 flake-registry = "";
31 nix-path = config.nix.nixPath;
32 trusted-users = [
33 "kierank"
34 ];
35 # Limit resource usage
36 max-jobs = 1;
37 cores = 1;
38 };
39 channel.enable = false;
40 # Disable automatic optimization to save CPU/memory
41 optimise.automatic = false;
42 registry = lib.mapAttrs (_: flake: { inherit flake; }) flakeInputs;
43 nixPath = lib.mapAttrsToList (n: _: "${n}=flake:${n}") flakeInputs;
44 # Enable automatic GC to free up disk space
45 gc = {
46 automatic = true;
47 dates = "weekly";
48 options = "--delete-older-than 7d";
49 };
50 };
51
52 time.timeZone = "America/New_York";
53
54 environment.systemPackages = with pkgs; [
55 # core essentials only
56 vim
57 curl
58 inputs.agenix.packages.x86_64-linux.default
59 ];
60
61 age.identityPaths = [
62 "/home/kierank/.ssh/id_rsa"
63 "/etc/ssh/id_rsa"
64 ];
65 age.secrets = {
66 wakatime = {
67 file = ../../secrets/wakatime.age;
68 path = "/home/kierank/.wakatime.cfg";
69 owner = "kierank";
70 };
71 cloudflare = {
72 file = ../../secrets/cloudflare.age;
73 owner = "caddy";
74 };
75 };
76
77 environment.sessionVariables = {
78 XDG_CACHE_HOME = "$HOME/.cache";
79 XDG_CONFIG_HOME = "$HOME/.config";
80 XDG_DATA_HOME = "$HOME/.local/share";
81 XDG_STATE_HOME = "$HOME/.local/state";
82 EDITOR = "vim";
83 SYSTEMD_EDITOR = "vim";
84 VISUAL = "vim";
85 };
86
87 atelier = {
88 authentication.enable = true;
89 };
90
91 networking = {
92 hostName = "prattle";
93 # Use systemd-networkd instead of NetworkManager (lighter)
94 useDHCP = true;
95 networkmanager.enable = false;
96 };
97
98 # Use bash instead of zsh to save memory
99 programs.bash.enableCompletion = true;
100
101 users.users = {
102 kierank = {
103 initialPassword = "changeme";
104 isNormalUser = true;
105 shell = pkgs.bashInteractive;
106 openssh.authorizedKeys.keys = [
107 "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCzEEjvbL/ttqmYoDjxYQmDIq36BabROJoXgQKeh9liBxApwp+2PmgxROzTg42UrRc9pyrkq5kVfxG5hvkqCinhL1fMiowCSEs2L2/Cwi40g5ZU+QwdcwI8a4969kkI46PyB19RHkxg54OUORiIiso/WHGmqQsP+5wbV0+4riSnxwn/JXN4pmnE//stnyAyoiEZkPvBtwJjKb3Ni9n3eNLNs6gnaXrCtaygEZdebikr9kS2g9mM696HvIFgM6cdR/wZ7DcLbG3IdTXuHN7PC3xxL+Y4ek5iMreQIPmuvs4qslbthPGYoYbYLUQiRa9XO5s/ksIj5Z14f7anHE6cuTQVpvNWdGDOigyIVS5qU+4ZF7j+rifzOXVL48gmcAvw/uV68m5Wl/p0qsC/d8vI3GYwEsWG/EzpAlc07l8BU2LxWgN+d7uwBFaJV9VtmUDs5dcslsh8IbzmtC9gq3OLGjklxTfIl6qPiL8U33oc/UwqzvZUrI2BlbagvIZYy6rP+q0= kierank@mockingjay"
108 ];
109 extraGroups = [
110 "wheel"
111 ];
112 };
113 root.openssh.authorizedKeys.keys = [
114 "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCzEEjvbL/ttqmYoDjxYQmDIq36BabROJoXgQKeh9liBxApwp+2PmgxROzTg42UrRc9pyrkq5kVfxG5hvkqCinhL1fMiowCSEs2L2/Cwi40g5ZU+QwdcwI8a4969kkI46PyB19RHkxg54OUORiIiso/WHGmqQsP+5wbV0+4riSnxwn/JXN4pmnE//stnyAyoiEZkPvBtwJjKb3Ni9n3eNLNs6gnaXrCtaygEZdebikr9kS2g9mM696HvIFgM6cdR/wZ7DcLbG3IdTXuHN7PC3xxL+Y4ek5iMreQIPmuvs4qslbthPGYoYbYLUQiRa9XO5s/ksIj5Z14f7anHE6cuTQVpvNWdGDOigyIVS5qU+4ZF7j+rifzOXVL48gmcAvw/uV68m5Wl/p0qsC/d8vI3GYwEsWG/EzpAlc07l8BU2LxWgN+d7uwBFaJV9VtmUDs5dcslsh8IbzmtC9gq3OLGjklxTfIl6qPiL8U33oc/UwqzvZUrI2BlbagvIZYy6rP+q0= kierank@mockingjay"
115 ];
116 };
117
118 # Allow passwordless sudo for wheel group (needed for deploy-rs)
119 security.sudo.wheelNeedsPassword = false;
120
121 services.openssh = {
122 enable = true;
123 openFirewall = true;
124 settings = {
125 PermitRootLogin = "no";
126 PasswordAuthentication = false;
127 };
128 };
129
130 networking.firewall = {
131 enable = true;
132 allowedTCPPorts = [ 22 80 443 ];
133 logRefusedConnections = false;
134 rejectPackets = true;
135 # Disable firewall logging to reduce overhead
136 logReversePathDrops = false;
137 };
138
139 services.tailscale = {
140 enable = true;
141 useRoutingFeatures = "client";
142 };
143
144 services.caddy = {
145 enable = true;
146 package = pkgs.caddy.withPlugins {
147 plugins = [ "github.com/caddy-dns/cloudflare@v0.2.2" ];
148 hash = "sha256-ea8PC/+SlPRdEVVF/I3c1CBprlVp1nrumKM5cMwJJ3U=";
149 };
150 email = "me@dunkirk.sh";
151 globalConfig = ''
152 acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN}
153 '';
154 virtualHosts."status.dunkirk.sh" = {
155 extraConfig = ''
156 tls {
157 dns cloudflare {env.CLOUDFLARE_API_TOKEN}
158 }
159 header {
160 Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
161 }
162 reverse_proxy localhost:3001 {
163 header_up X-Forwarded-Proto {scheme}
164 header_up X-Forwarded-For {remote}
165 }
166 '';
167 };
168 extraConfig = ''
169 # Default response for unhandled domains
170 :80 {
171 respond "404 - Looks like this pin is unobtainable" 404
172 }
173 :443 {
174 respond "404 - Looks like this pin is unobtainable" 404
175 }
176 '';
177 };
178
179 systemd.services.caddy.serviceConfig = {
180 EnvironmentFile = config.age.secrets.cloudflare.path;
181 };
182
183 services.uptime-kuma = {
184 enable = true;
185 settings = {
186 PORT = "3001";
187 };
188 };
189
190 boot.loader.systemd-boot.enable = true;
191 boot.loader.efi.canTouchEfiVariables = true;
192 boot.kernelParams = [ "console=ttyS0" ];
193
194 # Memory and resource optimizations
195 zramSwap = {
196 enable = true;
197 memoryPercent = 50; # Use 50% of RAM for compressed swap
198 };
199
200 # Reduce system logging overhead
201 services.journald.extraConfig = ''
202 SystemMaxUse=100M
203 MaxRetentionSec=7day
204 '';
205
206 system.stateVersion = "23.05";
207}