1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
{ pkgs, lib, config, ... }:
let
gotosocial = pkgs.callPackage ../../pkgs/gotosocial {};
in {
# dns.zones."ctu.cx".subdomains."fedi.home".CNAME = [ "${config.networking.fqdn}." ];
services.dnsmasq.settings.cname = [ "fedi.home.ctu.cx, ${config.networking.fqdn}" ];
age.secrets.restic-gotosocial.file = ./. + "/../../secrets/${config.networking.hostName}/restic/gotosocial.age";
age.secrets.gotosocial-env.file = ./. + "/../../secrets/${config.networking.hostName}/gotosocial-env.age";
systemd.services.restic-backup-gotosocial.serviceConfig.ReadWritePaths = [ "/var/lib/gotosocial" ];
restic-backups.gotosocial = {
user = "gotosocial";
passwordFile = config.age.secrets.restic-gotosocial.path;
sqliteDatabases = [ "/var/lib/gotosocial/db.sqlite" ];
paths = [ "/var/lib/gotosocial/storage" "/var/lib/gotosocial/backup.json" ];
runBeforeBackup = ''
${gotosocial}/bin/gotosocial --config-path /etc/gotosocial.yaml admin export --path /var/lib/gotosocial/backup.json
'';
};
systemd.services.gotosocial.serviceConfig = {
Group = lib.mkForce config.services.nginx.group;
EnvironmentFile = lib.mkIf (config.networking.usePBBUplink == false) config.age.secrets.gotosocial-env.path;
};
services.gotosocial = {
enable = true;
package = gotosocial;
group = "nginx";
settings = {
application-name = "ctucx.gts";
host = "fedi.home.ctu.cx";
account-domain = "fedi.home.ctu.cx";
protocol = "https";
bind-address = "[::1]";
port = 8085;
trusted-proxies = [ "::1/128" "172.17.0.0/24" ];
db-type = "sqlite";
db-address = "/var/lib/gotosocial/db.sqlite";
accounts-allow-custom-css = true;
accounts-registration-open = false;
instance-expose-peers = true;
instance-expose-suspended = true;
instance-expose-suspended-web = true;
instance-languages = [ "de" "en-us" ];
storage-backend = "local";
storage-local-base-path = "/var/lib/gotosocial/storage";
media-remote-max-size = 0;
media-remote-cache-days = 3;
media-cleanup-from = "02:00";
};
};
services.nginx.appendHttpConfig = ''
proxy_cache_path /var/cache/nginx keys_zone=gotosocial_ap_public_responses:10m inactive=1w;
'';
services.nginx.virtualHosts."fedi.home.ctu.cx" = {
enableACME = lib.mkIf config.networking.usePBBUplink true;
forceSSL = lib.mkIf config.networking.usePBBUplink true;
kTLS = lib.mkIf config.networking.usePBBUplink true;
locations = {
"= /".return = "307 /@leah";
"/" = {
proxyPass = "http://${toString config.services.gotosocial.settings.bind-address}:${toString config.services.gotosocial.settings.port}";
proxyWebsockets = true;
};
"~ /.well-known/(webfinger|host-meta)$" = {
proxyPass = "http://${toString config.services.gotosocial.settings.bind-address}:${toString config.services.gotosocial.settings.port}";
extraConfig = ''
proxy_cache gotosocial_ap_public_responses;
proxy_cache_background_update on;
proxy_cache_key $scheme://$host$uri$is_args$query_string;
proxy_cache_valid 200 10m;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504 http_429;
proxy_cache_lock on;
add_header X-Cache-Status $upstream_cache_status;
'';
};
"~ ^\/users\/(?:[a-z0-9_\.]+)\/main-key$" = {
proxyPass = "http://${toString config.services.gotosocial.settings.bind-address}:${toString config.services.gotosocial.settings.port}";
extraConfig = ''
proxy_cache gotosocial_ap_public_responses;
proxy_cache_background_update on;
proxy_cache_key $scheme://$host$uri;
proxy_cache_valid 200 604800s;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504 http_429;
proxy_cache_lock on;
add_header X-Cache-Status $upstream_cache_status;
'';
};
"/assets/".extraConfig = ''
alias ${config.services.gotosocial.package}/share/web/assets/;
autoindex off;
expires max;
add_header Cache-Control "public, immutable";
'';
};
};
}