grafana-alloy: don't build the frontend twice
[NixPkgs.git] / nixos / modules / services / web-apps / kasmweb / default.nix
blobf626e369334edb861d801e53ffb35dc4c3364c99
1 { config, lib, pkgs, ... }:
3 let
4   cfg = config.services.kasmweb;
5 in
7   options.services.kasmweb = {
8     enable = lib.mkEnableOption "kasmweb";
10     networkSubnet = lib.mkOption {
11       default = "172.20.0.0/16";
12       type = lib.types.str;
13       description = ''
14         The network subnet to use for the containers.
15       '';
16     };
18     postgres = {
19       user = lib.mkOption {
20         default = "kasmweb";
21         type = lib.types.str;
22         description = ''
23           Username to use for the postgres database.
24         '';
25       };
26       password = lib.mkOption {
27         default = "kasmweb";
28         type = lib.types.str;
29         description = ''
30           password to use for the postgres database.
31         '';
32       };
33     };
35     redisPassword = lib.mkOption {
36       default = "kasmweb";
37       type = lib.types.str;
38       description = ''
39         password to use for the redis cache.
40       '';
41     };
43     defaultAdminPassword = lib.mkOption {
44       default = "kasmweb";
45       type = lib.types.str;
46       description = ''
47         default admin password to use.
48       '';
49     };
51     defaultUserPassword = lib.mkOption {
52       default = "kasmweb";
53       type = lib.types.str;
54       description = ''
55         default user password to use.
56       '';
57     };
59     defaultManagerToken = lib.mkOption {
60       default = "kasmweb";
61       type = lib.types.str;
62       description = ''
63         default manager token to use.
64       '';
65     };
67     defaultGuacToken = lib.mkOption {
68       default = "kasmweb";
69       type = lib.types.str;
70       description = ''
71         default guac token to use.
72       '';
73     };
75     defaultRegistrationToken = lib.mkOption {
76       default = "kasmweb";
77       type = lib.types.str;
78       description = ''
79         default registration token to use.
80       '';
81     };
83     datastorePath = lib.mkOption {
84       type = lib.types.str;
85       default = "/var/lib/kasmweb";
86       description = ''
87         The directory used to store all data for kasmweb.
88       '';
89     };
91     listenAddress = lib.mkOption {
92       type = lib.types.str;
93       default = "0.0.0.0";
94       description = ''
95         The address on which kasmweb should listen.
96       '';
97     };
99     listenPort = lib.mkOption {
100       type = lib.types.int;
101       default = 443;
102       description = ''
103         The port on which kasmweb should listen.
104       '';
105     };
107     sslCertificate = lib.mkOption {
108       type = lib.types.nullOr lib.types.path;
109       default = null;
110       description = ''
111         The SSL certificate to be used for kasmweb.
112       '';
113     };
115     sslCertificateKey = lib.mkOption {
116       type = lib.types.nullOr lib.types.path;
117       default = null;
118       description = ''
119         The SSL certificate's key to be used for kasmweb. Make sure to specify
120         this as a string and not a literal path, so that it is not accidentally
121         included in your nixstore.
122       '';
123     };
124   };
126   config = lib.mkIf cfg.enable {
127     systemd.services = {
128       "init-kasmweb" = {
129         wantedBy = [
130           "docker-kasm_db.service"
131           "podman-kasm_db.service"
132         ];
133         wants = ["network-online.target"];
134         after = ["network-online.target"];
135         serviceConfig = {
136           Type = "oneshot";
137           TimeoutStartSec = 300;
138           ExecStart = pkgs.substituteAll {
139             src = ./initialize_kasmweb.sh;
140             isExecutable = true;
141             binPath = lib.makeBinPath [ pkgs.docker pkgs.openssl pkgs.gnused pkgs.yq-go ];
142             runtimeShell = pkgs.runtimeShell;
143             kasmweb = pkgs.kasmweb;
144             postgresUser = "postgres";
145             postgresPassword = "postgres";
146             inherit (cfg)
147               datastorePath
148               sslCertificate
149               sslCertificateKey
150               redisPassword
151               networkSubnet
152               defaultUserPassword
153               defaultAdminPassword
154               defaultManagerToken
155               defaultRegistrationToken
156               defaultGuacToken;
157           };
158         };
159       };
160     };
162     virtualisation = {
163       oci-containers.backend = "docker";
164       oci-containers.containers = {
165         kasm_db = {
166           image = "postgres:16-alpine";
167           autoStart = true;
168           environment = {
169             POSTGRES_PASSWORD = "postgres";
170             POSTGRES_USER = "postgres";
171             POSTGRES_DB = "kasm";
172           };
173           volumes = [
174             "${cfg.datastorePath}/conf/database/data.sql:/docker-entrypoint-initdb.d/data.sql"
175             "${cfg.datastorePath}/conf/database/:/tmp/"
176             "kasmweb_db:/var/lib/postgresql/data"
177           ];
178           extraOptions = [ "--network=kasm_default_network" ];
179         };
180         kasm_db_init = {
181           image = "kasmweb/api:${pkgs.kasmweb.version}";
182           user = "root:root";
183           autoStart = true;
184           volumes = [
185             "${cfg.datastorePath}/:/opt/kasm/current/"
186             "kasmweb_api_data:/tmp"
187           ];
188           dependsOn = [ "kasm_db" ];
189           entrypoint = "/bin/bash";
190           cmd = [ "/opt/kasm/current/init_seeds.sh" ];
191           extraOptions = [ "--network=kasm_default_network" "--userns=host" ];
192         };
193         kasm_redis = {
194           image = "redis:5-alpine";
195           entrypoint = "/bin/sh";
196           autoStart = true;
197           cmd = [
198             "-c"
199             "redis-server --requirepass ${cfg.redisPassword}"
200           ];
201           extraOptions = [ "--network=kasm_default_network" "--userns=host" ];
202         };
203         kasm_api = {
204           image = "kasmweb/api:${pkgs.kasmweb.version}";
205           autoStart = false;
206           user = "root:root";
207           volumes = [
208             "${cfg.datastorePath}/:/opt/kasm/current/"
209             "kasmweb_api_data:/tmp"
210           ];
211           dependsOn = [ "kasm_db_init" ];
212           extraOptions = [ "--network=kasm_default_network" "--userns=host"  ];
213         };
214         kasm_manager = {
215           image = "kasmweb/manager:${pkgs.kasmweb.version}";
216           autoStart = false;
217           user = "root:root";
218           volumes = [
219             "${cfg.datastorePath}/:/opt/kasm/current/"
220           ];
221           dependsOn = [ "kasm_db_init" "kasm_db" "kasm_api" ];
222           extraOptions = [ "--network=kasm_default_network" "--userns=host" "--read-only"];
223         };
224         kasm_agent = {
225           image = "kasmweb/agent:${pkgs.kasmweb.version}";
226           autoStart = false;
227           user = "root:root";
228           volumes = [
229             "${cfg.datastorePath}/:/opt/kasm/current/"
230             "/var/run/docker.sock:/var/run/docker.sock"
231             "${pkgs.docker}/bin/docker:/usr/bin/docker"
232             "${cfg.datastorePath}/conf/nginx:/etc/nginx/conf.d"
233           ];
234           dependsOn = [ "kasm_manager" ];
235           extraOptions = [ "--network=kasm_default_network" "--userns=host" "--read-only" ];
236         };
237         kasm_share = {
238           image = "kasmweb/share:${pkgs.kasmweb.version}";
239           autoStart = false;
240           user = "root:root";
241           volumes = [
242             "${cfg.datastorePath}/:/opt/kasm/current/"
243           ];
244           dependsOn = [ "kasm_db_init" "kasm_db" "kasm_redis" ];
245           extraOptions = [ "--network=kasm_default_network" "--userns=host" "--read-only" ];
246         };
247         kasm_guac = {
248           image = "kasmweb/kasm-guac:${pkgs.kasmweb.version}";
249           autoStart = false;
250           user = "root:root";
251           volumes = [
252             "${cfg.datastorePath}/:/opt/kasm/current/"
253           ];
254           dependsOn = [ "kasm_db" "kasm_redis" ];
255           extraOptions = [ "--network=kasm_default_network" "--userns=host" "--read-only" ];
256         };
257         kasm_proxy = {
258           image = "kasmweb/nginx:latest";
259           autoStart = false;
260           ports = [ "${cfg.listenAddress}:${toString cfg.listenPort}:443" ];
261           user = "root:root";
262           volumes = [
263             "${cfg.datastorePath}/conf/nginx:/etc/nginx/conf.d:ro"
264             "${cfg.datastorePath}/certs/kasm_nginx.key:/etc/ssl/private/kasm_nginx.key"
265             "${cfg.datastorePath}/certs/kasm_nginx.crt:/etc/ssl/certs/kasm_nginx.crt"
266             "${cfg.datastorePath}/www:/srv/www:ro"
267             "${cfg.datastorePath}/log/nginx:/var/log/external/nginx"
268             "${cfg.datastorePath}/log/logrotate:/var/log/external/logrotate"
269           ];
270           dependsOn = [ "kasm_manager" "kasm_api" "kasm_agent" "kasm_share"
271           "kasm_guac" ];
272           extraOptions = [ "--network=kasm_default_network" "--userns=host"
273           "--network-alias=proxy"];
274         };
275       };
276     };
277   };