Self-host your own digital island
1{ pkgs, config, lib, ... }:
2
3with lib;
4let cfg = config.eilean;
5in {
6 options.eilean.headscale = with lib; {
7 enable = mkEnableOption "headscale";
8 zone = mkOption {
9 type = types.str;
10 default = config.networking.domain;
11 defaultText = "config.networking.domain";
12 };
13 domain = mkOption {
14 type = types.str;
15 default = "headscale.${config.networking.domain}";
16 defaultText = "headscale.$\${config.networking.domain}";
17 };
18 };
19
20 config = mkIf cfg.headscale.enable {
21 # To set up:
22 # `headscale namespaces create <namespace_name>`
23 # To add a node:
24 # `headscale --namespace <namespace_name> nodes register --key <machine_key>`
25 services.headscale = {
26 enable = true;
27 # address = "127.0.0.1";
28 port = 10000;
29 settings = {
30 server_url = "https://${cfg.headscale.domain}";
31 logtail.enabled = false;
32 ip_prefixes = [ "100.64.0.0/10" "fd7a:115c:a1e0::/48" ];
33 };
34 };
35
36 services.nginx = {
37 enable = true;
38 virtualHosts.${cfg.headscale.domain} = {
39 forceSSL = true;
40 enableACME = true;
41 locations."/" = {
42 proxyPass = with config.services.headscale;
43 "http://${address}:${toString port}";
44 proxyWebsockets = true;
45 };
46 };
47 };
48
49 environment.systemPackages = [ config.services.headscale.package ];
50
51 eilean.dns.enable = true;
52 eilean.services.dns.zones.${cfg.headscale.zone}.records = [{
53 name = "${cfg.headscale.domain}.";
54 type = "CNAME";
55 value = cfg.domainName;
56 }];
57 };
58}