blob: a5e502c70f1181d786c808a4c681592b591dd8a5 [file] [log] [blame]
Skyler Greydb1f1d92023-10-22 16:43:45 +00001{ pkgs, ... }:
2let lib = pkgs.lib;
Skyler Greyc0a62472023-10-18 23:29:13 +00003in {
Skyler Greydb1f1d92023-10-22 16:43:45 +00004 Host = host: service: {
5 inherit host service;
6 extraHosts = [ ];
7 secure = true;
8 type = "hosts";
9 };
10 Hosts = hosts: service: {
11 inherit service;
12 host = builtins.elemAt hosts 0;
13 extraHosts = builtins.tail hosts;
14 secure = true;
15 type = "hosts";
16 };
17 InsecureHost = host: service: {
18 inherit host service;
19 extraHosts = [ ];
20 secure = false;
21 type = "hosts";
22 };
23 InsecureHosts = hosts: service: {
24 inherit service;
25 host = builtins.elemAt hosts 0;
26 extraHosts = builtins.tail hosts;
27 secure = false;
28 type = "hosts";
29 };
30 ReverseProxy = to: {
31 inherit to;
32 type = "reverseproxy";
33 };
34 PHP = root: socket: {
35 inherit root socket;
36 type = "php";
37 };
38 Redirect = to: {
39 inherit to;
40 permanent = false;
41 type = "redirect";
42 };
43 RedirectPermanent = to: {
44 inherit to;
45 permanent = true;
46 type = "redirect";
47 };
48 Directory = root: {
49 inherit root;
50 private = false;
51 type = "directory";
52 };
53 PrivateDirectory = root: {
54 inherit root;
55 private = true;
56 type = "directory";
57 };
58 File = path: {
59 inherit path;
60 type = "file";
61 };
62 Compose = services: {
63 inherit services;
64 type = "compose";
65 };
66 Path = path: service: {
67 inherit path service;
68 type = "path";
69 };
70 Status = statusCode: {
71 inherit statusCode;
72 type = "status";
73 };
Skyler Greyc0a62472023-10-18 23:29:13 +000074
Skyler Greydb1f1d92023-10-22 16:43:45 +000075 Merge = let
Skyler Greyc0a62472023-10-18 23:29:13 +000076 # builtins.length and count up
Skyler Greydb1f1d92023-10-22 16:43:45 +000077 _iterateCompose = services: currentConfig: currentPath: secure: priority: i:
78 if i < builtins.length services then
79 _iterateCompose services
80 (_merge (builtins.elemAt services i) currentConfig currentPath secure
81 (priority + i)) currentPath secure priority (i + 1)
82 else
83 currentConfig;
Skyler Greyc0a62472023-10-18 23:29:13 +000084
Skyler Greydb1f1d92023-10-22 16:43:45 +000085 _iterateMerge = i: current: services:
86 if i < builtins.length services then
87 _iterateMerge (i + 1)
88 (current ++ [ (_merge (builtins.elemAt services i) { } "/" true 1000) ])
89 services
90 else
91 current;
Skyler Greyc0a62472023-10-18 23:29:13 +000092
Skyler Greydb1f1d92023-10-22 16:43:45 +000093 _merge = service: currentConfig: currentPath: secure: priority:
94 if service.type == "hosts" then
95 _merge service.service (lib.recursiveUpdate currentConfig {
96 name = service.host;
97 value = {
98 serverAliases = service.extraHosts;
Skyler Greyc0a62472023-10-18 23:29:13 +000099
Skyler Greydb1f1d92023-10-22 16:43:45 +0000100 enableACME = true;
101 forceSSL = service.secure;
102 addSSL = !service.secure;
103 listenAddresses = [ "0.0.0.0" ];
104 };
105 }) currentPath service.secure priority
106 else if service.type == "reverseproxy" then
107 (lib.recursiveUpdate currentConfig {
108 value.locations.${currentPath} = {
Skyler Grey05068122023-10-22 20:51:01 +0000109 proxyPass = if currentPath == "/" then "http://${service.to}" else "http://${service.to}/";
Skyler Greydb1f1d92023-10-22 16:43:45 +0000110 proxyWebsockets = true;
111 recommendedProxySettings = true;
112 };
113 })
114 else if service.type == "php" then
115 (lib.recursiveUpdate currentConfig {
116 value.locations.${currentPath} = {
117 root = service.root;
118 index = "index.php index.html index.htm";
119 tryFiles = "$uri $uri/ ${currentPath}index.php?$query_string =404";
120 };
121 value.locations."~ ^${currentPath}.*.php$" = {
122 tryFiles = "$uri $uri/ ${currentPath}index.php?$query_string =404";
123 extraConfig = ''
124 include ${pkgs.nginx}/conf/fastcgi_params;
125 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
126 fastcgi_param REDIRECT_STATUS 200;
127 fastcgi_pass unix:${service.socket};
128 fastcgi_intercept_errors on;
129 ${lib.optionalString secure "fastcgi_param HTTPS on;"}
130 '';
131 };
132 })
133 else if service.type == "redirect" then
134 (lib.recursiveUpdate currentConfig {
135 value.locations.${currentPath}.return = if service.permanent then
136 "308 ${service.to}"
137 else
138 "307 ${service.to}";
139 })
140 else if service.type == "directory" then
141 (lib.recursiveUpdate currentConfig {
142 value.locations.${currentPath} = {
143 root = service.root;
144 index = "index.html index.htm";
145 tryFiles = "$uri $uri/ =404";
146 extraConfig = lib.optionalString (!service.private) "autoindex on;";
147 };
148 })
149 else if service.type == "file" then
150 (lib.recursiveUpdate currentConfig {
151 value.locations.${currentPath} = {
152 tryFiles = "${service.path} =404";
153 };
154 })
155 else if service.type == "path" then
156 _merge service.service currentConfig service.path service.secure
157 priority
158 else if service.type == "compose" then
159 (_iterateCompose service.services currentConfig currentPath secure
160 priority 0)
161 else if service.type == "status" then
162 (lib.recursiveUpdate currentConfig {
163 value.locations.${currentPath} = {
164 return = "${builtins.toString service.statusCode}";
165 };
166 })
167 else
168 throw "Unknown service type: ${service.type}";
169 in (services:
170 lib.pipe services [ (_iterateMerge 0 [ ]) builtins.listToAttrs ]);
Skyler Greyc0a62472023-10-18 23:29:13 +0000171
Skyler Greydb1f1d92023-10-22 16:43:45 +0000172 # https://www.nginx.com/resources/wiki/start/topics/examples/full/
Skyler Greyc0a62472023-10-18 23:29:13 +0000173
Skyler Greydb1f1d92023-10-22 16:43:45 +0000174 /* *
175 Internal needs to be a string that is both a host and a port, e.g. generic:1000
176 External should only be a port
177 Protocol should be TCP or UDP
178 */
179 Stream = external: internal: protocol: {
180 inherit external internal protocol;
181 };
Skyler Greyc0a62472023-10-18 23:29:13 +0000182
Skyler Greydb1f1d92023-10-22 16:43:45 +0000183 Alias = host: alias: {
184 inherit host;
185 aliases = [ alias ];
186 type = "aliases";
187 };
Skyler Greyc0a62472023-10-18 23:29:13 +0000188
Skyler Greydb1f1d92023-10-22 16:43:45 +0000189 Aliases = host: aliases: {
190 inherit host aliases;
191 type = "aliases";
192 };
Skyler Greyc0a62472023-10-18 23:29:13 +0000193}
194