{ tree, lib, inputs, config, ... }: let container-addresses = import ../../data/container-addresses.nix {}; hostIP = container-addresses.host; containerIP = container-addresses.containers.music; # Using secrets from Host secrets = config.services.secrets.secrets; ports = import ./data/ports.nix {}; in { networking.nat.forwardPorts = [ { sourcePort = ports.mpd; destination = "${containerIP}\:${toString ports.mpd}"; } { sourcePort = ports.slskd; destination = "${containerIP}\:${toString ports.slskd}"; } ]; containers.music = { autoStart = true; privateNetwork = true; hostAddress = hostIP; localAddress = containerIP; bindMounts = lib.mkMerge (lib.forEach [ "mpd_control_password" "slskd_env" ] (secret_name: let path = "${secrets.${secret_name}.path}"; in { "${path}" = { hostPath = "${path}"; }; })); config = { config, pkgs, ... }: { _module.args = { inherit inputs; inherit tree; host_secrets = secrets; }; imports = with tree; [ profiles.base inputs.home-manager-unstable.nixosModules.home-manager profiles.sshd profiles.nginx modules.nixos.secrets users.root ] ++ (with hosts.hetzner-vm.containers.music; [ profiles.music-sync profiles.mpd profiles.soulseek ]); # For Shared Secrets systemd.tmpfiles.rules = [ "d ${config.services.secrets.secretsDir} - root root" ]; networking.firewall = { enable = true; allowedTCPPorts = [22] ++ lib.mapAttrsToList (_name: value: value) ports; }; home-manager.users.root = { imports = with tree; [home.base home.dev.small]; home.packages = with pkgs; [vault]; home.stateVersion = "22.05"; }; # Manually configure nameserver. Using resolved inside the container seems to fail # currently environment.etc."resolv.conf".text = "nameserver 8.8.8.8"; system.stateVersion = "22.05"; }; }; services.nginx.virtualHosts."soulseek.owo.monster" = { forceSSL = true; enableACME = true; locations."/" = { proxyPass = "http://${containerIP}:${toString ports.slskd-web}"; proxyWebsockets = true; }; }; services.nginx.virtualHosts."stream.owo.monster" = let extraConfig = '' auth_basic "Music Password"; auth_basic_user_file ${secrets.music_stream_passwd.path}; ''; in { forceSSL = true; enableACME = true; locations = lib.mkMerge ([ { "/mpd/flac" = { proxyPass = "http://${containerIP}:${toString ports.mpd-flac}"; inherit extraConfig; }; } ] ++ (lib.forEach ["low" "medium" "high"] (quality: { "/mpd/opus-${quality}" = { proxyPass = "http://${containerIP}:${toString ports."mpd-opus-${quality}"}"; inherit extraConfig; }; }))); }; # For permissions of secrets users.users."mpd" = { uid = config.ids.uids.mpd; group = "mpd"; }; users.groups."mpd" = { gid = config.ids.gids.mpd; }; networking.firewall.allowedTCPPorts = with ports; [ mpd slskd ]; }