diff options
author | Ismaël Bouya <ismael.bouya@normalesup.org> | 2023-10-04 01:35:06 +0200 |
---|---|---|
committer | Ismaël Bouya <ismael.bouya@normalesup.org> | 2023-10-04 02:11:48 +0200 |
commit | 1a64deeb894dc95e2645a75771732c6cc53a79ad (patch) | |
tree | 1b9df4838f894577a09b9b260151756272efeb53 /flakes/mastodon/flake.nix | |
parent | fa25ffd4583cc362075cd5e1b4130f33306103f0 (diff) | |
download | Nix-1a64deeb894dc95e2645a75771732c6cc53a79ad.tar.gz Nix-1a64deeb894dc95e2645a75771732c6cc53a79ad.tar.zst Nix-1a64deeb894dc95e2645a75771732c6cc53a79ad.zip |
Squash changes containing private information
There were a lot of changes since the previous commit, but a lot of them
contained personnal information about users. All thos changes got
stashed into a single commit (history is kept in a different place) and
private information was moved in a separate private repository
Diffstat (limited to 'flakes/mastodon/flake.nix')
-rw-r--r-- | flakes/mastodon/flake.nix | 331 |
1 files changed, 331 insertions, 0 deletions
diff --git a/flakes/mastodon/flake.nix b/flakes/mastodon/flake.nix new file mode 100644 index 0000000..1d0db10 --- /dev/null +++ b/flakes/mastodon/flake.nix | |||
@@ -0,0 +1,331 @@ | |||
1 | { | ||
2 | description = "Your self-hosted, globally interconnected microblogging community"; | ||
3 | inputs.myuids = { | ||
4 | url = "path:../myuids"; | ||
5 | }; | ||
6 | inputs.flake-utils.url = "github:numtide/flake-utils"; | ||
7 | inputs.nixpkgs = { | ||
8 | url = "github:NixOS/nixpkgs/840c782d507d60aaa49aa9e3f6d0b0e780912742"; | ||
9 | flake = false; | ||
10 | }; | ||
11 | inputs.mastodon = { | ||
12 | url = "github:tootsuite/mastodon/v2.9.4"; | ||
13 | flake = false; | ||
14 | }; | ||
15 | |||
16 | outputs = { self, myuids, nixpkgs, mastodon, flake-utils }: flake-utils.lib.eachSystem ["x86_64-linux"] (system: | ||
17 | let | ||
18 | pkgs = import nixpkgs { inherit system; overlays = []; }; | ||
19 | version = (builtins.fromJSON (builtins.readFile ./flake.lock)).nodes.mastodon.original.ref; | ||
20 | inherit (pkgs) callPackage; | ||
21 | in rec { | ||
22 | packages.mastodon = callPackage ./. { src = mastodon // { inherit version; }; }; | ||
23 | defaultPackage = packages.mastodon; | ||
24 | legacyPackages.mastodon = packages.mastodon; | ||
25 | checks = { | ||
26 | build = defaultPackage; | ||
27 | }; | ||
28 | } | ||
29 | ) // rec { | ||
30 | overlays = { | ||
31 | mastodon = final: prev: { | ||
32 | mastodon = self.defaultPackage."${final.system}"; | ||
33 | }; | ||
34 | }; | ||
35 | overlay = overlays.mastodon; | ||
36 | nixosModule = { lib, pkgs, config, ... }: | ||
37 | let | ||
38 | name = "mastodon"; | ||
39 | cfg = config.immaeServices.mastodon; | ||
40 | in | ||
41 | { | ||
42 | options.immaeServices.mastodon = { | ||
43 | enable = lib.mkEnableOption "Enable Mastodon’s service"; | ||
44 | user = lib.mkOption { | ||
45 | type = lib.types.str; | ||
46 | default = name; | ||
47 | description = "User account under which Mastodon runs"; | ||
48 | }; | ||
49 | group = lib.mkOption { | ||
50 | type = lib.types.str; | ||
51 | default = name; | ||
52 | description = "Group under which Mastodon runs"; | ||
53 | }; | ||
54 | dataDir = lib.mkOption { | ||
55 | type = lib.types.path; | ||
56 | default = "/var/lib/${name}"; | ||
57 | description = '' | ||
58 | The directory where Mastodon stores its data. | ||
59 | ''; | ||
60 | }; | ||
61 | socketsPrefix = lib.mkOption { | ||
62 | type = lib.types.str; | ||
63 | default = "live"; | ||
64 | description = '' | ||
65 | The prefix to use for Mastodon sockets. | ||
66 | ''; | ||
67 | }; | ||
68 | socketsDir = lib.mkOption { | ||
69 | type = lib.types.path; | ||
70 | default = "/run/${name}"; | ||
71 | description = '' | ||
72 | The directory where Mastodon puts runtime files and sockets. | ||
73 | ''; | ||
74 | }; | ||
75 | configFile = lib.mkOption { | ||
76 | type = lib.types.path; | ||
77 | description = '' | ||
78 | The configuration file path for Mastodon. | ||
79 | ''; | ||
80 | }; | ||
81 | package = lib.mkOption { | ||
82 | type = lib.types.package; | ||
83 | default = pkgs.mastodon; | ||
84 | description = '' | ||
85 | Mastodon package to use. | ||
86 | ''; | ||
87 | }; | ||
88 | # Output variables | ||
89 | workdir = lib.mkOption { | ||
90 | type = lib.types.package; | ||
91 | default = cfg.package.override { varDir = cfg.dataDir; }; | ||
92 | description = '' | ||
93 | Adjusted mastodon package with overriden varDir | ||
94 | ''; | ||
95 | readOnly = true; | ||
96 | }; | ||
97 | systemdStateDirectory = lib.mkOption { | ||
98 | type = lib.types.str; | ||
99 | # Use ReadWritePaths= instead if varDir is outside of /var/lib | ||
100 | default = assert lib.strings.hasPrefix "/var/lib/" cfg.dataDir; | ||
101 | lib.strings.removePrefix "/var/lib/" cfg.dataDir; | ||
102 | description = '' | ||
103 | Adjusted Mastodon data directory for systemd | ||
104 | ''; | ||
105 | readOnly = true; | ||
106 | }; | ||
107 | systemdRuntimeDirectory = lib.mkOption { | ||
108 | type = lib.types.str; | ||
109 | # Use ReadWritePaths= instead if socketsDir is outside of /run | ||
110 | default = assert lib.strings.hasPrefix "/run/" cfg.socketsDir; | ||
111 | lib.strings.removePrefix "/run/" cfg.socketsDir; | ||
112 | description = '' | ||
113 | Adjusted Mastodon sockets directory for systemd | ||
114 | ''; | ||
115 | readOnly = true; | ||
116 | }; | ||
117 | sockets = lib.mkOption { | ||
118 | type = lib.types.attrsOf lib.types.path; | ||
119 | default = { | ||
120 | node = "${cfg.socketsDir}/${cfg.socketsPrefix}_node.sock"; | ||
121 | rails = "${cfg.socketsDir}/${cfg.socketsPrefix}_puma.sock"; | ||
122 | }; | ||
123 | readOnly = true; | ||
124 | description = '' | ||
125 | Mastodon sockets | ||
126 | ''; | ||
127 | }; | ||
128 | }; | ||
129 | |||
130 | config = lib.mkIf cfg.enable { | ||
131 | nixpkgs.overlays = [ self.overlay ]; | ||
132 | users.users = lib.optionalAttrs (cfg.user == name) { | ||
133 | "${name}" = { | ||
134 | uid = myuids.lib.uids.mastodon; | ||
135 | group = cfg.group; | ||
136 | description = "Mastodon user"; | ||
137 | home = cfg.dataDir; | ||
138 | useDefaultShell = true; | ||
139 | }; | ||
140 | }; | ||
141 | users.groups = lib.optionalAttrs (cfg.group == name) { | ||
142 | "${name}" = { | ||
143 | gid = myuids.lib.gids.mastodon; | ||
144 | }; | ||
145 | }; | ||
146 | |||
147 | systemd.slices.mastodon = { | ||
148 | description = "Mastodon slice"; | ||
149 | }; | ||
150 | |||
151 | systemd.services.mastodon-streaming = { | ||
152 | description = "Mastodon Streaming"; | ||
153 | wantedBy = [ "multi-user.target" ]; | ||
154 | after = [ "network.target" "mastodon-web.service" ]; | ||
155 | |||
156 | environment.NODE_ENV = "production"; | ||
157 | environment.SOCKET = cfg.sockets.node; | ||
158 | |||
159 | path = [ cfg.workdir.nodejs pkgs.bashInteractive ]; | ||
160 | |||
161 | script = '' | ||
162 | exec npm run start | ||
163 | ''; | ||
164 | |||
165 | postStart = '' | ||
166 | while [ ! -S $SOCKET ]; do | ||
167 | sleep 0.5 | ||
168 | done | ||
169 | chmod a+w $SOCKET | ||
170 | ''; | ||
171 | |||
172 | postStop = '' | ||
173 | rm $SOCKET | ||
174 | ''; | ||
175 | |||
176 | serviceConfig = { | ||
177 | Slice = "mastodon.slice"; | ||
178 | User = cfg.user; | ||
179 | EnvironmentFile = cfg.configFile; | ||
180 | PrivateTmp = true; | ||
181 | Restart = "always"; | ||
182 | TimeoutSec = 15; | ||
183 | Type = "simple"; | ||
184 | WorkingDirectory = cfg.workdir; | ||
185 | StateDirectory = cfg.systemdStateDirectory; | ||
186 | RuntimeDirectory = cfg.systemdRuntimeDirectory; | ||
187 | RuntimeDirectoryPreserve = "yes"; | ||
188 | }; | ||
189 | |||
190 | unitConfig.RequiresMountsFor = cfg.dataDir; | ||
191 | }; | ||
192 | |||
193 | systemd.services.mastodon-web = { | ||
194 | description = "Mastodon Web app"; | ||
195 | wantedBy = [ "multi-user.target" ]; | ||
196 | after = [ "network.target" ]; | ||
197 | |||
198 | environment.RAILS_ENV = "production"; | ||
199 | environment.BUNDLE_PATH = "${cfg.workdir.gems}/${cfg.workdir.gems.ruby.gemPath}"; | ||
200 | environment.BUNDLE_GEMFILE = "${cfg.workdir.gems.confFiles}/Gemfile"; | ||
201 | environment.SOCKET = cfg.sockets.rails; | ||
202 | |||
203 | path = [ cfg.workdir.gems cfg.workdir.gems.ruby pkgs.file pkgs.imagemagick ]; | ||
204 | |||
205 | preStart = '' | ||
206 | install -m 0755 -d ${cfg.dataDir}/tmp/cache | ||
207 | ./bin/bundle exec rails db:migrate | ||
208 | ''; | ||
209 | |||
210 | script = '' | ||
211 | exec ./bin/bundle exec puma -C config/puma.rb | ||
212 | ''; | ||
213 | |||
214 | postStart = '' | ||
215 | exec ./bin/tootctl cache clear | ||
216 | ''; | ||
217 | serviceConfig = { | ||
218 | Slice = "mastodon.slice"; | ||
219 | User = cfg.user; | ||
220 | EnvironmentFile = cfg.configFile; | ||
221 | PrivateTmp = true; | ||
222 | Restart = "always"; | ||
223 | TimeoutSec = 60; | ||
224 | Type = "simple"; | ||
225 | WorkingDirectory = cfg.workdir; | ||
226 | StateDirectory = cfg.systemdStateDirectory; | ||
227 | RuntimeDirectory = cfg.systemdRuntimeDirectory; | ||
228 | RuntimeDirectoryPreserve = "yes"; | ||
229 | }; | ||
230 | |||
231 | unitConfig.RequiresMountsFor = cfg.dataDir; | ||
232 | }; | ||
233 | |||
234 | # To be run manually because computationnally heavy | ||
235 | systemd.services.mastodon-cleanup-manual = { | ||
236 | description = "Cleanup mastodon"; | ||
237 | |||
238 | environment.RAILS_ENV = "production"; | ||
239 | environment.BUNDLE_PATH = "${cfg.workdir.gems}/${cfg.workdir.gems.ruby.gemPath}"; | ||
240 | environment.BUNDLE_GEMFILE = "${cfg.workdir.gems.confFiles}/Gemfile"; | ||
241 | environment.SOCKET = cfg.sockets.rails; | ||
242 | |||
243 | path = [ cfg.workdir.gems cfg.workdir.gems.ruby pkgs.file ]; | ||
244 | |||
245 | script = '' | ||
246 | exec ./bin/tootctl statuses remove --days 365 | ||
247 | ''; | ||
248 | |||
249 | serviceConfig = { | ||
250 | User = cfg.user; | ||
251 | EnvironmentFile = cfg.configFile; | ||
252 | PrivateTmp = true; | ||
253 | Type = "oneshot"; | ||
254 | WorkingDirectory = cfg.workdir; | ||
255 | StateDirectory = cfg.systemdStateDirectory; | ||
256 | RuntimeDirectory = cfg.systemdRuntimeDirectory; | ||
257 | RuntimeDirectoryPreserve = "yes"; | ||
258 | }; | ||
259 | |||
260 | unitConfig.RequiresMountsFor = cfg.dataDir; | ||
261 | }; | ||
262 | |||
263 | systemd.services.mastodon-cleanup = { | ||
264 | description = "Cleanup mastodon"; | ||
265 | startAt = "daily"; | ||
266 | restartIfChanged = false; | ||
267 | |||
268 | environment.RAILS_ENV = "production"; | ||
269 | environment.BUNDLE_PATH = "${cfg.workdir.gems}/${cfg.workdir.gems.ruby.gemPath}"; | ||
270 | environment.BUNDLE_GEMFILE = "${cfg.workdir.gems.confFiles}/Gemfile"; | ||
271 | environment.SOCKET = cfg.sockets.rails; | ||
272 | |||
273 | path = [ cfg.workdir.gems cfg.workdir.gems.ruby pkgs.file ]; | ||
274 | |||
275 | script = '' | ||
276 | exec ./bin/tootctl media remove --days 30 | ||
277 | ''; | ||
278 | |||
279 | serviceConfig = { | ||
280 | User = cfg.user; | ||
281 | EnvironmentFile = cfg.configFile; | ||
282 | PrivateTmp = true; | ||
283 | Type = "oneshot"; | ||
284 | WorkingDirectory = cfg.workdir; | ||
285 | StateDirectory = cfg.systemdStateDirectory; | ||
286 | RuntimeDirectory = cfg.systemdRuntimeDirectory; | ||
287 | RuntimeDirectoryPreserve = "yes"; | ||
288 | }; | ||
289 | |||
290 | unitConfig.RequiresMountsFor = cfg.dataDir; | ||
291 | }; | ||
292 | |||
293 | systemd.services.mastodon-sidekiq = { | ||
294 | description = "Mastodon Sidekiq"; | ||
295 | wantedBy = [ "multi-user.target" ]; | ||
296 | after = [ "network.target" "mastodon-web.service" ]; | ||
297 | |||
298 | environment.RAILS_ENV="production"; | ||
299 | environment.BUNDLE_PATH = "${cfg.workdir.gems}/${cfg.workdir.gems.ruby.gemPath}"; | ||
300 | environment.BUNDLE_GEMFILE = "${cfg.workdir.gems.confFiles}/Gemfile"; | ||
301 | environment.DB_POOL="5"; | ||
302 | |||
303 | path = [ cfg.workdir.gems cfg.workdir.gems.ruby pkgs.imagemagick pkgs.ffmpeg pkgs.file ]; | ||
304 | |||
305 | script = '' | ||
306 | exec ./bin/bundle exec sidekiq -c 5 -q default -q mailers -q pull -q push | ||
307 | ''; | ||
308 | |||
309 | serviceConfig = { | ||
310 | Slice = "mastodon.slice"; | ||
311 | User = cfg.user; | ||
312 | EnvironmentFile = cfg.configFile; | ||
313 | PrivateTmp = true; | ||
314 | Restart = "always"; | ||
315 | TimeoutSec = 15; | ||
316 | Type = "simple"; | ||
317 | WorkingDirectory = cfg.workdir; | ||
318 | StateDirectory = cfg.systemdStateDirectory; | ||
319 | RuntimeDirectory = cfg.systemdRuntimeDirectory; | ||
320 | RuntimeDirectoryPreserve = "yes"; | ||
321 | }; | ||
322 | |||
323 | unitConfig.RequiresMountsFor = cfg.dataDir; | ||
324 | }; | ||
325 | |||
326 | }; | ||
327 | }; | ||
328 | }; | ||
329 | } | ||
330 | |||
331 | |||