diff --git a/flake.lock b/flake.lock index 71f0a58..db91f09 100644 --- a/flake.lock +++ b/flake.lock @@ -538,11 +538,11 @@ }, "nix-secrets": { "locked": { - "lastModified": 1736453439, - "narHash": "sha256-lDnZPKCNGjLzYwuYgW+bj6xaTFEiEvfKLAOSI6BQR6c=", + "lastModified": 1736678262, + "narHash": "sha256-LLKE6KboWC8l9llNrrLU/o6kVaHFHDsWEW8fKpX/6NI=", "ref": "refs/heads/master", - "rev": "d7aadcc3de64b66359386399d80ccc446181a758", - "revCount": 196, + "rev": "7a43e9814b20d7eac2a44d514402c64a54597f35", + "revCount": 198, "type": "git", "url": "ssh://git@git.bitlab21.com/sam/nix-secrets.git" }, diff --git a/hosts/common/optional/docker/arrstack.nix b/hosts/common/optional/arion-containers/arrstack.nix similarity index 86% rename from hosts/common/optional/docker/arrstack.nix rename to hosts/common/optional/arion-containers/arrstack.nix index 90e9954..6a57033 100644 --- a/hosts/common/optional/docker/arrstack.nix +++ b/hosts/common/optional/arion-containers/arrstack.nix @@ -3,16 +3,6 @@ let openVpnPwd = config.sops.secrets."software/proton/openvpn_password".path; openVpnUser = config.sops.secrets."software/proton/openvpn_user".path; in { - services.restic.backups = { - daily = { - paths = [ - "/srv/media-server/arrstack" - ]; - exclude = [ - ]; - }; - }; - sops.secrets = { "software/proton/openvpn_password" = {}; "software/proton/openvpn_user" = {}; @@ -33,7 +23,7 @@ in { container_name = "glutun"; restart = "always"; volumes = [ - "/srv/media-server/arrstack/gluetun:/gluetun" + "/srv/docker/media-server/arrstack/gluetun:/gluetun" "${openVpnPwd}:/run/secrets/openvpn_password" "${openVpnUser}:/run/secrets/openvpn_user" ]; @@ -50,7 +40,7 @@ in { container_name = "qbittorrent"; restart = "always"; volumes = [ - "/srv/media-server/arrstack/qbittorrent:/config" + "/srv/docker/media-server/arrstack/qbittorrent:/config" "/media/media:/media" ]; environment = { diff --git a/hosts/common/optional/docker/jellyfin.nix b/hosts/common/optional/arion-containers/jellyfin.nix similarity index 52% rename from hosts/common/optional/docker/jellyfin.nix rename to hosts/common/optional/arion-containers/jellyfin.nix index cba2df1..65a075c 100644 --- a/hosts/common/optional/docker/jellyfin.nix +++ b/hosts/common/optional/arion-containers/jellyfin.nix @@ -1,14 +1,4 @@ { - services.restic.backups = { - daily = { - paths = [ - "/srv/media-server/jellyfin" - ]; - exclude = [ - ]; - }; - }; - virtualisation.arion = { backend = "podman-socket"; projects.jellyfin = { @@ -21,13 +11,13 @@ image = "lscr.io/linuxserver/jellyfin:latest"; restart = "always"; volumes = [ - "/srv/media-server/jellyfin/config:/config" - "/media/media/tv:/data/tvshows" - "/media/media/movies:/data/movies" - "/media/media/music/music_data:/data/music" - "/media/media/youtube:/data/youtube" - "/media/media/podcasts:/data/podcasts" - "/srv/media-server/jellyfin/config/custom-cont-init.d:/custom-cont-init.d:ro" + "/srv/docker/media-server/jellyfin/config:/config" + "/media/media/tv:/data/tvshows:ro" + "/media/media/movies:/data/movies:ro" + "/media/media/music/music_data:/data/music:ro" + "/media/media/youtube:/data/youtube:ro" + "/media/media/podcasts:/data/podcasts:ro" + "/srv/docker/media-server/jellyfin/config/custom-cont-init.d:/custom-cont-init.d:ro" ]; environment = { PUID = "1000"; diff --git a/hosts/common/optional/docker/default.nix b/hosts/common/optional/docker.nix similarity index 100% rename from hosts/common/optional/docker/default.nix rename to hosts/common/optional/docker.nix diff --git a/hosts/common/optional/nixos-containers/docker.nix b/hosts/common/optional/nixos-containers/docker.nix new file mode 100644 index 0000000..58d25cc --- /dev/null +++ b/hosts/common/optional/nixos-containers/docker.nix @@ -0,0 +1,168 @@ +{ + pkgs, + configVars, + lib, + inputs, + ... +}: let + containerName = "docker"; + containerIp = configVars.networking.addresses.docker.ip; + gatewayIp = configVars.networking.addresses.gateway.ip; + pubKeys = lib.filesystem.listFilesRecursive ../../users/keys; + arion = inputs.arion; + sops-nix = inputs.sops-nix; +in { + networking.nat.enable = true; + networking.nat.internalInterfaces = ["ve-+"]; + networking.nat.externalInterface = "br0"; + + services.restic.backups = { + daily = { + paths = [ + "/media/main-ssd/docker/media-server" + ]; + exclude = [ + ]; + }; + }; + + environment.persistence."/persist" = { + hideMounts = true; + directories = [ + "/var/lib/nixos-containers/${containerName}" + ]; + }; + + containers."${containerName}" = { + enableTun = true; + + # configuration to run docker/podman in systemd-nspawn container + # https://discourse.nixos.org/t/podman-docker-in-nixos-container-ideally-in-unprivileged-one/22909/12 + additionalCapabilities = [ + ''all" --system-call-filter="add_key keyctl bpf" --capability="all'' + ]; + extraFlags = ["--private-users-ownership=chown"]; + allowedDevices = [ + { + node = "/dev/fuse"; + modifier = "rwm"; + } + { + node = "/dev/mapper/control"; + modifier = "rw"; + } + { + node = "/dev/console"; + modifier = "rwm"; + } + { + node = "/dev/dri/card1"; + modifier = "rwm"; + } + { + node = "/dev/dri/renderD128"; + modifier = "rwm"; + } + ]; + ###### + + autoStart = true; + privateNetwork = true; + hostBridge = "br0"; + nixpkgs = pkgs.path; + bindMounts = { + "/dev/dri" = { + hostPath = "/dev/dri"; + isReadOnly = false; + }; + "/media/media" = { + hostPath = "/media/media"; + isReadOnly = false; + }; + "/srv/docker" = { + hostPath = "/media/main-ssd/docker"; + isReadOnly = false; + }; + "/etc/ssh/ssh_host_ed25519_key" = { + hostPath = "/etc/ssh/ssh_host_ed25519_key"; + isReadOnly = true; + }; + }; + + config = { + pkgs, + lib, + ... + }: let + secretsDirectory = builtins.toString inputs.nix-secrets; + secretsFile = "${secretsDirectory}/secrets.yaml"; + in { + networking = { + defaultGateway = "${gatewayIp}"; + interfaces.eth0.ipv4.addresses = [ + { + "address" = "${containerIp}"; + "prefixLength" = 24; + } + ]; + firewall = { + enable = true; + allowedTCPPorts = [ + ]; + }; + useHostResolvConf = lib.mkForce false; + }; + + services.resolved.enable = true; + + sops = { + defaultSopsFile = "${secretsFile}"; + validateSopsFiles = false; + + age = { + sshKeyPaths = ["/etc/ssh/ssh_host_ed25519_key"]; + }; + }; + + imports = [ + arion.nixosModules.arion + sops-nix.nixosModules.sops + ../arion-containers/arrstack.nix + ../arion-containers/jellyfin.nix + ]; + + environment.systemPackages = [ + pkgs.vim + pkgs.git + pkgs.arion + pkgs.dive + pkgs.podman-tui + pkgs.podman-compose + ]; + + virtualisation = { + podman = { + enable = true; + dockerSocket.enable = true; + defaultNetwork.settings.dns_enabled = true; + dockerCompat = true; + }; + }; + + networking.firewall.interfaces."podman+".allowedUDPPorts = [53]; + + services.openssh = { + enable = true; + settings.PasswordAuthentication = false; + }; + + users.users = { + root = { + openssh.authorizedKeys.keys = lib.lists.forEach pubKeys (key: builtins.readFile key); + }; + }; + + system.stateVersion = "24.05"; + }; + }; +} diff --git a/hosts/semita/default.nix b/hosts/semita/default.nix index 1b0af6d..e39b5e3 100644 --- a/hosts/semita/default.nix +++ b/hosts/semita/default.nix @@ -50,17 +50,21 @@ in { ../common/optional/nfs-mounts/media.nix ../common/optional/nfs-mounts/homeshare.nix ../common/optional/printing.nix - ../common/optional/docker + ../common/optional/docker.nix + ../common/optional/nix-ld.nix + ../common/optional/gaming.nix + ../common/optional/restic-backup.nix + + # nixos-containers ../common/optional/nixos-containers/nix-bitcoin.nix ../common/optional/nixos-containers/postgres.nix ../common/optional/nixos-containers/baseddata-worker.nix - ../common/optional/nix-ld.nix - ../common/optional/gaming.nix - - ../common/optional/restic-backup.nix ../common/optional/nixos-containers/backup-server.nix - ../common/optional/docker/jellyfin.nix - ../common/optional/docker/arrstack.nix + ../common/optional/nixos-containers/docker.nix + + # # docker containers + # ../common/optional/arion-containers/jellyfin.nix + # ../common/optional/arion-containers/arrstack.nix # # Build nix derivations on remote machine # ../common/optional/distributed_builds/local-machine.nix