diff --git a/flake.lock b/flake.lock index 8d6523b..9d6d124 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,24 @@ { "nodes": { + "copyparty": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1753554171, + "narHash": "sha256-pYkP9F7J1Dx3oQH+ZeoDSVNF+4rfRUJDxR05hA+0Skk=", + "owner": "9001", + "repo": "copyparty", + "rev": "48705a74c6d6c8c1dd7595deaf4e2af65c0adcb0", + "type": "github" + }, + "original": { + "owner": "9001", + "repo": "copyparty", + "type": "github" + } + }, "disko": { "inputs": { "nixpkgs": [ @@ -20,6 +39,21 @@ "type": "github" } }, + "flake-utils": { + "locked": { + "lastModified": 1678901627, + "narHash": "sha256-U02riOqrKKzwjsxc/400XnElV+UtPUQWpANPlyazjH0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "93a2b84fc4b70d9e089d029deacc3583435c2ed6", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, "home-manager": { "inputs": { "nixpkgs": [ @@ -58,6 +92,21 @@ } }, "nixpkgs": { + "locked": { + "lastModified": 1748162331, + "narHash": "sha256-rqc2RKYTxP3tbjA+PB3VMRQNnjesrT0pEofXQTrMsS8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "7c43f080a7f28b2774f3b3f43234ca11661bf334", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-25.05", + "type": "indirect" + } + }, + "nixpkgs_2": { "locked": { "lastModified": 1753345091, "narHash": "sha256-CdX2Rtvp5I8HGu9swBmYuq+ILwRxpXdJwlpg8jvN4tU=", @@ -75,10 +124,11 @@ }, "root": { "inputs": { + "copyparty": "copyparty", "disko": "disko", "home-manager": "home-manager", "nixos-hardware": "nixos-hardware", - "nixpkgs": "nixpkgs", + "nixpkgs": "nixpkgs_2", "sops-nix": "sops-nix" } }, diff --git a/flake.nix b/flake.nix index ab01ab4..5c6a426 100644 --- a/flake.nix +++ b/flake.nix @@ -17,6 +17,8 @@ url = "github:Mic92/sops-nix"; inputs.nixpkgs.follows = "nixpkgs"; }; + + copyparty.url = "github:9001/copyparty"; }; outputs = { diff --git a/main/default.nix b/main/default.nix index 65eebe9..f99d23c 100644 --- a/main/default.nix +++ b/main/default.nix @@ -137,7 +137,7 @@ in { # Reverse Proxy reverse-proxy = { nginx.enable = false; # TODO does not work for some reason - traefik.enable = false; # TODO has issues retrieving certificate from duckdns + traefik.enable = true; # TODO has issues retrieving certificate from duckdns caddy.enable = false; # TODO has issues retrieving certificate from duckdns }; @@ -145,6 +145,10 @@ in { podman.enable = false; docker.enable = true; }; + + social.matrix.enable = false; # TODO does not work :) + + file-server.copyparty.enable = false; }; # DO NOT CHANGE AT ANY POINT! diff --git a/main/secrets/secrets.yaml b/main/secrets/secrets.yaml index 1c4a2d9..f5760a7 100644 --- a/main/secrets/secrets.yaml +++ b/main/secrets/secrets.yaml @@ -10,6 +10,7 @@ example_booleans: - ENC[AES256_GCM,data:5VhbnIk=,iv:sRnE8roVMQVs1Dk9tOtALWiDtfM4aJiSX5gb/MDHak8=,tag:egUULcUP5vCsy5uUM+j6dA==,type:bool] user_password: ENC[AES256_GCM,data:Q7rk67ylyjr5Sa+AYCxnQAPLbBP5Fy85wTGLZuqxBG3iJ+MmhEgfeatVA2tcsY7GSaU/vghny+TJtrvhDYYMqa10h/F0wPxUjId78qkhKbnRQs4mqAxA9heSi4ojp1kh/pXN7tj64wNyJA==,iv:FTUojVNz78tn/Uj1N8Oj5Iov9eEMRo5vz+mqHdewxjg=,tag:YF74hLXXUby0IjHrqdkBUQ==,type:str] duckdns-token: ENC[AES256_GCM,data:Gf3kIpOO/X+ZVXV4w71Fp5qMuNedBBoobazAFpp22RC70xKb6xsJVffWdtFq0blDe5Y=,iv:SNq6wnhG6CuDwB3NQ/PryTgY3U/J2g1XfGCW7gSEYbo=,tag:MWqhrJRreGZ/SaapAaCXQA==,type:str] +matrix_secret: ENC[AES256_GCM,data:U1yPFsFeLA5tbFf/MMACrhmH/32zUMUg2HOHWdAtcm+ybg9KgjhQmbGDM/MTDoRaAa+Zqfs774gz3A6Rg4HLuvCr4cPotSCHH8qRPz+UDK4Bvf305EfLP22Rrhc=,iv:A9BSgw1hHg+y8x4GC4hWNBCaYZNlRfS1+jKKv38znXg=,tag:SkwEfez7TRhFuLEL4PkvZA==,type:str] sops: age: - recipient: age19wvqtn4ju6k4vs8fxr34unl6xx4cv04jw0lx9ps20xlde927zfssgl4qke @@ -30,7 +31,7 @@ sops: NHdWQnlGbk43WS80VDkxV0o4TE5uSUUK0WSdFzR3u0pLUYHXaTMrtBm0sKKe9ZPG nF90b/jv66WGIH1n2oFaaohCkd7DZGzSpr0+KsqX6pkszYnp39YC5A== -----END AGE ENCRYPTED FILE----- - lastmodified: "2025-07-26T13:53:03Z" - mac: ENC[AES256_GCM,data:WJJxd7d/Ld3z54JMgB7RhiBzy1P/hW14kRjfpX4pRIKzNzvUEivh1FQ1NUbonAGXrZZhE0WNPQaLcv185KeqXLF3NxWTawH+he+/uZr+cqcLU8Ylnyt4sbDDUCJgfo8HU0d+7xWrXblNqWQDHcEvm+KoSgwFYfBVGGvpCOv/mIs=,iv:jRMxA37VB21CQ1DqtKGYAMBHkf1O6bi65fvB0yh7roU=,tag:k29jd2jP137EkemkE4p2fw==,type:str] + lastmodified: "2025-07-26T21:14:39Z" + mac: ENC[AES256_GCM,data:76/u+mXqsYQA0Y5rcUskN2Uh8nCKyZxPk3yLd4F/zXnfOe6eqLBAfwvZ2XGu1Y+KQEMidSvrd+7WJ9bPHFxbftglIIeU8NxdXqgQZrH2Bx6kMgGzSR72IzYOJvl5rPsYa3mjRIcaBdyE7oo3ZSQctHlf40zEaTNesNgjVPgvWhs=,iv:yYq5knPV7JdvnkC18/MFg1/6W1cx2d7zAtRCe/C2Txg=,tag:jc7grjZajT2TH3TzLVQ82Q==,type:str] unencrypted_suffix: _unencrypted version: 3.10.2 diff --git a/modules/default.nix b/modules/default.nix index 7b52442..1e07eec 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -4,5 +4,7 @@ imports = [ ./reverse-proxy ./virtualisation + ./social + ./file-server ]; } diff --git a/modules/file-server/copyparty/default.nix b/modules/file-server/copyparty/default.nix new file mode 100644 index 0000000..eb3533d --- /dev/null +++ b/modules/file-server/copyparty/default.nix @@ -0,0 +1,19 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.dov.file-server.copyparty; +in { + options.dov.file-server.copyparty = { enable = mkEnableOption "copyparty config"; }; + + config = mkIf cfg.enable { + # # add the copyparty overlay to expose the package to the module + # nixpkgs.overlays = [ copyparty.overlays.default ]; + # # (optional) install the package globally + # environment.systemPackages = [ pkgs.copyparty ]; + # # configure the copyparty module + # services.copyparty.enable = cfg.enable; + }; + +} diff --git a/modules/file-server/default.nix b/modules/file-server/default.nix new file mode 100644 index 0000000..af1944f --- /dev/null +++ b/modules/file-server/default.nix @@ -0,0 +1,7 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./copyparty + ]; +} diff --git a/modules/reverse-proxy/traefik/default.nix b/modules/reverse-proxy/traefik/default.nix index c65d05c..8af18a9 100644 --- a/modules/reverse-proxy/traefik/default.nix +++ b/modules/reverse-proxy/traefik/default.nix @@ -4,24 +4,26 @@ with lib; let cfg = config.dov.reverse-proxy.traefik; + configFile = pkgs.writeText "duckdns-options" + '' + DUCKDNS_PROPAGATION_TIMEOUT=120 + ''; in { options.dov.reverse-proxy.traefik = { enable = mkEnableOption "traefik config"; }; config = mkIf cfg.enable { - # 1. SOPS Configuration for the DuckDNS Token - # This decrypts the secret and provides it to the Traefik service. + networking.firewall.allowedTCPPorts = [ 80 443 53 ]; + sops.secrets.duckdns-token = { - # The Traefik service needs permission to read this file. owner = "traefik"; group = config.services.traefik.group; }; - # 3. Traefik Service Configuration services.traefik = { enable = true; # Load the DuckDNS token as an environment variable for Traefik. - environmentFiles = [ config.sops.secrets.duckdns-token.path ]; + environmentFiles = [ config.sops.secrets.duckdns-token.path configFile ]; # Static configuration (traefik.yml) - defines entrypoints and certificate resolvers. staticConfigOptions = { @@ -53,11 +55,7 @@ in { # Use the DNS-01 challenge with the DuckDNS provider dnsChallenge = { provider = "duckdns"; - # Traefik will get the DUCKDNS_TOKEN from the environment file. - resolvers = [ - "1.1.1.1:53" - "8.8.8.8:53" - ]; + disablePropagationCheck = true; }; }; }; @@ -73,14 +71,14 @@ in { routers = { # --- Router for the Traefik dashboard (optional) --- dashboard-router = { - rule = "Host(`traefik.local.susano-traefik.duckdns.org`)"; # Example: A local-only subdomain + rule = "Host(`traefik.susano-test.duckdns.org`)"; # Example: A local-only subdomain entryPoints = [ "websecure" ]; service = "api@internal"; # Special service for the dashboard tls.certResolver = "duckdns"; }; immich-router = { - rule = "Host(`immich.susano-traefik.duckdns.org`)"; # 1. The new domain + rule = "Host(`immich.susano-test.duckdns.org`)"; # 1. The new domain entryPoints = [ "websecure" ]; # 2. Listen on HTTPS service = "immich-service"; # 3. Link to the new Immich service tls.certResolver = "duckdns"; # 4. Use the same SSL resolver diff --git a/modules/social/default.nix b/modules/social/default.nix new file mode 100644 index 0000000..cf8f6ac --- /dev/null +++ b/modules/social/default.nix @@ -0,0 +1,7 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./matrix + ]; +} diff --git a/modules/social/matrix/default.nix b/modules/social/matrix/default.nix new file mode 100644 index 0000000..f8aee68 --- /dev/null +++ b/modules/social/matrix/default.nix @@ -0,0 +1,56 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.dov.social.matrix; + fqdn = "matrix.susano-tailscale.duckdns.org"; + baseUrl = "https://${fqdn}"; + clientConfig."m.homeserver".base_url = baseUrl; + serverConfig."m.server" = "${fqdn}:443"; + mkWellKnown = data: '' + default_type application/json; + add_header Access-Control-Allow-Origin *; + return 200 '${builtins.toJSON data}'; + ''; +in { + options.dov.social.matrix = { + enable = mkEnableOption "docker config"; + }; + + config = mkIf cfg.enable { + sops.secrets.matrix_secret = { + owner = "matrix-synapse"; + group = "matrix-synapse"; + }; + + networking.firewall.allowedTCPPorts = [ 80 443 ]; + + services.postgresql.enable = true; + + services.matrix-synapse = { + enable = true; + settings = { + server_name = "susano-tailscale"; + # The public base URL value must match the `base_url` value set in `clientConfig` above. + # The default value here is based on `server_name`, so if your `server_name` is different + # from the value of `fqdn` above, you will likely run into some mismatched domain names + # in client applications. + public_baseurl = baseUrl; + listeners = [{ + port = 8008; + bind_addresses = [ "::1" ]; + type = "http"; + tls = false; + x_forwarded = true; + resources = [{ + names = [ "client" "federation" ]; + compress = true; + }]; + }]; + }; + + extraConfigFiles = [ "/run/secrets/matrix_secret" ]; + }; + }; +}