grafana-alloy: don't build the frontend twice
[NixPkgs.git] / nixos / modules / services / web-apps / akkoma.md
blob13b074b228a4187b60d1e1a8ad0c6860a167e5fa
1 # Akkoma {#module-services-akkoma}
3 [Akkoma](https://akkoma.dev/) is a lightweight ActivityPub microblogging server forked from Pleroma.
5 ## Service configuration {#modules-services-akkoma-service-configuration}
7 The Elixir configuration file required by Akkoma is generated automatically from
8 [{option}`services.akkoma.config`](options.html#opt-services.akkoma.config). Secrets must be
9 included from external files outside of the Nix store by setting the configuration option to
10 an attribute set containing the attribute {option}`_secret` – a string pointing to the file
11 containing the actual value of the option.
13 For the mandatory configuration settings these secrets will be generated automatically if the
14 referenced file does not exist during startup, unless disabled through
15 [{option}`services.akkoma.initSecrets`](options.html#opt-services.akkoma.initSecrets).
17 The following configuration binds Akkoma to the Unix socket `/run/akkoma/socket`, expecting to
18 be run behind a HTTP proxy on `fediverse.example.com`.
21 ```nix
23   services.akkoma.enable = true;
24   services.akkoma.config = {
25     ":pleroma" = {
26       ":instance" = {
27         name = "My Akkoma instance";
28         description = "More detailed description";
29         email = "admin@example.com";
30         registration_open = false;
31       };
33       "Pleroma.Web.Endpoint" = {
34         url.host = "fediverse.example.com";
35       };
36     };
37   };
39 ```
41 Please refer to the [configuration cheat sheet](https://docs.akkoma.dev/stable/configuration/cheatsheet/)
42 for additional configuration options.
44 ## User management {#modules-services-akkoma-user-management}
46 After the Akkoma service is running, the administration utility can be used to
47 [manage users](https://docs.akkoma.dev/stable/administration/CLI_tasks/user/). In particular an
48 administrative user can be created with
50 ```ShellSession
51 $ pleroma_ctl user new <nickname> <email> --admin --moderator --password <password>
52 ```
54 ## Proxy configuration {#modules-services-akkoma-proxy-configuration}
56 Although it is possible to expose Akkoma directly, it is common practice to operate it behind an
57 HTTP reverse proxy such as nginx.
59 ```nix
61   services.akkoma.nginx = {
62     enableACME = true;
63     forceSSL = true;
64   };
66   services.nginx = {
67     enable = true;
69     clientMaxBodySize = "16m";
70     recommendedTlsSettings = true;
71     recommendedOptimisation = true;
72     recommendedGzipSettings = true;
73   };
75 ```
77 Please refer to [](#module-security-acme) for details on how to provision an SSL/TLS certificate.
79 ### Media proxy {#modules-services-akkoma-media-proxy}
81 Without the media proxy function, Akkoma does not store any remote media like pictures or video
82 locally, and clients have to fetch them directly from the source server.
84 ```nix
86   # Enable nginx slice module distributed with Tengine
87   services.nginx.package = pkgs.tengine;
89   # Enable media proxy
90   services.akkoma.config.":pleroma".":media_proxy" = {
91     enabled = true;
92     proxy_opts.redirect_on_failure = true;
93   };
95   # Adjust the persistent cache size as needed:
96   #  Assuming an average object size of 128 KiB, around 1 MiB
97   #  of memory is required for the key zone per GiB of cache.
98   # Ensure that the cache directory exists and is writable by nginx.
99   services.nginx.commonHttpConfig = ''
100     proxy_cache_path /var/cache/nginx/cache/akkoma-media-cache
101       levels= keys_zone=akkoma_media_cache:16m max_size=16g
102       inactive=1y use_temp_path=off;
103   '';
105   services.akkoma.nginx = {
106     locations."/proxy" = {
107       proxyPass = "http://unix:/run/akkoma/socket";
109       extraConfig = ''
110         proxy_cache akkoma_media_cache;
112         # Cache objects in slices of 1 MiB
113         slice 1m;
114         proxy_cache_key $host$uri$is_args$args$slice_range;
115         proxy_set_header Range $slice_range;
117         # Decouple proxy and upstream responses
118         proxy_buffering on;
119         proxy_cache_lock on;
120         proxy_ignore_client_abort on;
122         # Default cache times for various responses
123         proxy_cache_valid 200 1y;
124         proxy_cache_valid 206 301 304 1h;
126         # Allow serving of stale items
127         proxy_cache_use_stale error timeout invalid_header updating;
128       '';
129     };
130   };
134 #### Prefetch remote media {#modules-services-akkoma-prefetch-remote-media}
136 The following example enables the `MediaProxyWarmingPolicy` MRF policy which automatically
137 fetches all media associated with a post through the media proxy, as soon as the post is
138 received by the instance.
140 ```nix
142   services.akkoma.config.":pleroma".":mrf".policies =
143     map (pkgs.formats.elixirConf { }).lib.mkRaw [
144       "Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy"
145   ];
149 #### Media previews {#modules-services-akkoma-media-previews}
151 Akkoma can generate previews for media.
153 ```nix
155   services.akkoma.config.":pleroma".":media_preview_proxy" = {
156     enabled = true;
157     thumbnail_max_width = 1920;
158     thumbnail_max_height = 1080;
159   };
163 ## Frontend management {#modules-services-akkoma-frontend-management}
165 Akkoma will be deployed with the `akkoma-fe` and `admin-fe` frontends by default. These can be
166 modified by setting
167 [{option}`services.akkoma.frontends`](options.html#opt-services.akkoma.frontends).
169 The following example overrides the primary frontend’s default configuration using a custom
170 derivation.
172 ```nix
174   services.akkoma.frontends.primary.package = pkgs.runCommand "akkoma-fe" {
175     config = builtins.toJSON {
176       expertLevel = 1;
177       collapseMessageWithSubject = false;
178       stopGifs = false;
179       replyVisibility = "following";
180       webPushHideIfCW = true;
181       hideScopeNotice = true;
182       renderMisskeyMarkdown = false;
183       hideSiteFavicon = true;
184       postContentType = "text/markdown";
185       showNavShortcuts = false;
186     };
187     nativeBuildInputs = with pkgs; [ jq xorg.lndir ];
188     passAsFile = [ "config" ];
189   } ''
190     mkdir $out
191     lndir ${pkgs.akkoma-frontends.akkoma-fe} $out
193     rm $out/static/config.json
194     jq -s add ${pkgs.akkoma-frontends.akkoma-fe}/static/config.json ${config} \
195       >$out/static/config.json
196   '';
200 ## Federation policies {#modules-services-akkoma-federation-policies}
202 Akkoma comes with a number of modules to police federation with other ActivityPub instances.
203 The most valuable for typical users is the
204 [`:mrf_simple`](https://docs.akkoma.dev/stable/configuration/cheatsheet/#mrf_simple) module
205 which allows limiting federation based on instance hostnames.
207 This configuration snippet provides an example on how these can be used. Choosing an adequate
208 federation policy is not trivial and entails finding a balance between connectivity to the rest
209 of the fediverse and providing a pleasant experience to the users of an instance.
212 ```nix
214   services.akkoma.config.":pleroma" = with (pkgs.formats.elixirConf { }).lib; {
215     ":mrf".policies = map mkRaw [
216       "Pleroma.Web.ActivityPub.MRF.SimplePolicy"
217     ];
219     ":mrf_simple" = {
220       # Tag all media as sensitive
221       media_nsfw = mkMap {
222         "nsfw.weird.kinky" = "Untagged NSFW content";
223       };
225       # Reject all activities except deletes
226       reject = mkMap {
227         "kiwifarms.cc" = "Persistent harassment of users, no moderation";
228       };
230       # Force posts to be visible by followers only
231       followers_only = mkMap {
232         "beta.birdsite.live" = "Avoid polluting timelines with Twitter posts";
233       };
234     };
235   };
239 ## Upload filters {#modules-services-akkoma-upload-filters}
241 This example strips GPS and location metadata from uploads, deduplicates them and anonymises the
242 the file name.
244 ```nix
246   services.akkoma.config.":pleroma"."Pleroma.Upload".filters =
247     map (pkgs.formats.elixirConf { }).lib.mkRaw [
248       "Pleroma.Upload.Filter.Exiftool"
249       "Pleroma.Upload.Filter.Dedupe"
250       "Pleroma.Upload.Filter.AnonymizeFilename"
251     ];
255 ## Migration from Pleroma {#modules-services-akkoma-migration-pleroma}
257 Pleroma instances can be migrated to Akkoma either by copying the database and upload data or by
258 pointing Akkoma to the existing data. The necessary database migrations are run automatically
259 during startup of the service.
261 The configuration has to be copy‐edited manually.
263 Depending on the size of the database, the initial migration may take a long time and exceed the
264 startup timeout of the system manager. To work around this issue one may adjust the startup timeout
265 {option}`systemd.services.akkoma.serviceConfig.TimeoutStartSec` or simply run the migrations
266 manually:
268 ```ShellSession
269 pleroma_ctl migrate
272 ### Copying data {#modules-services-akkoma-migration-pleroma-copy}
274 Copying the Pleroma data instead of re‐using it in place may permit easier reversion to Pleroma,
275 but allows the two data sets to diverge.
277 First disable Pleroma and then copy its database and upload data:
279 ```ShellSession
280 # Create a copy of the database
281 nix-shell -p postgresql --run 'createdb -T pleroma akkoma'
283 # Copy upload data
284 mkdir /var/lib/akkoma
285 cp -R --reflink=auto /var/lib/pleroma/uploads /var/lib/akkoma/
288 After the data has been copied, enable the Akkoma service and verify that the migration has been
289 successful. If no longer required, the original data may then be deleted:
291 ```ShellSession
292 # Delete original database
293 nix-shell -p postgresql --run 'dropdb pleroma'
295 # Delete original Pleroma state
296 rm -r /var/lib/pleroma
299 ### Re‐using data {#modules-services-akkoma-migration-pleroma-reuse}
301 To re‐use the Pleroma data in place, disable Pleroma and enable Akkoma, pointing it to the
302 Pleroma database and upload directory.
304 ```nix
306   # Adjust these settings according to the database name and upload directory path used by Pleroma
307   services.akkoma.config.":pleroma"."Pleroma.Repo".database = "pleroma";
308   services.akkoma.config.":pleroma".":instance".upload_dir = "/var/lib/pleroma/uploads";
312 Please keep in mind that after the Akkoma service has been started, any migrations applied by
313 Akkoma have to be rolled back before the database can be used again with Pleroma. This can be
314 achieved through `pleroma_ctl ecto.rollback`. Refer to the
315 [Ecto SQL documentation](https://hexdocs.pm/ecto_sql/Mix.Tasks.Ecto.Rollback.html) for
316 details.
318 ## Advanced deployment options {#modules-services-akkoma-advanced-deployment}
320 ### Confinement {#modules-services-akkoma-confinement}
322 The Akkoma systemd service may be confined to a chroot with
324 ```nix
326   services.systemd.akkoma.confinement.enable = true;
330 Confinement of services is not generally supported in NixOS and therefore disabled by default.
331 Depending on the Akkoma configuration, the default confinement settings may be insufficient and
332 lead to subtle errors at run time, requiring adjustment:
335 [{option}`services.systemd.akkoma.confinement.packages`](options.html#opt-systemd.services._name_.confinement.packages)
336 to make packages available in the chroot.
338 {option}`services.systemd.akkoma.serviceConfig.BindPaths` and
339 {option}`services.systemd.akkoma.serviceConfig.BindReadOnlyPaths` permit access to outside paths
340 through bind mounts. Refer to
341 [`BindPaths=`](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#BindPaths=)
342 of {manpage}`systemd.exec(5)` for details.
344 ### Distributed deployment {#modules-services-akkoma-distributed-deployment}
346 Being an Elixir application, Akkoma can be deployed in a distributed fashion.
348 This requires setting
349 [{option}`services.akkoma.dist.address`](options.html#opt-services.akkoma.dist.address) and
350 [{option}`services.akkoma.dist.cookie`](options.html#opt-services.akkoma.dist.cookie). The
351 specifics depend strongly on the deployment environment. For more information please check the
352 relevant [Erlang documentation](https://www.erlang.org/doc/reference_manual/distributed.html).