]>
Commit | Line | Data |
---|---|---|
613aea56 IB |
1 | { lib, pkgs, config, ... }: |
2 | let | |
3 | name = "mastodon"; | |
4 | cfg = config.services.mastodon; | |
5 | ||
6 | uid = config.ids.uids.mastodon; | |
7 | gid = config.ids.gids.mastodon; | |
8 | in | |
9 | { | |
10 | options.services.mastodon = { | |
11 | enable = lib.mkEnableOption "Enable Mastodon’s service"; | |
12 | user = lib.mkOption { | |
13 | type = lib.types.str; | |
14 | default = name; | |
15 | description = "User account under which Mastodon runs"; | |
16 | }; | |
17 | group = lib.mkOption { | |
18 | type = lib.types.str; | |
19 | default = name; | |
20 | description = "Group under which Mastodon runs"; | |
21 | }; | |
22 | dataDir = lib.mkOption { | |
23 | type = lib.types.path; | |
24 | default = "/var/lib/${name}"; | |
25 | description = '' | |
26 | The directory where Mastodon stores its data. | |
27 | ''; | |
28 | }; | |
29 | socketsPrefix = lib.mkOption { | |
30 | type = lib.types.string; | |
31 | default = "live"; | |
32 | description = '' | |
33 | The prefix to use for Mastodon sockets. | |
34 | ''; | |
35 | }; | |
36 | socketsDir = lib.mkOption { | |
37 | type = lib.types.path; | |
38 | default = "/run/${name}"; | |
39 | description = '' | |
40 | The directory where Mastodon puts runtime files and sockets. | |
41 | ''; | |
42 | }; | |
43 | configFile = lib.mkOption { | |
44 | type = lib.types.path; | |
45 | description = '' | |
46 | The configuration file path for Mastodon. | |
47 | ''; | |
48 | }; | |
49 | package = lib.mkOption { | |
50 | type = lib.types.package; | |
51 | default = pkgs.webapps.mastodon; | |
52 | description = '' | |
53 | Mastodon package to use. | |
54 | ''; | |
55 | }; | |
56 | # Output variables | |
57 | workdir = lib.mkOption { | |
58 | type = lib.types.package; | |
59 | default = cfg.package.override { varDir = cfg.dataDir; }; | |
60 | description = '' | |
61 | Adjusted mastodon package with overriden varDir | |
62 | ''; | |
63 | readOnly = true; | |
64 | }; | |
65 | sockets = lib.mkOption { | |
66 | type = lib.types.attrsOf lib.types.path; | |
67 | default = { | |
68 | node = "${cfg.socketsDir}/${cfg.socketsPrefix}_node.sock"; | |
69 | rails = "${cfg.socketsDir}/${cfg.socketsPrefix}_puma.sock"; | |
70 | }; | |
71 | readOnly = true; | |
72 | description = '' | |
73 | Mastodon sockets | |
74 | ''; | |
75 | }; | |
76 | }; | |
77 | ||
78 | config = lib.mkIf cfg.enable { | |
79 | users.users = lib.optionalAttrs (cfg.user == name) (lib.singleton { | |
80 | inherit name; | |
81 | inherit uid; | |
82 | group = cfg.group; | |
83 | description = "Mastodon user"; | |
84 | home = cfg.dataDir; | |
85 | useDefaultShell = true; | |
86 | }); | |
87 | users.groups = lib.optionalAttrs (cfg.group == name) (lib.singleton { | |
88 | inherit name; | |
89 | inherit gid; | |
90 | }); | |
91 | ||
92 | systemd.services.mastodon-streaming = { | |
93 | description = "Mastodon Streaming"; | |
94 | wantedBy = [ "multi-user.target" ]; | |
95 | after = [ "network.target" "mastodon-web.service" ]; | |
96 | ||
97 | environment.NODE_ENV = "production"; | |
98 | environment.SOCKET = cfg.sockets.node; | |
99 | ||
100 | path = [ pkgs.nodejs pkgs.bashInteractive ]; | |
101 | ||
102 | script = '' | |
103 | exec npm run start | |
104 | ''; | |
105 | ||
106 | postStart = '' | |
107 | while [ ! -S $SOCKET ]; do | |
108 | sleep 0.5 | |
109 | done | |
110 | chmod a+w $SOCKET | |
111 | ''; | |
112 | ||
113 | postStop = '' | |
114 | rm $SOCKET | |
115 | ''; | |
116 | ||
117 | serviceConfig = { | |
118 | User = cfg.user; | |
119 | EnvironmentFile = cfg.configFile; | |
120 | PrivateTmp = true; | |
121 | Restart = "always"; | |
122 | TimeoutSec = 15; | |
123 | Type = "simple"; | |
124 | WorkingDirectory = cfg.workdir; | |
125 | }; | |
126 | ||
127 | unitConfig.RequiresMountsFor = cfg.dataDir; | |
128 | }; | |
129 | ||
130 | systemd.services.mastodon-web = { | |
131 | description = "Mastodon Web app"; | |
132 | wantedBy = [ "multi-user.target" ]; | |
133 | after = [ "network.target" ]; | |
134 | ||
135 | environment.RAILS_ENV = "production"; | |
136 | environment.BUNDLE_PATH = "${cfg.workdir.gems}/${cfg.workdir.gems.ruby.gemPath}"; | |
137 | environment.BUNDLE_GEMFILE = "${cfg.workdir.gems.confFiles}/Gemfile"; | |
138 | environment.SOCKET = cfg.sockets.rails; | |
139 | ||
140 | path = [ cfg.workdir.gems cfg.workdir.gems.ruby pkgs.file ]; | |
141 | ||
142 | preStart = '' | |
143 | ./bin/bundle exec rails db:migrate | |
144 | ''; | |
145 | ||
146 | script = '' | |
147 | exec ./bin/bundle exec puma -C config/puma.rb | |
148 | ''; | |
149 | ||
150 | serviceConfig = { | |
151 | User = cfg.user; | |
152 | EnvironmentFile = cfg.configFile; | |
153 | PrivateTmp = true; | |
154 | Restart = "always"; | |
155 | TimeoutSec = 60; | |
156 | Type = "simple"; | |
157 | WorkingDirectory = cfg.workdir; | |
158 | }; | |
159 | ||
160 | unitConfig.RequiresMountsFor = cfg.dataDir; | |
161 | }; | |
162 | ||
163 | systemd.services.mastodon-sidekiq = { | |
164 | description = "Mastodon Sidekiq"; | |
165 | wantedBy = [ "multi-user.target" ]; | |
166 | after = [ "network.target" "mastodon-web.service" ]; | |
167 | ||
168 | environment.RAILS_ENV="production"; | |
169 | environment.BUNDLE_PATH = "${cfg.workdir.gems}/${cfg.workdir.gems.ruby.gemPath}"; | |
170 | environment.BUNDLE_GEMFILE = "${cfg.workdir.gems.confFiles}/Gemfile"; | |
171 | environment.DB_POOL="5"; | |
172 | ||
173 | path = [ cfg.workdir.gems cfg.workdir.gems.ruby pkgs.imagemagick pkgs.ffmpeg pkgs.file ]; | |
174 | ||
175 | script = '' | |
176 | exec ./bin/bundle exec sidekiq -c 5 -q default -q mailers -q pull -q push | |
177 | ''; | |
178 | ||
179 | serviceConfig = { | |
180 | User = cfg.user; | |
181 | EnvironmentFile = cfg.configFile; | |
182 | PrivateTmp = true; | |
183 | Restart = "always"; | |
184 | TimeoutSec = 15; | |
185 | Type = "simple"; | |
186 | WorkingDirectory = cfg.workdir; | |
187 | }; | |
188 | ||
189 | unitConfig.RequiresMountsFor = cfg.dataDir; | |
190 | }; | |
191 | ||
192 | system.activationScripts.mastodon = { | |
193 | deps = [ "users" ]; | |
194 | text = '' | |
195 | install -m 0755 -o ${cfg.user} -g ${cfg.group} -d ${cfg.socketsDir} | |
196 | install -m 0755 -o ${cfg.user} -g ${cfg.group} -d ${cfg.dataDir} ${cfg.dataDir}/tmp/cache | |
197 | ''; | |
198 | }; | |
199 | ||
200 | }; | |
201 | } |