]> Git — Sourcephile - sourcephile-nix.git/blob - hosts/mermet/radicle.nix
+dev/update(android): remove pkgs.android-udev-rules
[sourcephile-nix.git] / hosts / mermet / radicle.nix
1 {
2 config,
3 pkgs,
4 lib,
5 host,
6 hostName,
7 ...
8 }:
9 let
10 inherit (config.networking) domain;
11 inherit (config.users) users;
12 srv = "radicle";
13 radicle = config.services.radicle;
14 seed = "${srv}-${hostName}.${domain}";
15 repositories = {
16 haskell-miso-nix-demo = "rad:z2BeGZUdNCY3FzYarKMV7XXXuc5os";
17 heartwood = "rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5";
18 literate-phylomemy = "rad:z2364hmzZUAGy1nKdSFa1gLSoUE2M";
19 logic = "rad:z3795BqJN8hSMGkyAUr8hHviEEi2H";
20 symantic-base = "rad:z4NtwMC1GmUuCRLngaZrVrSZLmUvh";
21 };
22 in
23 {
24 services.radicle = {
25 enable = true;
26 privateKeyFile = "key:${radicle/key.cred}";
27 publicKey = radicle/key.pub;
28 #package = pkgs.radicle-node;
29 node = { };
30 # FIXME: because radicle-node from the heartwood's flake.nix does not include rad
31 # Should be re-enabled once radicle-node comes from Nixpkgs
32 checkConfig = false;
33 httpd = {
34 enable = true;
35 package = pkgs.radicle-httpd;
36 nginx = {
37 serverName = seed;
38 forceSSL = true;
39 enableACME = false;
40 useACMEHost = domain;
41 extraConfig = ''
42 access_log off;
43 error_log /var/log/nginx/${domain}/${srv}-${hostName}/error.log warn;
44 '';
45 };
46 # UsabilitySelfDescriptivenessToDo: needs nixos-25.11
47 #aliases = repositories;
48 };
49 settings = {
50 preferredSeeds = [
51 "z6MkrLMMsiPWUcNPHcRajuMi9mDfYckSoJyPwwnknocNYPm7@seed.radicle.garden:8776"
52 #"z6Mkmqogy2qEM2ummccUthFEaaHvyYmYBYh3dbe9W4ebScxo@ash.radicle.garden:8776"
53 ];
54 publicExplorer = "https://${srv}.${domain}/nodes/$host/$rid$path";
55 node = {
56 policy = "block";
57 scope = "all";
58 # Relaying produces a constant network stream!
59 relay = "never";
60 # Make this a public node
61 #externalAddresses = [
62 # "${seed}:${toString radicle.node.listenPort}"
63 # #"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.onion:${toString radicle.node.listenPort}"
64 #];
65 peers = {
66 type = "dynamic";
67 target = 0;
68 };
69 limits = {
70 routingMaxSize = 1000;
71 routingMaxAge = 1 * 7 * 24 * 60 * 60; # 1 week
72 gossipMaxAge = 1 * 7 * 24 * 60 * 60; # 1 week
73 fetchConcurrency = 1;
74 maxOpenFiles = 4096;
75 rate = {
76 inbound = {
77 fillRate = 1;
78 capacity = 1;
79 };
80 outbound = {
81 fillRate = 1;
82 capacity = 1;
83 };
84 };
85 connection = {
86 inbound = 16;
87 outbound = 32;
88 };
89 };
90 workers = host.CPUs;
91 /*
92 onion = {
93 mode = "proxy";
94 address = "127.0.0.1:9050";
95 };
96 */
97 };
98 web = {
99 description = "Radicle node hosting repositories for sourcephile.fr";
100 #bannerUrl = "";
101 #avatarUrl = "";
102 pinned = {
103 # Pinned repositories must be `rad clone`-d before.
104 repositories = [
105 repositories.haskell-miso-nix-demo
106 repositories.literate-phylomemy
107 repositories.logic
108 repositories.symantic-base
109 ];
110 };
111 };
112 };
113 };
114 systemd.services.radicle-node = {
115 environment.RUST_LOG = "debug";
116 serviceConfig = {
117 CPUAccounting = true;
118 CPUWeight = "idle";
119 #CPUQuota = "60%";
120 MemoryAccounting = true;
121 MemoryHigh = "500M";
122 MemoryMax = "600M";
123 CPUSchedulingPolicy = "idle";
124 IOSchedulingClass = "idle";
125 # 0: high priority, 7: low priority
126 IOSchedulingPriority = 3;
127 Nice = 15;
128 };
129 };
130 services.sanoid.datasets."rpool/var/lib/${srv}" = {
131 use_template = [ "snap" ];
132 hourly = 0;
133 daily = 7;
134 monthly = 0;
135 recursive = true;
136 };
137 environment.systemPackages = [
138 pkgs.radicle-node
139 ];
140
141 networking.nftables.ruleset = ''
142 table inet filter {
143 chain input-net {
144 tcp dport ${toString radicle.node.listenPort} counter accept comment "radicle-node"
145 }
146 chain input-neb-sourcephile {
147 tcp dport ${toString radicle.node.listenPort} counter accept comment "radicle-node"
148 }
149 chain output-net {
150 skuid ${users.radicle.name} meta l4proto tcp counter accept comment "radicle-node"
151 }
152 }
153 '';
154
155 services.nginx.virtualHosts."${srv}-explorer.${domain}" = {
156 serverAliases = [ "${srv}.${domain}" ];
157 forceSSL = true;
158 useACMEHost = domain;
159 extraConfig = ''
160 access_log off;
161 error_log /var/log/nginx/${domain}/${srv}-explorer/error.log warn;
162 '';
163 locations."/" = {
164 extraConfig = ''
165 try_files $uri $uri/ /index.html;
166 '';
167 index = "index.html";
168 root = pkgs.radicle-explorer.overrideAttrs (previousAttrs: {
169 postPatch =
170 (previousAttrs.postPatch or "")
171 + ''
172 cp ${pkgs.writeText "local.json" ''
173 {
174 "nodes": {
175 "fallbackPublicExplorer": "https://app.radicle.xyz/nodes/$host/$rid$path",
176 "defaultHttpdPort": 443,
177 "defaultLocalHttpdPort": 8080,
178 "defaultHttpdHostname": "localhost",
179 "defaultHttpdScheme": "https",
180 "defaultNodePort": 8776,
181 "pinned": [
182 {
183 "baseUrl": {
184 "hostname": "${seed}",
185 "port": 443,
186 "scheme": "https"
187 }
188 }
189 ]
190 },
191 "supportWebsite": "https://radicle.zulipchat.com",
192 "reactions": ["👍", "👎", "😄", "🙁", "👀"],
193 "fallbackPreferredSeed": {
194 "hostname": "${seed}",
195 "port": 443,
196 "scheme": "https"
197 }
198 }
199 ''} config/local.json
200 '';
201 });
202 };
203 };
204 systemd.services.nginx.serviceConfig.LogsDirectory = lib.mkForce [
205 "nginx/${domain}/${srv}-${hostName}"
206 "nginx/${domain}/${srv}-explorer"
207 ];
208 }