{ config, inputs, lib, libNginx, this, ... }: let cfg = config.nixfiles.modules.ipfs; gatewayDefaultPort = 6001; apiDefaultPort = 5001; swarmDefaultPort = 4001; in { options.nixfiles.modules.ipfs = { enable = lib.mkEnableOption "IPFS daemon"; domain = lib.mkOption { description = "Domain name sans protocol scheme."; type = lib.types.str; default = "ipfs.${config.networking.fqdn}"; }; gatewayBind = lib.mkOption { description = "Gateway bind."; type = lib.types.str; default = "127.0.0.1"; }; gatewayPort = lib.mkOption { description = "Gateway port."; type = lib.types.port; default = if this.isHeadless then gatewayDefaultPort + 990 else gatewayDefaultPort; }; apiBind = lib.mkOption { description = "API bind."; type = lib.types.str; default = "127.0.0.1"; }; apiPort = lib.mkOption { description = "API port."; type = lib.types.port; default = if this.isHeadless then apiDefaultPort + 990 else apiDefaultPort; }; swarmPort = lib.mkOption { description = "Swarm port."; type = lib.types.port; default = swarmDefaultPort; }; }; config = lib.mkIf cfg.enable ( lib.mkMerge [ { services.kubo = { enable = true; user = lib.my.username; inherit (config.my) group; dataDir = "${config.dirs.data}/ipfs"; autoMigrate = true; autoMount = true; emptyRepo = true; enableGC = true; # https://github.com/ipfs/kubo/blob/master/docs/config.md settings = lib.mkMerge [ ( let filterAddresses = [ "/ip4/100.64.0.0/ipcidr/10" "/ip4/169.254.0.0/ipcidr/16" "/ip4/172.16.0.0/ipcidr/12" "/ip4/192.0.0.0/ipcidr/24" "/ip4/192.0.2.0/ipcidr/24" "/ip4/192.168.0.0/ipcidr/16" "/ip4/198.18.0.0/ipcidr/15" "/ip4/198.51.100.0/ipcidr/24" "/ip4/203.0.113.0/ipcidr/24" "/ip4/240.0.0.0/ipcidr/4" "/ip6/100::/ipcidr/64" "/ip6/2001:2::/ipcidr/48" "/ip6/2001:db8::/ipcidr/32" "/ip6/fe80::/ipcidr/10" ] ++ lib.optionals (!lib.hasAttr "wireguard" this) [ "/ip4/10.0.0.0/ipcidr/8" "/ip6/fc00::/ipcidr/7" ]; in { Addresses = { API = "/ip4/${cfg.apiBind}/tcp/${toString cfg.apiPort}"; Gateway = "/ip4/${cfg.gatewayBind}/tcp/${toString cfg.gatewayPort}"; Swarm = let port = toString cfg.swarmPort; in [ "/ip4/0.0.0.0/tcp/${port}" "/ip6/::/tcp/${port}" "/ip4/0.0.0.0/udp/${port}/quic" "/ip4/0.0.0.0/udp/${port}/quic-v1" "/ip4/0.0.0.0/udp/${port}/quic-v1/webtransport" "/ip6/::/udp/${port}/quic" "/ip6/::/udp/${port}/quic-v1" "/ip6/::/udp/${port}/quic-v1/webtransport" ]; NoAnnounce = filterAddresses; }; Swarm.AddrFilters = filterAddresses; API.HTTPHeaders = { Access-Control-Allow-Origin = [ "http://127.0.0.1:5001" "http://webui.ipfs.io.ipns.localhost:6001" ]; Access-Control-Allow-Methods = [ "PUT" "POST" ]; }; Experimental.FilestoreEnabled = true; } ) ]; localDiscovery = true; startWhenNeeded = true; }; networking.firewall = rec { allowedTCPPorts = [ swarmDefaultPort ]; allowedUDPPorts = allowedTCPPorts; }; boot.kernel.sysctl = { "net.core.rmem_max" = 7500000; "net.core.wmem_max" = 7500000; }; topology = { nodes.${this.hostname}.services.ipfs-kubo = { name = "IPFS Kubo"; icon = "${inputs.homelab-svg-assets}/assets/ipfs.svg"; details.listen.text = '' ${cfg.gatewayBind}:${toString cfg.gatewayPort} ${cfg.apiBind}:${toString cfg.apiPort} ''; }; }; } (lib.mkIf this.isHeadless { nixfiles.modules.nginx = { enable = true; upstreams = { kubo_gateway.servers."${cfg.gatewayBind}:${toString cfg.gatewayPort}" = { }; kubo_api.servers."${cfg.apiBind}:${toString cfg.apiPort}" = { }; }; virtualHosts = { ${cfg.domain} = { locations."/".proxyPass = "http://kubo_gateway"; extraConfig = libNginx.config.internalOnly; }; "api.${cfg.domain}" = { locations = { "/".proxyPass = "http://kubo_api"; "~ ^/$".return = "301 http${lib.optionalString config.nixfiles.modules.acme.enable "s"}://api.${cfg.domain}/webui"; }; extraConfig = libNginx.config.internalOnly; }; }; }; topology.nodes.${this.hostname}.services.ipfs-kubo.info = cfg.domain; }) ] ); }