]>
Commit | Line | Data |
---|---|---|
35a397cd IB |
1 | { lib, pkgs, config, mylibs, ... }: |
2 | let | |
3 | mastodon = pkgs.callPackage ./mastodon.nix { | |
4 | inherit (mylibs) fetchedGithub checkEnv; | |
5 | }; | |
6 | ||
7 | cfg = config.services.myWebsites.tools.mastodon; | |
8 | in { | |
9 | options.services.myWebsites.tools.mastodon = { | |
10 | enable = lib.mkEnableOption "enable mastodon's website"; | |
11 | }; | |
12 | ||
13 | config = lib.mkIf cfg.enable { | |
14 | # FIXME: Can we use dynamic users from systemd? | |
15 | # nixos/modules/misc/ids.nix | |
16 | ids.uids.mastodon = 399; | |
17 | ids.gids.mastodon = 399; | |
18 | ||
19 | users.users.mastodon = { | |
20 | name = "mastodon"; | |
21 | uid = config.ids.uids.mastodon; | |
22 | group = "mastodon"; | |
23 | description = "Mastodon user"; | |
24 | home = "${mastodon.railsRoot}"; | |
25 | useDefaultShell = true; | |
26 | }; | |
27 | ||
28 | users.groups.mastodon.gid = config.ids.gids.mastodon; | |
29 | ||
30 | systemd.services.mastodon-streaming = { | |
31 | description = "Mastodon Streaming"; | |
32 | wantedBy = [ "multi-user.target" ]; | |
33 | after = [ "network.target" "mastodon-web.service" ]; | |
34 | ||
35 | environment.NODE_ENV = "production"; | |
36 | environment.SOCKET = mastodon.nodeSocket; | |
37 | ||
38 | path = [ pkgs.nodejs pkgs.bashInteractive ]; | |
39 | ||
40 | script = '' | |
41 | exec npm run start | |
42 | ''; | |
43 | ||
44 | postStart = '' | |
45 | while [ ! -S $SOCKET ]; do | |
46 | sleep 0.5 | |
47 | done | |
48 | chmod a+w $SOCKET | |
49 | ''; | |
50 | ||
51 | postStop = '' | |
52 | rm $SOCKET | |
53 | ''; | |
54 | ||
55 | serviceConfig = { | |
56 | User = "mastodon"; | |
57 | EnvironmentFile = mastodon.config; | |
58 | PrivateTmp = true; | |
59 | Restart = "always"; | |
60 | TimeoutSec = 15; | |
61 | Type = "simple"; | |
62 | WorkingDirectory = mastodon.railsRoot; | |
63 | }; | |
64 | ||
65 | unitConfig.RequiresMountsFor = mastodon.varDir; | |
66 | }; | |
67 | ||
68 | systemd.services.mastodon-web = { | |
69 | description = "Mastodon Web app"; | |
70 | wantedBy = [ "multi-user.target" ]; | |
71 | after = [ "network.target" ]; | |
72 | ||
73 | environment.RAILS_ENV = "production"; | |
74 | environment.SOCKET = mastodon.railsSocket; | |
75 | ||
76 | path = [ pkgs.bundler ]; | |
77 | ||
78 | preStart = '' | |
79 | bundle exec rails db:migrate | |
80 | ''; | |
81 | ||
82 | script = '' | |
83 | exec bundle exec puma -C config/puma.rb | |
84 | ''; | |
85 | ||
86 | serviceConfig = { | |
87 | User = "mastodon"; | |
88 | EnvironmentFile = mastodon.config; | |
89 | PrivateTmp = true; | |
90 | Restart = "always"; | |
91 | TimeoutSec = 15; | |
92 | Type = "simple"; | |
93 | WorkingDirectory = mastodon.railsRoot; | |
94 | }; | |
95 | ||
96 | unitConfig.RequiresMountsFor = mastodon.varDir; | |
97 | }; | |
98 | ||
99 | systemd.services.mastodon-sidekiq = { | |
100 | description = "Mastodon Sidekiq"; | |
101 | wantedBy = [ "multi-user.target" ]; | |
102 | after = [ "network.target" "mastodon-web.service" ]; | |
103 | ||
104 | environment.RAILS_ENV="production"; | |
105 | environment.DB_POOL="5"; | |
106 | ||
107 | path = [ pkgs.bundler ]; | |
108 | ||
109 | script = '' | |
110 | exec bundle exec sidekiq -c 5 -q default -q mailers -q pull -q push | |
111 | ''; | |
112 | ||
113 | serviceConfig = { | |
114 | User = "mastodon"; | |
115 | EnvironmentFile = mastodon.config; | |
116 | PrivateTmp = true; | |
117 | Restart = "always"; | |
118 | TimeoutSec = 15; | |
119 | Type = "simple"; | |
120 | WorkingDirectory = mastodon.railsRoot; | |
121 | }; | |
122 | ||
123 | unitConfig.RequiresMountsFor = mastodon.varDir; | |
124 | }; | |
125 | ||
126 | # FIXME: initial sync | |
127 | system.activationScripts.mastodon = { | |
128 | deps = [ "users" ]; | |
129 | text = '' | |
130 | install -m 0755 -o mastodon -g mastodon -d ${mastodon.socketsDir} | |
131 | install -m 0755 -o mastodon -g mastodon -d ${mastodon.varDir} | |
132 | ''; | |
133 | }; | |
134 | ||
135 | services.myWebsites.tools.modules = [ | |
136 | "headers" "proxy" "proxy_wstunnel" "proxy_http" "proxy_balancer" | |
137 | # FIXME: probably only one balancer method is needed: | |
138 | "lbmethod_byrequests" "lbmethod_bytraffic" "lbmethod_bybusyness" "lbmethod_heartbeat" | |
139 | ]; | |
140 | security.acme.certs."eldiron".extraDomains."mastodon.immae.eu" = null; | |
141 | services.myWebsites.tools.vhostConfs.mastodon = { | |
142 | certName = "eldiron"; | |
143 | hosts = ["mastodon.immae.eu" ]; | |
144 | root = "${mastodon.railsRoot}/public/"; | |
145 | extraConfig = [ '' | |
146 | Header always set Referrer-Policy "strict-origin-when-cross-origin" | |
147 | Header always set Strict-Transport-Security "max-age=31536000" | |
148 | ||
149 | <LocationMatch "^/(assets|avatars|emoji|headers|packs|sounds|system)> | |
150 | Header always set Cache-Control "public, max-age=31536000, immutable" | |
151 | Require all granted | |
152 | </LocationMatch> | |
153 | ||
154 | ProxyPreserveHost On | |
155 | RequestHeader set X-Forwarded-Proto "https" | |
156 | ||
157 | RewriteEngine On | |
158 | ||
159 | ProxyPass /500.html ! | |
160 | ProxyPass /sw.js ! | |
161 | ProxyPass /embed.js ! | |
162 | ProxyPass /robots.txt ! | |
163 | ProxyPass /manifest.json ! | |
164 | ProxyPass /browserconfig.xml ! | |
165 | ProxyPass /mask-icon.svg ! | |
166 | ProxyPassMatch ^(/.*\.(png|ico|gif)$) ! | |
167 | ProxyPassMatch ^/(assets|avatars|emoji|headers|packs|sounds|system|.well-known/acme-challenge) ! | |
168 | ||
169 | ProxyPassMatch /api/v1/streaming/(.+)$ balancer://node_servers_http/api/v1/streaming/$1 | |
170 | ProxyPass /api/v1/streaming/ balancer://node_servers/ | |
171 | ProxyPassReverse /api/v1/streaming/ balancer://node_servers/ | |
172 | ProxyPass / balancer://puma_servers/ | |
173 | ProxyPassReverse / balancer://puma_servers/ | |
174 | ||
175 | <Proxy balancer://puma_servers> | |
176 | BalancerMember unix://${mastodon.railsSocket}|http:// | |
177 | </Proxy> | |
178 | ||
179 | <Proxy balancer://node_servers> | |
180 | BalancerMember unix://${mastodon.nodeSocket}|ws://localhost | |
181 | </Proxy> | |
182 | ||
183 | <Proxy balancer://node_servers_http> | |
184 | BalancerMember unix://${mastodon.nodeSocket}|http://localhost | |
185 | </Proxy> | |
186 | ||
187 | Alias /system ${mastodon.varDir} | |
188 | ||
189 | <Directory ${mastodon.varDir}> | |
190 | Require all granted | |
191 | Options -MultiViews | |
192 | </Directory> | |
193 | ||
194 | <Directory ${mastodon.railsRoot}/public/> | |
195 | Require all granted | |
196 | Options -MultiViews +FollowSymlinks | |
197 | </Directory> | |
198 | ||
199 | ErrorDocument 500 /500.html | |
200 | ErrorDocument 501 /500.html | |
201 | ErrorDocument 502 /500.html | |
202 | ErrorDocument 503 /500.html | |
203 | ErrorDocument 504 /500.html | |
204 | '' ]; | |
205 | }; | |
206 | }; | |
207 | } |