A vibe coded tangled fork which supports pijul.
at 3b14253cae0356307eb6f6b69014ff9e1ed71c3a 269 lines 8.7 kB view raw
1{ 2 nixpkgs, 3 system, 4 hostSystem, 5 self, 6}: let 7 envVar = name: let 8 var = builtins.getEnv name; 9 in 10 if var == "" 11 then throw "\$${name} must be defined, see https://docs.tangled.org/hacking-on-tangled.html#hacking-on-tangled for more details" 12 else var; 13 envVarOr = name: default: let 14 var = builtins.getEnv name; 15 in 16 if var != "" 17 then var 18 else default; 19 20 plcUrl = envVarOr "TANGLED_VM_PLC_URL" "https://plc.directory"; 21 jetstream = envVarOr "TANGLED_VM_JETSTREAM_ENDPOINT" "wss://jetstream1.us-west.bsky.network/subscribe"; 22 relayUrl = envVarOr "TANGLED_VM_RELAY_URL" "https://relay1.us-east.bsky.network"; 23in 24 nixpkgs.lib.nixosSystem { 25 inherit system; 26 modules = [ 27 self.nixosModules.did-method-plc 28 self.nixosModules.bluesky-jetstream 29 self.nixosModules.bluesky-relay 30 self.nixosModules.knot 31 self.nixosModules.spindle 32 ({ 33 lib, 34 config, 35 pkgs, 36 ... 37 }: { 38 virtualisation.vmVariant.virtualisation = { 39 host.pkgs = import nixpkgs {system = hostSystem;}; 40 41 graphics = false; 42 memorySize = 2048; 43 diskSize = 10 * 1024; 44 cores = 2; 45 forwardPorts = [ 46 # caddy 47 { 48 from = "host"; 49 host.port = 80; 50 guest.port = 80; 51 } 52 { 53 from = "host"; 54 host.port = 443; 55 guest.port = 443; 56 } 57 { 58 from = "host"; 59 proto = "udp"; 60 host.port = 443; 61 guest.port = 443; 62 } 63 # ssh 64 { 65 from = "host"; 66 host.port = 2222; 67 guest.port = 22; 68 } 69 # knot 70 { 71 from = "host"; 72 host.port = 6444; 73 guest.port = 6444; 74 } 75 # spindle 76 { 77 from = "host"; 78 host.port = 6555; 79 guest.port = 6555; 80 } 81 { 82 from = "host"; 83 host.port = 6556; 84 guest.port = 2480; 85 } 86 ]; 87 sharedDirectories = { 88 # We can't use the 9p mounts directly for most of these 89 # as SQLite is incompatible with them. So instead we 90 # mount the shared directories to a different location 91 # and copy the contents around on service start/stop. 92 caddyData = { 93 source = "$TANGLED_VM_DATA_DIR/caddy"; 94 target = config.services.caddy.dataDir; 95 }; 96 knotData = { 97 source = "$TANGLED_VM_DATA_DIR/knot"; 98 target = "/mnt/knot-data"; 99 }; 100 spindleData = { 101 source = "$TANGLED_VM_DATA_DIR/spindle"; 102 target = "/mnt/spindle-data"; 103 }; 104 spindleLogs = { 105 source = "$TANGLED_VM_DATA_DIR/spindle-logs"; 106 target = "/var/log/spindle"; 107 }; 108 }; 109 }; 110 # This is fine because any and all ports that are forwarded to host are explicitly marked above, we don't need a separate guest firewall 111 networking.firewall.enable = false; 112 # resolve `*.tngl.boltless.dev` to host 113 services.dnsmasq.enable = true; 114 services.dnsmasq.settings.address = "/tngl.boltless.dev/10.0.2.2"; 115 security.pki.certificates = [ 116 (builtins.readFile ../contrib/certs/root.crt) 117 ]; 118 time.timeZone = "Europe/London"; 119 services.timesyncd.enable = lib.mkVMOverride true; 120 services.getty.autologinUser = "root"; 121 environment.systemPackages = with pkgs; [curl vim git sqlite litecli]; 122 virtualisation.docker.extraOptions = '' 123 --dns 172.17.0.1 124 ''; 125 services.tangled.knot = { 126 enable = true; 127 motd = "Welcome to the development knot!\n"; 128 server = { 129 owner = envVar "TANGLED_VM_KNOT_OWNER"; 130 hostname = envVarOr "TANGLED_VM_KNOT_HOST" "localhost:6444"; 131 plcUrl = plcUrl; 132 jetstreamEndpoint = jetstream; 133 listenAddr = "0.0.0.0:6444"; 134 }; 135 }; 136 services.tangled.spindle = { 137 enable = true; 138 server = { 139 owner = envVar "TANGLED_VM_SPINDLE_OWNER"; 140 hostname = envVarOr "TANGLED_VM_SPINDLE_HOST" "localhost:6555"; 141 plcUrl = plcUrl; 142 relayUrl = relayUrl; 143 listenAddr = "0.0.0.0:6555"; 144 dev = true; 145 queueSize = 100; 146 maxJobCount = 2; 147 secrets = { 148 provider = "sqlite"; 149 }; 150 }; 151 }; 152 services.did-method-plc.enable = true; 153 services.bluesky-pds = { 154 enable = true; 155 # overriding package version to support emails 156 package = pkgs.bluesky-pds.overrideAttrs (old: rec { 157 version = "0.4.188"; 158 src = pkgs.fetchFromGitHub { 159 owner = "bluesky-social"; 160 repo = "pds"; 161 tag = "v${version}"; 162 hash = "sha256-t8KdyEygXdbj/5Rhj8W40e1o8mXprELpjsKddHExmo0="; 163 }; 164 pnpmDeps = pkgs.fetchPnpmDeps { 165 inherit version src; 166 pname = old.pname; 167 sourceRoot = old.sourceRoot; 168 fetcherVersion = 2; 169 hash = "sha256-lQie7f8JbWKSpoavnMjHegBzH3GB9teXsn+S2SLJHHU="; 170 }; 171 }); 172 settings = { 173 LOG_ENABLED = "true"; 174 175 PDS_JWT_SECRET = "8cae8bffcc73d9932819650791e4e89a"; 176 PDS_ADMIN_PASSWORD = "d6a902588cd93bee1af83f924f60cfd3"; 177 PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX = "2e92e336a50a618458e1097d94a1db86ec3fd8829d7735020cbae80625c761d7"; 178 179 PDS_EMAIL_SMTP_URL = envVarOr "TANGLED_VM_PDS_EMAIL_SMTP_URL" null; 180 PDS_EMAIL_FROM_ADDRESS = envVarOr "TANGLED_VM_PDS_EMAIL_FROM_ADDRESS" null; 181 182 PDS_DID_PLC_URL = "http://localhost:8080"; 183 PDS_CRAWLERS = "https://relay.tngl.boltless.dev"; 184 PDS_HOSTNAME = "pds.tngl.boltless.dev"; 185 PDS_PORT = 3000; 186 }; 187 }; 188 services.bluesky-relay = { 189 enable = true; 190 }; 191 services.bluesky-jetstream = { 192 enable = true; 193 livenessTtl = 300; 194 websocketUrl = "ws://localhost:3000/xrpc/com.atproto.sync.subscribeRepos"; 195 }; 196 services.caddy = { 197 enable = true; 198 configFile = pkgs.writeText "Caddyfile" '' 199 { 200 debug 201 cert_lifetime 3601d 202 pki { 203 ca local { 204 intermediate_lifetime 3599d 205 } 206 } 207 } 208 209 plc.tngl.boltless.dev { 210 tls internal 211 reverse_proxy http://localhost:8080 212 } 213 214 *.pds.tngl.boltless.dev, pds.tngl.boltless.dev { 215 tls internal 216 reverse_proxy http://localhost:3000 217 } 218 219 jetstream.tngl.boltless.dev { 220 tls internal 221 reverse_proxy http://localhost:6008 222 } 223 224 relay.tngl.boltless.dev { 225 tls internal 226 reverse_proxy http://localhost:2470 227 } 228 229 knot.tngl.boltless.dev { 230 tls internal 231 reverse_proxy http://localhost:6444 232 } 233 234 spindle.tngl.boltless.dev { 235 tls internal 236 reverse_proxy http://localhost:6555 237 } 238 ''; 239 }; 240 users = { 241 # So we don't have to deal with permission clashing between 242 # blank disk VMs and existing state 243 users.${config.services.tangled.knot.gitUser}.uid = 666; 244 groups.${config.services.tangled.knot.gitUser}.gid = 666; 245 246 # TODO: separate spindle user 247 }; 248 systemd.services = let 249 mkDataSyncScripts = source: target: { 250 enableStrictShellChecks = true; 251 252 preStart = lib.mkBefore '' 253 mkdir -p ${target} 254 ${lib.getExe pkgs.rsync} -a ${source}/ ${target} 255 ''; 256 257 postStop = lib.mkAfter '' 258 ${lib.getExe pkgs.rsync} -a ${target}/ ${source} 259 ''; 260 261 serviceConfig.PermissionsStartOnly = true; 262 }; 263 in { 264 knot = mkDataSyncScripts "/mnt/knot-data" config.services.tangled.knot.stateDir; 265 spindle = mkDataSyncScripts "/mnt/spindle-data" config.services.tangled.spindle.server.stateDir; 266 }; 267 }) 268 ]; 269 }