1import ../../make-test-python.nix (
2 { pkgs, ... }:
3 let
4 cert =
5 pkgs:
6 pkgs.runCommand "selfSignedCerts" { buildInputs = [ pkgs.openssl ]; } ''
7 openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -nodes -subj '/CN=mastodon.local' -days 36500
8 mkdir -p $out
9 cp key.pem cert.pem $out
10 '';
11
12 hosts = ''
13 192.168.2.103 mastodon.local
14 '';
15
16 postgresqlPassword = "thisisnotasecret";
17 redisPassword = "thisisnotasecrettoo";
18
19 in
20 {
21 name = "mastodon-remote-postgresql";
22 meta.maintainers = with pkgs.lib.maintainers; [
23 erictapen
24 izorkin
25 ];
26
27 nodes = {
28 databases =
29 { config, ... }:
30 {
31 environment = {
32 etc = {
33 "redis/password-redis-db".text = redisPassword;
34 };
35 };
36 networking = {
37 interfaces.eth1 = {
38 ipv4.addresses = [
39 {
40 address = "192.168.2.102";
41 prefixLength = 24;
42 }
43 ];
44 };
45 extraHosts = hosts;
46 firewall.allowedTCPPorts = [
47 config.services.redis.servers.mastodon.port
48 config.services.postgresql.settings.port
49 ];
50 };
51
52 services.redis.servers.mastodon = {
53 enable = true;
54 bind = "0.0.0.0";
55 port = 31637;
56 requirePassFile = "/etc/redis/password-redis-db";
57 };
58
59 services.postgresql = {
60 enable = true;
61 enableTCPIP = true;
62 authentication = ''
63 hostnossl mastodon mastodon 192.168.2.201/32 md5
64 '';
65 ensureDatabases = [ "mastodon" ];
66 ensureUsers = [
67 {
68 name = "mastodon";
69 ensureDBOwnership = true;
70 }
71 ];
72 initialScript = pkgs.writeText "postgresql_init.sql" ''
73 CREATE ROLE mastodon LOGIN PASSWORD '${postgresqlPassword}';
74 '';
75 };
76 };
77
78 nginx =
79 { nodes, ... }:
80 {
81 networking = {
82 interfaces.eth1 = {
83 ipv4.addresses = [
84 {
85 address = "192.168.2.103";
86 prefixLength = 24;
87 }
88 ];
89 };
90 extraHosts = hosts;
91 firewall.allowedTCPPorts = [
92 80
93 443
94 ];
95 };
96
97 security = {
98 pki.certificateFiles = [ "${cert pkgs}/cert.pem" ];
99 };
100
101 services.nginx = {
102 enable = true;
103 recommendedProxySettings = true;
104 virtualHosts."mastodon.local" = {
105 root = "/var/empty";
106 forceSSL = true;
107 enableACME = pkgs.lib.mkForce false;
108 sslCertificate = "${cert pkgs}/cert.pem";
109 sslCertificateKey = "${cert pkgs}/key.pem";
110 locations."/" = {
111 tryFiles = "$uri @proxy";
112 };
113 locations."@proxy" = {
114 proxyPass = "http://192.168.2.201:${toString nodes.server.services.mastodon.webPort}";
115 proxyWebsockets = true;
116 };
117 };
118 };
119 };
120
121 server =
122 { config, pkgs, ... }:
123 {
124 virtualisation.memorySize = 2048;
125
126 environment = {
127 etc = {
128 "mastodon/password-redis-db".text = redisPassword;
129 "mastodon/password-posgressql-db".text = postgresqlPassword;
130 };
131 };
132
133 networking = {
134 interfaces.eth1 = {
135 ipv4.addresses = [
136 {
137 address = "192.168.2.201";
138 prefixLength = 24;
139 }
140 ];
141 };
142 extraHosts = hosts;
143 firewall.allowedTCPPorts = [
144 config.services.mastodon.webPort
145 config.services.mastodon.sidekiqPort
146 ];
147 };
148
149 services.mastodon = {
150 enable = true;
151 configureNginx = false;
152 localDomain = "mastodon.local";
153 enableUnixSocket = false;
154 streamingProcesses = 2;
155 redis = {
156 createLocally = false;
157 host = "192.168.2.102";
158 port = 31637;
159 passwordFile = "/etc/mastodon/password-redis-db";
160 };
161 database = {
162 createLocally = false;
163 host = "192.168.2.102";
164 port = 5432;
165 name = "mastodon";
166 user = "mastodon";
167 passwordFile = "/etc/mastodon/password-posgressql-db";
168 };
169 smtp = {
170 createLocally = false;
171 fromAddress = "mastodon@mastodon.local";
172 };
173 extraConfig = {
174 BIND = "0.0.0.0";
175 EMAIL_DOMAIN_ALLOWLIST = "example.com";
176 RAILS_SERVE_STATIC_FILES = "true";
177 TRUSTED_PROXY_IP = "192.168.2.103";
178 };
179 };
180 };
181
182 client =
183 { pkgs, ... }:
184 {
185 environment.systemPackages = [ pkgs.jq ];
186 networking = {
187 interfaces.eth1 = {
188 ipv4.addresses = [
189 {
190 address = "192.168.2.202";
191 prefixLength = 24;
192 }
193 ];
194 };
195 extraHosts = hosts;
196 };
197
198 security = {
199 pki.certificateFiles = [ "${cert pkgs}/cert.pem" ];
200 };
201 };
202 };
203
204 testScript = import ./script.nix {
205 inherit pkgs;
206 extraInit = ''
207 nginx.wait_for_unit("nginx.service")
208 nginx.wait_for_open_port(443)
209 databases.wait_for_unit("redis-mastodon.service")
210 databases.wait_for_unit("postgresql.target")
211 databases.wait_for_open_port(31637)
212 databases.wait_for_open_port(5432)
213 '';
214 extraShutdown = ''
215 nginx.shutdown()
216 databases.shutdown()
217 '';
218 };
219 }
220)