commit cca6abb1967ba34b30e956ea0f5e32c905445023 Author: System administrator Date: Mon Jul 1 22:19:14 2024 +0300 initial commit 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; + }; + }; + }; +}