]> Git — Sourcephile - sourcephile-nix.git/blob - hosts/mermet/pleroma.nix
mermet: knot: change dnssec-policy to ed25519
[sourcephile-nix.git] / hosts / mermet / pleroma.nix
1 { pkgs, lib, config, ... }:
2 let
3 domain = "autogeree.net";
4 srv = "pleroma";
5 owner = "${srv}-${domain}";
6 db = "${srv}-${domain}";
7 port = 4000;
8 inherit (config.services) postgresql;
9 inherit (config.users) groups;
10
11 # pleroma_ctl instance gen
12 # https://git.pleroma.social/pleroma/pleroma/blob/develop/config/config.exs
13 pleroma-conf = ''
14 import Config
15
16 config :pleroma, Pleroma.Web.Endpoint,
17 url: [host: "${srv}.${domain}", scheme: "https", port: 443],
18 http: [ip: {127, 0, 0, 1}, port: ${toString port}]
19
20 config :pleroma, :http_security,
21 sts: true
22
23 config :pleroma, Pleroma.Web.WebFinger, domain: "${domain}"
24
25 # RELEASE_COOKIE="/var/lib/pleroma/.cookie" \
26 # pleroma_ctl user new $user $user+pleroma@autogeree.net --password "$password" --moderator --admin -y
27 config :pleroma, :instance,
28 name: "${domain}",
29 email: "root+${srv}@${domain}",
30 notify_email: "root+${srv}@${domain}",
31 limit: 5000,
32 registrations_open: false,
33 invites_enabled: true,
34 description: "Pleroma: An efficient and flexible fediverse server",
35 short_description: "",
36 background_image: "/images/city.jpg",
37 instance_thumbnail: "/instance/thumbnail.jpeg",
38 max_pinned_statuses: 4
39
40 config :pleroma, :media_proxy,
41 enabled: false,
42 redirect_on_failure: true
43 #base_url: "https://cache.pleroma.social"
44
45 config :pleroma, :markup,
46 allow_inline_images: true,
47 allow_headings: true,
48 allow_tables: true
49
50 # pleroma_ctl email test --to julm+pleroma@autogeree.net
51 config :pleroma, Pleroma.Emails.Mailer, [
52 adapter: Swoosh.Adapters.Sendmail,
53 enabled: true,
54 cmd_path: "/run/wrappers/bin/sendmail",
55 cmd_args: ""
56 ]
57
58 config :pleroma, :dangerzone,
59 override_repo_pool_size: true
60
61 config :pleroma, Pleroma.Repo,
62 adapter: Ecto.Adapters.Postgres,
63 username: "${owner}",
64 socket_dir: "/run/postgresql",
65 database: "${db}",
66 pool_size: 5,
67 # Database task queue timeout to avoid timeouts on the front end
68 # due to a slow postgresql, eg. because of a CPUQuota= hardening.
69 queue_target: 20_000,
70 queue_interval: 1_000,
71 ownership_timeout: 20_000,
72 timeout: 40_000,
73 prepare: :named,
74 # https://docs-develop.pleroma.social/backend/configuration/postgresql/#disable-generic-query-plans
75 parameters: [
76 plan_cache_mode: "force_custom_plan"
77 ]
78
79 config :pleroma, :database, rum_enabled: false
80 config :pleroma, :instance, static_dir: "/var/lib/${srv}/static"
81 config :pleroma, Pleroma.Uploaders.Local, uploads: "/var/lib/${srv}/uploads"
82 config :pleroma, configurable_from_database: false
83 config :pleroma, Pleroma.Upload, filters: [
84 Pleroma.Upload.Filter.Exiftool.StripLocation,
85 Pleroma.Upload.Filter.Exiftool.ReadDescription
86 ]
87
88 # https://docs-develop.pleroma.social/backend/configuration/howto_proxy/
89 #config :pleroma, :http, proxy_url: {:socks5, :localhost, 9050}
90 config :pleroma, :mrf,
91 policies: [
92 Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy,
93 Pleroma.Web.ActivityPub.MRF.TagPolicy,
94 Pleroma.Web.ActivityPub.MRF.SimplePolicy
95 ]
96
97 config :pleroma, :media_proxy,
98 enabled: true,
99 proxy_opts: [
100 redirect_on_failure: true
101 ];
102 '';
103 in
104 {
105 services = {
106 pleroma = {
107 enable = true;
108 configs = [ pleroma-conf ];
109 secretConfigFile = "/run/credentials/${srv}.service/config.exs";
110 };
111 nginx = {
112 enable = true;
113 upstreams.${srv} = {
114 servers."127.0.0.1:${toString port}" = {
115 max_fails = 5;
116 fail_timeout = "60s";
117 };
118 extraConfig = ''
119 '';
120 };
121 proxyCachePath."${domain}/${srv}/proxy" = {
122 enable = true;
123 inactive = "720m";
124 keysZoneName = "${domain}/${srv}/proxy";
125 keysZoneSize = "10m";
126 levels = "1:2";
127 maxSize = "10g";
128 useTempPath = false;
129 };
130
131 virtualHosts.${domain} = {
132 locations."/.well-known/host-meta" = {
133 return = "301 https://${srv}.${domain}$request_uri";
134 };
135 };
136 virtualHosts."${srv}.${domain}" = {
137 forceSSL = true;
138 useACMEHost = domain;
139 extraConfig = ''
140 access_log /var/log/nginx/${domain}/${srv}/access.log json buffer=32k;
141 error_log /var/log/nginx/${domain}/${srv}/error.log;
142 '';
143 locations."/" = {
144 proxyPass = "http://${srv}";
145 extraConfig = ''
146 add_header 'Access-Control-Allow-Origin' '*' always;
147 add_header 'Access-Control-Allow-Methods' 'POST, PUT, DELETE, GET, PATCH, OPTIONS' always;
148 add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Idempotency-Key' always;
149 add_header 'Access-Control-Expose-Headers' 'Link, X-RateLimit-Reset, X-RateLimit-Limit, X-RateLimit-Remaining, X-Request-Id' always;
150 if ($request_method = OPTIONS) {
151 return 204;
152 }
153 add_header Referrer-Policy same-origin;
154 add_header X-Content-Type-Options nosniff;
155 add_header X-Download-Options noopen;
156 add_header X-Frame-Options DENY;
157 add_header X-Permitted-Cross-Domain-Policies none;
158 add_header X-XSS-Protection "1; mode=block";
159 client_max_body_size 16m;
160 proxy_connect_timeout 90;
161 proxy_http_version 1.1;
162 proxy_read_timeout 90;
163 proxy_redirect off;
164 proxy_send_timeout 90;
165 proxy_set_header Connection "upgrade";
166 proxy_set_header Upgrade $http_upgrade;
167 '';
168 };
169 locations."/proxy" = {
170 proxyPass = "http://${srv}";
171 extraConfig = ''
172 proxy_cache ${domain}/${srv}/proxy;
173 proxy_cache_lock on;
174 proxy_ignore_client_abort on;
175 '';
176 };
177 };
178 };
179 postgresql = {
180 identMap = ''
181 # MAPNAME SYSTEM-USERNAME PG-USERNAME
182 user root ${owner}
183 user ${srv} ${owner}
184 '';
185 };
186 sanoid.datasets."rpool/var/lib/${srv}" = {
187 use_template = [ "snap" ];
188 daily = 31;
189 monthly = 3;
190 recursive = true;
191 };
192 };
193 systemd.services = {
194 nginx = {
195 serviceConfig = {
196 LogsDirectory = lib.mkForce [ "nginx/${domain}/${srv}" ];
197 };
198 };
199 pleroma = {
200 path = [
201 pkgs.exiftool
202 # For RELEASE_COOKIE
203 pkgs.hexdump
204 # For rand()
205 pkgs.gawk
206 ];
207 environment.RELEASE_VM_ARGS = pkgs.writeText "vm.args" ''
208 # Disable the busy-waiting.
209 # https://docs-develop.pleroma.social/backend/configuration/optimizing_beam/#virtual-machine-andor-few-cpu-cores
210 +sbwt none
211 +sbwtdcpu none
212 +sbwtdio none
213 '';
214 unitConfig = {
215 StartLimitBurst = 5;
216 StartLimitIntervalSec = "600s";
217 };
218 serviceConfig = {
219 LoadCredentialEncrypted = [ "config.exs:${./pleroma/config.exs.cred}" ];
220 SupplementaryGroups = [ groups."postgres".name ];
221 TimeoutStopSec = "10s";
222 Restart = "on-failure";
223 RestartSec = "10s";
224 MemoryAccounting = true;
225 MemoryHigh = "500M";
226 MemoryMax = "600M";
227 # For sendmail
228 NoNewPrivileges = lib.mkForce false;
229 };
230 };
231 postgresql = {
232 postStart = lib.mkAfter ''
233 connection_limit=64 \
234 encoding=UTF8 \
235 lc_collate=fr_FR.UTF-8 \
236 lc_type=fr_FR.UTF-8 \
237 owner="${owner}" \
238 pass="" \
239 pg_createdb "${db}" >/dev/null
240 pg_adduser "${db}" "${owner}" >/dev/null
241
242 $PSQL -d "${db}" -AqtX --set ON_ERROR_STOP=1 -f - <<EOF
243 --Extensions made by ecto.migrate that need superuser access
244 CREATE EXTENSION IF NOT EXISTS citext;
245 CREATE EXTENSION IF NOT EXISTS pg_trgm;
246 CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
247 EOF
248 '';
249 };
250 };
251 }