From cca6abb1967ba34b30e956ea0f5e32c905445023 Mon Sep 17 00:00:00 2001 From: System administrator Date: Mon, 1 Jul 2024 22:19:14 +0300 Subject: [PATCH] initial commit --- configuration.nix | 149 ++++++++++++++++++++ flake.lock | 275 +++++++++++++++++++++++++++++++++++++ flake.nix | 26 ++++ grafana.nix | 60 ++++++++ gtrackmap.nix | 16 +++ hardware-configuration.nix | 40 ++++++ hydra.nix | 21 +++ immich.nix | 202 +++++++++++++++++++++++++++ invidious.nix | 25 ++++ owncast.nix | 16 +++ services.nix | 41 ++++++ syncthing.nix | 33 +++++ vaultwarden.nix | 42 ++++++ wireguard.nix | 41 ++++++ 14 files changed, 987 insertions(+) create mode 100644 configuration.nix create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 grafana.nix create mode 100644 gtrackmap.nix create mode 100644 hardware-configuration.nix create mode 100644 hydra.nix create mode 100644 immich.nix create mode 100644 invidious.nix create mode 100644 owncast.nix create mode 100644 services.nix create mode 100644 syncthing.nix create mode 100644 vaultwarden.nix create mode 100644 wireguard.nix diff --git a/configuration.nix b/configuration.nix new file mode 100644 index 0000000..584c1a4 --- /dev/null +++ b/configuration.nix @@ -0,0 +1,149 @@ +# Edit this configuration file to define what should be installed on +# your system. Help is available in the configuration.nix(5) man page +# and in the NixOS manual (accessible by running `nixos-help`). + +{ config, pkgs, self, ... }: + +{ + nix = { + settings = { + experimental-features = [ "nix-command" "flakes" ]; + auto-optimise-store = true; + }; + gc = { + automatic = true; + dates = "weekly"; + options = "--delete-older-than 30d"; + }; + }; + + system.autoUpgrade = { + enable = true; + flake = "/etc/nixos"; + flags = [ + "--update-input" + "nixpkgs" + "-L" # print build logs + ]; + dates = "02:00"; + randomizedDelaySec = "45min"; + }; + + # Use the GRUB 2 boot loader. + boot.loader.grub.enable = true; + boot.loader.grub.efiSupport = false; + # boot.loader.grub.efiInstallAsRemovable = true; + # boot.loader.efi.efiSysMountPoint = "/boot/efi"; + # Define on which hard drive you want to install Grub. + boot.loader.grub.device = "/dev/sda"; # or "nodev" for efi only + + networking.hostName = "freun-dev"; # Define your hostname. + networking.useDHCP = false; + + systemd.network = { + enable = true; + networks.static = { + name = "enp1s0"; + address = [ + "95.217.223.61/32" + "2a01:4f9:c012:5e97::1/64" + ]; + routes = [ + { Gateway = "fe80::1"; } + { + Gateway = "172.31.1.1"; + GatewayOnLink = true; + } + ]; + dns = [ + # Hetzner + "185.12.64.1" + "185.12.64.2" + "2a01:4ff:ff00::add:1" + "2a01:4ff:ff00::add:2" + # Quad9 + "9.9.9.9" + "149.112.112.112" + "2620:fe::fe" + "2620:fe::9" + ]; + }; + }; + + # Set your time zone. + time.timeZone = "Europe/Helsinki"; + + # Configure network proxy if necessary + # networking.proxy.default = "http://user:password@proxy:port/"; + # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain"; + + # Select internationalisation properties. + i18n.defaultLocale = "en_US.UTF-8"; + # console = { + # font = "Lat2-Terminus16"; + # keyMap = "us"; + # useXkbConfig = true; # use xkbOptions in tty. + # }; + + + # Configure keymap in X11 + services.xserver.xkb.layout = "us"; + services.xserver.xkb.options = "eurosign:e,caps:escape"; + + # Define a user account. Don't forget to set a password with ‘passwd’. + users.users.jokke = { + isNormalUser = true; + extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user. + # packages = with pkgs; [ + # firefox + # tree + # ]; + openssh.authorizedKeys.keys = [ + "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLIUkESu5NnBi1M0+ZjYrkp6/rIFuwc3aguspf98jmOydNce6l65cnS3GRzc9oWx4lu11ahi87ZuE+pYV+gaHm4=" + ]; + }; + + # List packages installed in system profile. To search, run: + # $ nix search wget + environment.systemPackages = with pkgs; [ + vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default. + wget + htop + ]; + + # Some programs need SUID wrappers, can be configured further or are + # started in user sessions. + # programs.mtr.enable = true; + # programs.gnupg.agent = { + # enable = true; + # enableSSHSupport = true; + # }; + + # List services that you want to enable: + + # Enable the OpenSSH daemon. + services.openssh = { + enable = true; + settings.PasswordAuthentication = false; + }; + + # Open ports in the firewall. + networking.firewall.allowedTCPPorts = [ 22 ]; + # networking.firewall.allowedUDPPorts = [ ... ]; + # Or disable the firewall altogether. + # networking.firewall.enable = false; + + # Copy the NixOS configuration file and link it from the resulting system + # (/run/current-system/configuration.nix). This is useful in case you + # accidentally delete configuration.nix. + # system.copySystemConfiguration = true; + + # This value determines the NixOS release from which the default + # settings for stateful data, like file locations and database versions + # on your system were taken. It's perfectly fine and recommended to leave + # this value at the release version of the first install of this system. + # Before changing this value read the documentation for this option + # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). + system.stateVersion = "23.05"; # Did you read the comment? +} + diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..a5bb433 --- /dev/null +++ b/flake.lock @@ -0,0 +1,275 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_3": { + "inputs": { + "systems": "systems_3" + }, + "locked": { + "lastModified": 1701680307, + "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "frontend": { + "inputs": { + "flake-utils": "flake-utils_2", + "nixpkgs": "nixpkgs", + "pnpm2nix": "pnpm2nix" + }, + "locked": { + "lastModified": 1717665236, + "narHash": "sha256-CGP0L44HxDp0i32iekMyy6M7AmVVsgLy84aA2+MR2AY=", + "owner": "gtrackmap", + "repo": "frontend", + "rev": "cad5b5abdeac60541b0f8487d22f4db4ace79f78", + "type": "github" + }, + "original": { + "owner": "gtrackmap", + "repo": "frontend", + "type": "github" + } + }, + "gtrackmap": { + "inputs": { + "flake-utils": "flake-utils", + "frontend": "frontend", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1717955510, + "narHash": "sha256-WuEs+ljTjyEIDNLmvyv7niQsNVr0lEfOjOcsmiL6mfQ=", + "owner": "gtrackmap", + "repo": "gtrackmap", + "rev": "ef27a0397c4d73dc31e7b49c8a2736ae62b5a3ff", + "type": "github" + }, + "original": { + "owner": "gtrackmap", + "repo": "gtrackmap", + "type": "github" + } + }, + "nextcloud": { + "inputs": { + "nixos-shell": "nixos-shell", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1711735384, + "narHash": "sha256-2oFPzoL5QfC6bifttaUku2ENv9ATv6umH6qhZY4A7T8=", + "owner": "onny", + "repo": "nixos-nextcloud-testumgebung", + "rev": "fa6f062830b4bc3cedb9694c1dbf01d5fdf775ac", + "type": "github" + }, + "original": { + "owner": "onny", + "repo": "nixos-nextcloud-testumgebung", + "type": "github" + } + }, + "nixos-shell": { + "inputs": { + "nixpkgs": "nixpkgs_3" + }, + "locked": { + "lastModified": 1711263551, + "narHash": "sha256-lDaSa0yT0uzFXq1rB0DbD5MNi2TmG9DaTrZqZoPP/I4=", + "owner": "Mic92", + "repo": "nixos-shell", + "rev": "b7e8a0c75c99d81039d1ca7eaab227e4814de638", + "type": "github" + }, + "original": { + "owner": "Mic92", + "repo": "nixos-shell", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1717196966, + "narHash": "sha256-yZKhxVIKd2lsbOqYd5iDoUIwsRZFqE87smE2Vzf6Ck0=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "57610d2f8f0937f39dbd72251e9614b1561942d8", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1702151865, + "narHash": "sha256-9VAt19t6yQa7pHZLDbil/QctAgVsA66DLnzdRGqDisg=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "666fc80e7b2afb570462423cb0e1cf1a3a34fedd", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1628465643, + "narHash": "sha256-QSNw9bDq9uGUniQQtakRuw4m21Jxugm23SXLVgEV4DM=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "6ef4f522d63f22b40004319778761040d3197390", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-unstable", + "type": "indirect" + } + }, + "nixpkgs_4": { + "locked": { + "lastModified": 1719506693, + "narHash": "sha256-C8e9S7RzshSdHB7L+v9I51af1gDM5unhJ2xO1ywxNH8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b2852eb9365c6de48ffb0dc2c9562591f652242a", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "pnpm2nix": { + "inputs": { + "flake-utils": "flake-utils_3", + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1706694632, + "narHash": "sha256-ytyTwNPiUR8aq74QlxFI+Wv3MyvXz5POO1xZxQIoi0c=", + "owner": "nzbr", + "repo": "pnpm2nix-nzbr", + "rev": "0366b7344171accc2522525710e52a8abbf03579", + "type": "github" + }, + "original": { + "owner": "nzbr", + "repo": "pnpm2nix-nzbr", + "type": "github" + } + }, + "root": { + "inputs": { + "gtrackmap": "gtrackmap", + "nextcloud": "nextcloud", + "nixpkgs": "nixpkgs_4" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_3": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..babbc7a --- /dev/null +++ b/flake.nix @@ -0,0 +1,26 @@ +{ + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + nextcloud = { + url = "github:onny/nixos-nextcloud-testumgebung"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + gtrackmap = { + url = "github:gtrackmap/gtrackmap"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + outputs = { self, nixpkgs, gtrackmap, ... }@attrs: { + nixosConfigurations.freun-dev = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + specialArgs = attrs; + modules = [ + ./hardware-configuration.nix + ./configuration.nix + ./services.nix + gtrackmap.nixosModules.x86_64-linux.default + ]; + }; + }; +} + diff --git a/grafana.nix b/grafana.nix new file mode 100644 index 0000000..a6a7f33 --- /dev/null +++ b/grafana.nix @@ -0,0 +1,60 @@ +{ ... }: +let + fqdn = "graph.freun.dev"; + port = 3300; +in +{ + services.grafana = { + enable = true; + + settings = { + server = { + root_url = "https://${fqdn}"; + http_port = port; + }; + + database = { + host = "/var/run/postgresql"; + type = "postgres"; + user = "grafana"; + }; + + smtp = { + enabled = true; + host = "horologium.uberspace.de"; + from_address = "noreply@freun.dev"; + from_name = "Vaultwarden"; + user = "noreply@freun.dev"; + password = "$__file{/var/secrets/smtp-password}"; + }; + }; + }; + + services.prometheus = { + enable = true; + exporters.node.enable = true; + scrapeConfigs = [ + { + job_name = "node"; + static_configs = [ + { targets = [ "localhost:9100" ]; } + ]; + } + ]; + }; + + services.caddy.virtualHosts = { + "${fqdn}".extraConfig = '' + reverse_proxy localhost:${builtins.toString port} + ''; + }; + + services.postgresql = { + ensureDatabases = [ "grafana" ]; + ensureUsers = [{ + name = "grafana"; + ensureDBOwnership = true; + }]; + }; +} + diff --git a/gtrackmap.nix b/gtrackmap.nix new file mode 100644 index 0000000..5b12abf --- /dev/null +++ b/gtrackmap.nix @@ -0,0 +1,16 @@ +{ config, ... }: +let + fqdn = "trackmap.freun.dev"; +in +{ + services.gtrackmap = { + enable = true; + port = 3200; + }; + + services.caddy.virtualHosts = { + "${fqdn}".extraConfig = '' + reverse_proxy localhost:${toString config.services.gtrackmap.port} + ''; + }; +} diff --git a/hardware-configuration.nix b/hardware-configuration.nix new file mode 100644 index 0000000..1778bd5 --- /dev/null +++ b/hardware-configuration.nix @@ -0,0 +1,40 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ (modulesPath + "/profiles/qemu-guest.nix") + ]; + + boot.initrd.availableKernelModules = [ "ahci" "xhci_pci" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = + { device = "/dev/disk/by-uuid/8456c7de-2116-4cbe-8deb-76cafbd3e6dd"; + fsType = "btrfs"; + options = [ "subvol=@" ]; + }; + + fileSystems."/var" = + { device = "/dev/disk/by-uuid/8456c7de-2116-4cbe-8deb-76cafbd3e6dd"; + fsType = "btrfs"; + options = [ "subvol=@var" ]; + }; + + swapDevices = + [ { device = "/dev/disk/by-uuid/614a1b7f-04aa-478c-9011-8b81f133da98"; } + ]; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.enp1s0.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; +} diff --git a/hydra.nix b/hydra.nix new file mode 100644 index 0000000..608a53a --- /dev/null +++ b/hydra.nix @@ -0,0 +1,21 @@ +{ ... }: +let + fqdn = "ci.freun.dev"; + port = 3400; +in +{ + services.hydra = { + enable = true; + hydraURL = "https://${fqdn}"; + notificationSender = "Hydra "; + buildMachinesFiles = []; + useSubstitutes = true; + inherit port; + }; + + services.caddy.virtualHosts = { + "${fqdn}".extraConfig = '' + reverse_proxy localhost:${builtins.toString port} + ''; + }; +} diff --git a/immich.nix b/immich.nix new file mode 100644 index 0000000..3f696b3 --- /dev/null +++ b/immich.nix @@ -0,0 +1,202 @@ +{ pkgs, lib, ... }: + +let + immich_version = "release"; + storage_dir = "/mnt/storage/syncthing"; + immich_data_dir = "/mnt/storage/immich"; + + volumeServices = names: ( + lib.lists.foldl (services: name: + services // { + "podman-volume-immich_${name}" = { + path = [ pkgs.podman ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + script = '' + podman volume inspect immich_${name} || podman volume create immich_${name} + ''; + partOf = [ "podman-compose-immich-root.target" ]; + wantedBy = [ "podman-compose-immich-root.target" ]; + }; + } + ) {} names + ); + + containerServices = services: ( + lib.lists.foldl (acc: { name, volumes ? [], ... }: + let + volume_services = map (volume: "podman-volume-immich_${volume}.service") volumes; + dependent_services = [ "podman-network-immich_default.service" ] ++ volume_services; + in + + acc // { + "podman-immich_${name}" = { + serviceConfig = { + Restart = lib.mkOverride 500 "always"; + }; + after = dependent_services; + requires = dependent_services; + partOf = [ + "podman-compose-immich-root.target" + ]; + wantedBy = [ + "podman-compose-immich-root.target" + ]; + }; + } + ) + {} services + ); +in { + # Containers + virtualisation.oci-containers.containers = { + "immich_machine_learning" = { + image = "ghcr.io/immich-app/immich-machine-learning:${immich_version}"; + environmentFiles = [ + "/var/secrets/immich.env" + ]; + volumes = [ + "immich_model_cache:/cache:rw" + ]; + log-driver = "journald"; + extraOptions = [ + "--network-alias=immich-machine-learning" + "--network=immich_default" + ]; + }; + + "immich_microservices" = { + image = "ghcr.io/immich-app/immich-server:${immich_version}"; + environmentFiles = [ + "/var/secrets/immich.env" + ]; + volumes = [ + "/etc/localtime:/etc/localtime:ro" + "${immich_data_dir}:/usr/src/app/upload:rw" + "${storage_dir}:${storage_dir}:ro" + ]; + cmd = [ "start.sh" "microservices" ]; + dependsOn = [ + "immich_postgres" + "immich_redis" + ]; + log-driver = "journald"; + extraOptions = [ + "--network-alias=immich-microservices" + "--network=immich_default" + ]; + }; + + "immich_postgres" = { + image = "registry.hub.docker.com/tensorchord/pgvecto-rs:pg14-v0.2.0"; + environmentFiles = [ + "/var/secrets/immich.env" + ]; + environment = { + POSTGRES_INITDB_ARGS = "--data-checksums"; + }; + volumes = [ + "immich_db_data:/var/lib/postgresql/data:rw" + ]; + cmd = [ "postgres" "-c" "shared_preload_libraries=vectors.so" "-c" "search_path=\"$user\", public, vectors" "-c" "logging_collector=on" "-c" "max_wal_size=2GB" "-c" "shared_buffers=512MB" "-c" "wal_compression=on" ]; + log-driver = "journald"; + extraOptions = [ + "--network-alias=database" + "--network=immich_default" + ]; + }; + + "immich_redis" = { + image = "registry.hub.docker.com/library/redis:6.2-alpine"; + environmentFiles = [ + "/var/secrets/immich.env" + ]; + log-driver = "journald"; + extraOptions = [ + "--network-alias=redis" + "--network=immich_default" + ]; + }; + + "immich_server" = { + image = "ghcr.io/immich-app/immich-server:${immich_version}"; + environmentFiles = [ + "/var/secrets/immich.env" + ]; + volumes = [ + "/etc/localtime:/etc/localtime:ro" + "${immich_data_dir}:/usr/src/app/upload:rw" + "${storage_dir}:${storage_dir}:ro" + ]; + ports = [ + "2283:3001/tcp" + ]; + cmd = [ "start.sh" "immich" ]; + dependsOn = [ + "immich_postgres" + "immich_redis" + ]; + log-driver = "journald"; + extraOptions = [ + "--network-alias=immich-server" + "--network=immich_default" + ]; + }; + }; + + systemd.services = (containerServices [ + { name = "machine_learning"; volumes = [ "model_cache" ]; } + { name = "postgres"; volumes = [ "db_data" ]; } + { name = "redis"; } + { name = "server"; } + { name = "microservices"; } + ]) // { + # Networks + "podman-network-immich_default" = { + path = [ pkgs.podman ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStop = "${pkgs.podman}/bin/podman network rm -f immich_default"; + }; + script = '' + podman network inspect immich_default || podman network create immich_default + ''; + partOf = [ "podman-compose-immich-root.target" ]; + wantedBy = [ "podman-compose-immich-root.target" ]; + }; + } // (volumeServices [ + "db_data" + "model_cache" + ]); + + # Root service + # When started, this will automatically create all resources and start + # the containers. When stopped, this will teardown all resources. + systemd.targets."podman-compose-immich-root" = { + unitConfig = { + Description = "Root target generated by compose2nix."; + }; + wantedBy = [ "multi-user.target" ]; + }; + + services.caddy.virtualHosts = { + "img.freun.dev".extraConfig = '' + reverse_proxy localhost:2283 + ''; + }; + + fileSystems."${immich_data_dir}" = { + device = "//u407959.your-storagebox.de/backup/immich"; + fsType = "cifs"; + options = let + # this line prevents hanging on network split + automount_opts = "x-systemd.automount,auto,x-systemd.device-timeout=5s,x-systemd.mount-timeout=5s"; + + in ["${automount_opts},credentials=/var/secrets/smb-storage"]; + }; + + environment.systemPackages = [ pkgs.cifs-utils ]; +} diff --git a/invidious.nix b/invidious.nix new file mode 100644 index 0000000..2f7474d --- /dev/null +++ b/invidious.nix @@ -0,0 +1,25 @@ +{ ... }: +let + fqdn = "vid.freun.dev"; +in +{ + services.invidious = { + enable = true; + domain = fqdn; + + settings = { + external_port = 443; + db = { + dbname = "invidious"; + user = "invidious"; + }; + }; + }; + + services.caddy.virtualHosts = { + "${fqdn}".extraConfig = '' + reverse_proxy localhost:3000 + ''; + }; + +} diff --git a/owncast.nix b/owncast.nix new file mode 100644 index 0000000..b71b26f --- /dev/null +++ b/owncast.nix @@ -0,0 +1,16 @@ +{ ... }: +let + fqdn = "stream.freun.dev"; +in +{ + services.owncast = { + enable = true; + openFirewall = true; + }; + + services.caddy.virtualHosts = { + "${fqdn}".extraConfig = '' + reverse_proxy localhost:8080 + ''; + }; +} diff --git a/services.nix b/services.nix new file mode 100644 index 0000000..f823547 --- /dev/null +++ b/services.nix @@ -0,0 +1,41 @@ +{ ... }: +{ + networking.firewall.allowedTCPPorts = [ 80 443 ]; + + services.caddy = { + enable = true; + enableReload = true; + email = "admin@pimeys.pm"; + }; + + services.postgresql.enable = true; + + virtualisation.podman = { + enable = true; + autoPrune.enable = true; + dockerCompat = true; + defaultNetwork.settings = { + # Required for container networking to be able to use names. + dns_enabled = true; + }; + }; + + virtualisation.oci-containers.backend = "podman"; + + networking.firewall = { + trustedInterfaces = [ "podman1" ]; + interfaces.podman1.allowedUDPPorts = [ 53 ]; + }; + + imports = [ + ./vaultwarden.nix + ./immich.nix + ./syncthing.nix + ./invidious.nix + ./grafana.nix + ./gtrackmap.nix + ./owncast.nix + ./hydra.nix + ./wireguard.nix + ]; +} diff --git a/syncthing.nix b/syncthing.nix new file mode 100644 index 0000000..cc8235a --- /dev/null +++ b/syncthing.nix @@ -0,0 +1,33 @@ +{ pkgs, config, lib, ... }: +let + storage_dir = "/mnt/storage/syncthing"; +in +{ + services.syncthing = { + enable = true; + dataDir = "/mnt/storage/syncthing"; + openDefaultPorts = true; + }; + + services.caddy.virtualHosts = { + "sync.freun.dev".extraConfig = '' + reverse_proxy localhost:8384 { + header_up Host {upstream_hostport} + } + ''; + }; + + fileSystems."${storage_dir}" = { + device = "//u407959.your-storagebox.de/backup/syncthing"; + fsType = "cifs"; + options = let + # this line prevents hanging on network split + automount_opts = "x-systemd.automount,auto,x-systemd.device-timeout=5s,x-systemd.mount-timeout=5s"; + uid = builtins.toString config.users.users.syncthing.uid; + gid = builtins.toString config.users.groups.syncthing.gid; + in ["${automount_opts},credentials=/var/secrets/smb-storage,uid=${uid},gid=${gid}"]; + }; + + + environment.systemPackages = [ pkgs.cifs-utils ]; +} diff --git a/vaultwarden.nix b/vaultwarden.nix new file mode 100644 index 0000000..c54987c --- /dev/null +++ b/vaultwarden.nix @@ -0,0 +1,42 @@ +{ ... }: +{ + services.vaultwarden = { + enable = true; + dbBackend = "postgresql"; + environmentFile = "/var/secrets/vaultwarden.env"; + config = { + DOMAIN = "https://pw.freun.dev"; + DATABASE_URL = "postgres://%2Fvar%2Frun%2Fpostgresql/vaultwarden"; + WEBSOCKET_ENABLED = true; + WEBSOCKET_ADDRESS = "127.0.0.1"; + WEBSOCKET_PORT = 3012; + SIGNUPS_VERIFY = true; + PASSWORD_ITERATIONS = 600000; + YUBICO_CLIENT_ID = 86799; + SMTP_HOST = "horologium.uberspace.de"; + SMTP_FROM = "noreply@freun.dev"; + SMTP_FROM_NAME = "Vaultwarden"; + SMTP_USERNAME = "noreply@freun.dev"; + SMTP_PORT = 587; + HELO_NAME = "freun.dev"; + ROCKET_LIMITS = "{json=10485760}"; + }; + }; + + services.caddy.virtualHosts = { + "pw.freun.dev".extraConfig = '' + reverse_proxy /notifications/hub localhost:3012 + reverse_proxy localhost:8000 { + header_up X-Real-IP {remote_host} + } + ''; + }; + + services.postgresql = { + ensureDatabases = [ "vaultwarden" ]; + ensureUsers = [{ + name = "vaultwarden"; + ensureDBOwnership = true; + }]; + }; +} diff --git a/wireguard.nix b/wireguard.nix new file mode 100644 index 0000000..3e52e72 --- /dev/null +++ b/wireguard.nix @@ -0,0 +1,41 @@ +{ config, pkgs, lib, ... }: +let + port = 51820; + name = "wg0"; + peers = [ + { + PublicKey = "XI0/k2j20CVSfevwjkmo4IddVoA2VY2fN6feauXYEXU="; + AllowedIPs = [ "10.100.0.2" ]; + } # radish + ]; + address = [ "10.100.0.1/24" ]; +in +{ + networking.firewall.allowedUDPPorts = [ port ]; + networking.useNetworkd = true; + + systemd.network = { + enable = true; + netdevs.${name} = { + netdevConfig = { + Kind = "wireguard"; + Name = "${name}"; + MTUBytes = "1300"; + }; + wireguardConfig = { + PrivateKeyFile = "/var/secrets/wireguard-privkey"; + ListenPort = port; + }; + wireguardPeers = peers; + }; + + networks.${name} = { + matchConfig.Name = name; + inherit address; + networkConfig = { + IPMasquerade = "ipv4"; + IPForward = true; + }; + }; + }; +}