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