diff --git a/servers/hetzner/modules/services/caddy.nix b/servers/hetzner/modules/services/caddy.nix index 53d10bb..37572bf 100644 --- a/servers/hetzner/modules/services/caddy.nix +++ b/servers/hetzner/modules/services/caddy.nix @@ -24,7 +24,7 @@ in { # Global Caddyfile snippets (shared across all virtual hosts). extraConfig = '' (admin_gate) { - @notvpn not remote_ip 10.8.0.0/24 + @notvpn not remote_ip 127.0.0.1 ::1 10.8.0.0/24 fd10:8::/64 49.13.92.205 2a01:4f8:c014:2585::1 respond @notvpn "Forbidden" 403 } # Restrict access to the server itself (loopback + public IPs) or the @@ -245,7 +245,6 @@ in { import security_headers import csp ${antiScrape} - import admin_gate reverse_proxy 127.0.0.1:5000 encode zstd gzip ''; diff --git a/servers/hetzner/modules/services/virtualcam.nix b/servers/hetzner/modules/services/virtualcam.nix index 2ff0c24..3bebbd9 100644 --- a/servers/hetzner/modules/services/virtualcam.nix +++ b/servers/hetzner/modules/services/virtualcam.nix @@ -4,8 +4,8 @@ unstablePkgs, ... }: let - rev = "3b45cc1233f11a40a756b371c9e2813c78a1ca82"; - apiRev = "a73f4c4be840444072b0a7f5458438a34b470ea9"; + rev = "6e351ddc732421eb775eb9843ccd2389d6525edd"; + apiRev = "390878d126185b21a14479f85c70134a155c61c6"; # Private repositories are fetched over SSH (port 2222). nix-daemon runs as # root and uses /root/.ssh (identity materialized by the git-ssh-key unit), @@ -31,7 +31,7 @@ pname = "virtualcam-website"; version = "0.1.0"; src = srcPatched; - npmDepsHash = "sha256-0g98Jh/RwoicjrfiSbfqNo331k3ab8hINjV6dHHN0y4="; + npmDepsHash = "sha256-GodWQKtOtsLOjjiwzxun+wTPhtvjR2uCV91n+wiZHw4="; nodejs = unstablePkgs.nodejs; buildPhase = '' @@ -50,6 +50,7 @@ ''; APP_URL = "https://virtualcam.severijnse.eu"; + GOOGLE_CLIENT_ID = "754775011707-c699m092tv3icmovhk5qa106v3q6eh7c.apps.googleusercontent.com"; # Only used to satisfy prisma generate / next build metadata resolution. DATABASE_URL = "postgresql://virtualcam@localhost/virtualcam?host=/run/postgresql&schema=public"; # Use the nixpkgs-bundled Prisma engine so the sandboxed offline build does @@ -94,7 +95,7 @@ chmod 0600 "${envFile}" ${pkgs.sops}/bin/sops --decrypt --input-type yaml --output-type yaml ${secretsFile} | ${pkgs.gnused}/bin/sed -nE \ - 's/^virtualcam_license_signing_key: (.*)/LICENSE_SIGNING_KEY=\1/p; s/^virtualcam_admin_token: (.*)/ADMIN_TOKEN=\1/p; s/^virtualcam_smtp_pass: (.*)/SMTP_PASS=\1/p' \ + 's/^virtualcam_license_signing_key: (.*)/LICENSE_SIGNING_KEY=\1/p; s/^virtualcam_admin_token: (.*)/ADMIN_TOKEN=\1/p; s/^virtualcam_smtp_pass: (.*)/SMTP_PASS=\1/p; s/^virtualcam_google_OAuth_secret: (.*)/GOOGLE_CLIENT_SECRET=\1/p; s/^shkeeper_api_key: (.*)/SHKEEPER_API_KEY=\1/p' \ >> "${envFile}" ''; @@ -220,8 +221,8 @@ in { virtualcam = { description = "Virtualcamera website (Next.js)"; - after = ["postgresql.service" "virtualcam-migrate.service" "virtualcam-seed.service" "virtualcam-secrets.service"]; - requires = ["postgresql.service" "virtualcam-migrate.service" "virtualcam-seed.service" "virtualcam-secrets.service"]; + after = ["postgresql.service" "podman-shkeeper.service" "virtualcam-migrate.service" "virtualcam-seed.service" "virtualcam-secrets.service"]; + requires = ["postgresql.service" "podman-shkeeper.service" "virtualcam-migrate.service" "virtualcam-seed.service" "virtualcam-secrets.service"]; wantedBy = ["multi-user.target"]; path = [unstablePkgs.nodejs]; serviceConfig = { @@ -237,8 +238,12 @@ in { Environment = [ "DATABASE_URL=${dbUrl}" "APP_URL=https://virtualcam.severijnse.eu" + "GOOGLE_CLIENT_ID=754775011707-c699m092tv3icmovhk5qa106v3q6eh7c.apps.googleusercontent.com" "PAYMENTS_MODE=shkeeper" - "BYPASS_PAYMENTS=true" + "BYPASS_PAYMENTS=false" + "SHKEEPER_URL=https://pay.severijnse.eu" + "SHKEEPER_CRYPTO=BTC" + "SHKEEPER_FIAT=USD" "ADMIN_EMAILS=jory@severijnse.eu" "SMTP_HOST=mail.severijnse.eu" "SMTP_PORT=587" @@ -253,8 +258,8 @@ in { virtualcam-api = { description = "Virtualcamera license API (Go/Fiber)"; - after = ["postgresql.service" "virtualcam-migrate.service" "virtualcam-secrets.service"]; - requires = ["postgresql.service" "virtualcam-migrate.service" "virtualcam-secrets.service"]; + after = ["postgresql.service" "podman-shkeeper.service" "virtualcam-migrate.service" "virtualcam-secrets.service"]; + requires = ["postgresql.service" "podman-shkeeper.service" "virtualcam-migrate.service" "virtualcam-secrets.service"]; wantedBy = ["multi-user.target"]; serviceConfig = { User = "virtualcam"; diff --git a/servers/hetzner/secrets/secrets.yaml b/servers/hetzner/secrets/secrets.yaml index 299bda1..fa6eef7 100644 --- a/servers/hetzner/secrets/secrets.yaml +++ b/servers/hetzner/secrets/secrets.yaml @@ -1,3 +1,4 @@ +shkeeper_api_key: ENC[AES256_GCM,data:kUymtefYJOllK5cxKHhD3HnXO/uo1w==,iv:OH9ZaQJZsFfo00BIl5MlRw1XBzHUmFi1FW54/J6O/8Q=,tag:HQJyuEoz5fsDi7iMq3PEzw==,type:str] restic_password: ENC[AES256_GCM,data:OHQlxUpNnTqMQm6A/o3ID/3F91NpVKOrsFYdLqrtI4vp+6TWHR8=,iv:bBd+gfi78lgTaTv0QUWYGQWPsurrzx90VvOzA2d2euA=,tag:qsHSdAHx1auwdZCgn2O5Qw==,type:str] b2_key_id: ENC[AES256_GCM,data:4B9rvg06baH6aNiT,iv:Qk1ToF3lMYLTrZdzpfaoGVzdiKYs492w9fzn4/TbNfQ=,tag:djxfqwgNZmRGqvteTX9G3w==,type:str] b2_application_key: ENC[AES256_GCM,data:xGAbBqx+6ErK7sy3FR0yza6mJU5oc5uQQGcwKtcPp1Ef4XEVd8do/wN7,iv:CojcoykDRBfvN8yqMMrPJq9mtAwxyswqXXVBKPupxDs=,tag:BkfFHAGJvtCDUpFoxXVP3Q==,type:str] @@ -7,6 +8,7 @@ virtualcam_license_signing_key: ENC[AES256_GCM,data:zk8YDER9d9mBOdXgEKKC6dubSMfz virtualcam_admin_token: ENC[AES256_GCM,data:JC5zSFBCoEapxv/Kcs4VXk3HAkiqwXVrCv1rlqFsXVx3LGspnQdzjOIahlM=,iv:GRVfMNGkwC3xXR00ww29rFbhTrpuViad+H05yDhR9BA=,tag:OBnxBD/8KU4mn17FFTcdng==,type:str] git_ssh_key_b64: ENC[AES256_GCM,data:LaUcR005w9iCd/DifDhzLM7tU4AuTiFM802gMU1HMtvFN2iSffucaFJWxpKv2zFxDxz0QpA3XwM1M5yJC4K3YFMxPkPXcWLYN4yHcc1yXuoB3SseQXjcJnPMqZvJfVYhHep+6CVVlVDQs1Y+miBvbAhrvCEblwUu5LhD7yvoJLwTnEpT15WGDvqezzYKzNSyQGNRa8KPjsD/7gJN3RyUPzKo6GsrIp8d8eOTuCZwEcJVDKE0ACXs4V6cd+akqIWZkNPyilnMTuK5cqg2YuqSpwu9NncKED6SjmPiozPKKgTVaWhNCRJUTBfIw85fdXizvq7PNbNRxxBsscAWd0ixXiLqg1RTipfv85wL4Nru3r3qcQGAWmOpTHKW5fA9kR4ygdNxEVkOgQ70m9U0wev+vdIJUoRYj09Ikobej370NKppOP6+oeEDE7NpkFH7tzRk1oHtwoc1dwP9Kq1T8XdxttCKFyb1pAJ6gMdMThCfJlC9/Uu/WYbYVu5bCj6BAmrdrmhbPrsEOylBeC9j9RhyRrFEqLd8AZ01Zg8oKcj9WtCWEMf9Y4biv2xE43JbBGRvLAx3sH9MRplu2hN2W/bRxa/EPj9GHgbUjScDBkm/QVbMeV+QOgi09sCHDTeSX3BHdZ8ZLNjuNUwYnWZq4lPix0iYS5MufiixNdQmncPeHq0UuBtVifEl2Jmjq1COLyeAQe47AKQ5zDjT91xtBRZVZEVk0kGBYHtBEJ9ezPwckSw=,iv:cbIpwwhmyJVvvTMB95YBzt+RQLOji6yJh+SpcJc3Q1Y=,tag:t8WxU1IPDfkB8muTdBLUhg==,type:str] virtualcam_smtp_pass: ENC[AES256_GCM,data:D5kDTQP9/YV5BjAWeTn0G2zKe+s=,iv:7dZJprrs0S2ECtbDQuvhUWsU0Xzpld5/XZqdbyefg0o=,tag:uWe811KAisBJ5M1EhJjrcQ==,type:str] +virtualcam_google_OAuth_secret: ENC[AES256_GCM,data:kPJIP4iH2vFo+VRojvhjzrQhDWidFq7kjC7ZaFcwJ7dNHlo=,iv:qKWClwSIRPU2Xz50bGYqU+eMR/iFxqnaKkb18eL3aMU=,tag:78jGQgL1myDBMiZP8GZ80g==,type:str] sops: kms: [] gcp_kms: [] @@ -40,8 +42,8 @@ sops: MHJrVVpDYWdJNmxtUkozSzR4Nmt3R28KrhYi830HUFAPfg8WvPad7BAuNe1mYOWt WEFIquuX/H/N+y/7uQcBDbvnBzyropE1hW8aNrxSKMeawvQZWNXkZA== -----END AGE ENCRYPTED FILE----- - lastmodified: "2026-08-15T15:47:14Z" - mac: ENC[AES256_GCM,data:I28P0NVocgflBTd27KrVOV2Nh5cUpuv8yL13Z54dFron3g27j0sr5PJMc7ZzTkHvKrU+gwBxPBmldh/q3QB50Mz3bK4S3b8O5hPp7xR4mc3ajQwMPaqLj7A6aeXsixIQVDfZEHtXpWB4DKaA8FLYKOZBAXhW2f1SGWnVJwKqn9M=,iv:fMlP/VxGN3y+d0unBA87qfUaT51MIQsAKsuEXTv3qDg=,tag:yjaSL1ymvdpGDuy7OdANZA==,type:str] + lastmodified: "2026-08-19T10:30:19Z" + mac: ENC[AES256_GCM,data:JOWFguh2iE4+OyU00l+2gn7GWv2yej37OLLhVVO6Yb7Kv4vgk4NhZKJLqopteQK1o6dPeWbeIydHG1Qmef0Sm0NmCyi7i6BCTplVizf/puaGjpkU5YAs90+HiEa9cKlNQ5brfNH3YecJeN9dK+d7o8bMO/xPv3raqFMBBoVtgu4=,iv:A7kCOzyWwiVaXKVMKXQ4j86zz2f65wAjOtaVEuLa81I=,tag:bcbPsmRRFRHX7qi4WdYb0g==,type:str] pgp: [] unencrypted_suffix: _unencrypted version: 3.8.1 diff --git a/system/nix/default.nix b/system/nix/default.nix index 9625853..084050b 100644 --- a/system/nix/default.nix +++ b/system/nix/default.nix @@ -19,6 +19,16 @@ in { package = pkgs.lix; + gc = { + automatic = true; + dates = "weekly"; + options = "--delete-older-than 14d"; + }; + + optimise = { + automatic = true; + }; + # pin the registry to avoid downloading and evaling a new nixpkgs version every time registry = lib.mapAttrs (_: v: {flake = v;}) flakeInputs;