From 9a4ed1b04b78b15e02280523ed84c5d3a16967bb Mon Sep 17 00:00:00 2001 From: OlivierChiasson Date: Fri, 29 May 2026 00:08:10 -0300 Subject: [PATCH] Rebase to flake parts #11 --- flake.lock | 58 ++++++++++++++++++- flake.nix | 6 ++ modules/hosts/14900k/configuration.nix | 1 + .../hosts/nix-server/SOPS-personal-website.md | 18 ++++++ .../_services/cloudflare-dyndns.nix | 26 +++++++++ modules/hosts/nix-server/_services/gitea.nix | 47 +++++++++++++++ .../nix-server/_services/personal-website.nix | 56 ++++++++++++++++++ modules/hosts/nix-server/configuration.nix | 3 + modules/hosts/nix-server/secrets.yaml | 26 +++++---- modules/lib/ssh-inventory.nix | 6 +- modules/system/default.nix | 1 + 11 files changed, 232 insertions(+), 16 deletions(-) create mode 100644 modules/hosts/nix-server/SOPS-personal-website.md create mode 100644 modules/hosts/nix-server/_services/cloudflare-dyndns.nix create mode 100644 modules/hosts/nix-server/_services/gitea.nix create mode 100644 modules/hosts/nix-server/_services/personal-website.nix diff --git a/flake.lock b/flake.lock index 99366be..77c6546 100644 --- a/flake.lock +++ b/flake.lock @@ -186,7 +186,25 @@ }, "flake-utils": { "inputs": { - "systems": "systems_2" + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_3" }, "locked": { "lastModified": 1731533236, @@ -485,6 +503,24 @@ "type": "github" } }, + "personal-website": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1779905483, + "narHash": "sha256-+j7FvKPMIp5SFgZscLSXd33hiFJHbpLXH5ImXWq7RXc=", + "path": "/home/olivier/Projects/Personal-Website", + "type": "path" + }, + "original": { + "type": "git", + "url": "https://git.chiasson.cloud/Olivier/Personal-Website" + } + }, "quickshell": { "inputs": { "nixpkgs": [ @@ -523,6 +559,7 @@ "nixpkgs": "nixpkgs", "nur": "nur", "oom-hardware": "oom-hardware", + "personal-website": "personal-website", "sops-nix": "sops-nix", "spicetify-nix": "spicetify-nix", "swiftshare": "swiftshare", @@ -558,7 +595,7 @@ "nixpkgs": [ "nixpkgs" ], - "systems": "systems" + "systems": "systems_2" }, "locked": { "lastModified": 1779000518, @@ -576,7 +613,7 @@ }, "swiftshare": { "inputs": { - "flake-utils": "flake-utils", + "flake-utils": "flake-utils_2", "nixpkgs": [ "nixpkgs" ] @@ -625,6 +662,21 @@ "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" + } + }, "t2fanrd": { "inputs": { "nixpkgs": [ diff --git a/flake.nix b/flake.nix index 6763ba7..07ab624 100644 --- a/flake.nix +++ b/flake.nix @@ -92,6 +92,12 @@ inputs.nixpkgs.follows = "nixpkgs"; }; + # After pushing Personal-Website, `nix flake update personal-website` refreshes the lock pin. + personal-website = { + url = "git+https://git.chiasson.cloud/Olivier/Personal-Website"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + # DDRM browser-extension backend ddrm = { url = "git+https://git.chiasson.cloud/Olivier/DDRM"; diff --git a/modules/hosts/14900k/configuration.nix b/modules/hosts/14900k/configuration.nix index 10dd87a..86ea482 100644 --- a/modules/hosts/14900k/configuration.nix +++ b/modules/hosts/14900k/configuration.nix @@ -124,6 +124,7 @@ services.cloudflare-warp.enable = true; thunderbird prismlauncher + dualsensectl ]; diff --git a/modules/hosts/nix-server/SOPS-personal-website.md b/modules/hosts/nix-server/SOPS-personal-website.md new file mode 100644 index 0000000..f788d74 --- /dev/null +++ b/modules/hosts/nix-server/SOPS-personal-website.md @@ -0,0 +1,18 @@ +# personal-website sops secrets + +Add these keys to `secrets.yaml` (on a host with your age key): + +```yaml +personal-website: + ghcr-token: + database-password: + auth-secret: + oauth-discord-client-secret: +``` + +```bash +cd modules/hosts/nix-server +sops secrets.yaml +``` + +After editing, verify with `sops -d secrets.yaml | yq '.personal-website'`. diff --git a/modules/hosts/nix-server/_services/cloudflare-dyndns.nix b/modules/hosts/nix-server/_services/cloudflare-dyndns.nix new file mode 100644 index 0000000..10ba099 --- /dev/null +++ b/modules/hosts/nix-server/_services/cloudflare-dyndns.nix @@ -0,0 +1,26 @@ +# Cloudflare dynamic DNS via NixOS (kissgyorgy/cloudflare-dyndns). +{ config, ... }: +let + secretFilePath = ../secrets.yaml; +in +{ + sops.secrets."cloudflare-ddns/api-token".sopsFile = secretFilePath; + + services.cloudflare-dyndns = { + enable = true; + apiTokenFile = config.sops.secrets."cloudflare-ddns/api-token".path; + domains = [ + "chiasson.cloud" + "chiassoncloud.services" + "swiftshare.cloud" + "blackfry.day" + "yestur.day" + "rp-own.life" + "xn--1iu.cc" + ]; + proxied = true; + ipv4 = true; + ipv6 = false; + # Default: *:0/5 (every 5 minutes). + }; +} diff --git a/modules/hosts/nix-server/_services/gitea.nix b/modules/hosts/nix-server/_services/gitea.nix new file mode 100644 index 0000000..173e4cd --- /dev/null +++ b/modules/hosts/nix-server/_services/gitea.nix @@ -0,0 +1,47 @@ +{ lib, ... }: +{ + services.gitea = { + enable = true; + + # Migrated sqlite DB and repos; do not provision a fresh database. + database = { + type = "sqlite3"; + createDatabase = false; + }; + + settings = { + server = { + DOMAIN = "git.chiasson.cloud"; + HTTP_PORT = 3002; + ROOT_URL = "https://git.chiasson.cloud/"; + # Clone URLs and LAN git@… -p 222 (was Docker host 222 → container 22). + # Port 222 is <1024 (privileged); systemd must grant CAP_NET_BIND_SERVICE below. + SSH_PORT = 222; + START_SSH_SERVER = true; + SSH_LISTEN_HOST = "0.0.0.0"; + SSH_LISTEN_PORT = 222; + }; + + service.DISABLE_REGISTRATION = false; + }; + }; + + # First boot after migration runs DB migrate + hook regen; default WatchdogSec=30 kills + # gitea while storage/actions init is still running. Type=notify also fails if startup + # is slow; PrivateUsers breaks access to migrated files owned by the real gitea uid. + # Port 222 is privileged (<1024); Docker mapped host 222→container 22 as root. + systemd.services.gitea.serviceConfig = { + Type = lib.mkForce "simple"; + PrivateUsers = lib.mkForce false; + NoNewPrivileges = lib.mkForce false; + AmbientCapabilities = "CAP_NET_BIND_SERVICE"; + CapabilityBoundingSet = lib.mkForce [ "CAP_NET_BIND_SERVICE" ]; + TimeoutStartSec = lib.mkForce "20min"; + WatchdogSec = lib.mkForce 0; + }; + + networking.firewall.allowedTCPPorts = [ + 3002 + 222 + ]; +} diff --git a/modules/hosts/nix-server/_services/personal-website.nix b/modules/hosts/nix-server/_services/personal-website.nix new file mode 100644 index 0000000..c8310c0 --- /dev/null +++ b/modules/hosts/nix-server/_services/personal-website.nix @@ -0,0 +1,56 @@ +{ config, ... }: +let + secretFilePath = ../secrets.yaml; +in +{ + sops.secrets."personal-website/database-password".sopsFile = secretFilePath; + sops.secrets."personal-website/auth-secret".sopsFile = secretFilePath; + sops.secrets."personal-website/oauth-discord-client-secret".sopsFile = secretFilePath; + + sops.templates."personal-website-postgres.env" = { + content = '' + POSTGRES_PASSWORD=${config.sops.placeholder."personal-website/database-password"} + POSTGRES_USER=chiassoncloud + POSTGRES_DB=chiassoncloud + ''; + }; + + sops.templates."personal-website.env" = { + content = '' + DATABASE_URL=postgresql://chiassoncloud:${config.sops.placeholder."personal-website/database-password"}@personal-website-db:5432/chiassoncloud + AUTH_SECRET=${config.sops.placeholder."personal-website/auth-secret"} + AUTH_DISCORD_SECRET=${config.sops.placeholder."personal-website/oauth-discord-client-secret"} + ''; + }; + + services.personalWebsite = { + enable = true; + + app = { + image = "ghcr.io/olivierchiasson/personal-website:main"; + ghcr = { + username = "olivierchiasson"; + passwordFile = config.sops.secrets."swiftshare/ghcr-token".path; + }; + + port = 3001; + authUrl = "https://chiasson.cloud"; + publicUrl = "https://chiasson.cloud"; + disableTelemetry = true; + environmentFiles = [ config.sops.templates."personal-website.env".path ]; + }; + + database = { + user = "chiassoncloud"; + name = "chiassoncloud"; + environmentFiles = [ config.sops.templates."personal-website-postgres.env".path ]; + }; + + auth.discord.clientId = "1400660345068191855"; + + umami = { + websiteId = "3b2f29d3-11b8-4a3b-bc76-bda3f27926d1"; + scriptUrl = "https://analytics.chiasson.cloud/script.js"; + }; + }; +} diff --git a/modules/hosts/nix-server/configuration.nix b/modules/hosts/nix-server/configuration.nix index f0e32a4..951934e 100644 --- a/modules/hosts/nix-server/configuration.nix +++ b/modules/hosts/nix-server/configuration.nix @@ -18,6 +18,7 @@ ./_services/portainer.nix ./_services/organizr.nix ./_services/swiftshare.nix + ./_services/personal-website.nix ./_services/immich.nix ./_services/jellyfin.nix ./_services/nixdesk-nfs-client.nix @@ -29,6 +30,8 @@ ./_services/qbittorrent.nix ./_services/seerr.nix ./_services/dispatcharr.nix + ./_services/gitea.nix + ./_services/cloudflare-dyndns.nix ]; boot.loader.grub = { diff --git a/modules/hosts/nix-server/secrets.yaml b/modules/hosts/nix-server/secrets.yaml index 194b0ce..325b3dc 100644 --- a/modules/hosts/nix-server/secrets.yaml +++ b/modules/hosts/nix-server/secrets.yaml @@ -1,5 +1,5 @@ swiftshare: - ghcr-token: ENC[AES256_GCM,data:wNzBA8Ib5WjxoKkGiWkfeGspKzy/vzbwwAp/+cjRF9Vsmlyx67OovQ==,iv:MCrkALYCHiPDb1tNQaWRrxuYSRXD6JtzJzEOr1aqhBk=,tag:okQfIP5IJUUIFfwAlZM1ow==,type:str] + ghcr-token: ENC[AES256_GCM,data:V/5dLVLv4BbAxdMiBxXgmNbK17HAQkqzHJA2NWzOFfFlcy3dq8SnZQ==,iv:YTB3Bef+kZXunXVUCkFj/YZo1POdx2K+bNvzarSJ1Iw=,tag:HEBT4ZKMXTIy+ZEkNx3rHw==,type:str] database-password: ENC[AES256_GCM,data:r9GSaoQ7bS644ipb3kU=,iv:KYDTzYtjfz5meDb0nemY1lhSFEorKHL0hSRIcQaHg5c=,tag:RVjAfb8XGsybAgIc2/hH+g==,type:str] auth-secret: ENC[AES256_GCM,data:tTXLMWASBfF49gBFrf+CZ3R4oTt7hEGUhAqEdvoQtm0zbb2VUhTq7y4tH/c=,iv:Halfu9hBex4SEUMHLAicqApTxZP0NV9pJZTr+bBSek4=,tag:1WqN75zT+zoka9sIXOJGfQ==,type:str] oauth-discord-client-secret: ENC[AES256_GCM,data:a9Iarcpl1HOFXdsDMh3H662T8yqVvGtfguVICwWVrAg=,iv:LsUserWQcEDV0TiRWj1sHh5/ZiFQzyc1gRWg+Ewwjik=,tag:33Ml08oHVXl0ZMmiwQ2mig==,type:str] @@ -11,10 +11,15 @@ swiftshare: minio-secret-key: ENC[AES256_GCM,data:szkx+MTbMWmfbQ==,iv:+1zlHJRKMR4XDv1rrkOeilz06YA1W/1o+egylm/ZjPs=,tag:70QO3dPp9WRd71Puzl47QA==,type:str] immich: database-password: ENC[AES256_GCM,data:YWLt2pty/yVrrF7K,iv:uqrQGfST/A6LzRZ4+O0puXA1bd/7CL5A/T7jU+/++X8=,tag:/gNGK3z4RembX+tBET4M5g==,type:str] +personal-website: + database-password: ENC[AES256_GCM,data:PR6nNKOqB/SE956hXA4=,iv:/1usgEXfY+ef9bOAaCdjduqBqoonAm5saFBSjdGhm1Q=,tag:mDThIsYVUKyN6vQlh2YYbQ==,type:str] + auth-secret: ENC[AES256_GCM,data:NHY+0tOA6FRmvkKZ/KgpogwOf+DuF42aoxspPUdVSi/iY5dF2yY8hwHaehI=,iv:9Gv/1YDcU+rMuX3PrwwT97qdsywIn+/wWEk17evyloo=,tag:R6RZbRhyXkwfZ0p/fZ+YcA==,type:str] + oauth-discord-client-secret: ENC[AES256_GCM,data:YegPgoSRKNcDaID9LPWxHDz4T7VnhFfuWMyALfFhpg8=,iv:VSLWA1HG1+Y70tKnRoFulBZSKdoJTYmIDzCXIZeFYCc=,tag:yNR8rrm/7Mrj/RIVNLFfsg==,type:str] +cloudflare-ddns: + api-token: ENC[AES256_GCM,data:wFKbclETO0YQTcfNUdKyr6mxQODeiaYn3gLeC1mWeRda97rOvlum+Q==,iv:IuT4exNhh0z+9DbY3WNnVqEy4398DTm7aluhOv9XFss=,tag:GGPoSJLBScTmXyQ7Vab6EA==,type:str] sops: age: - - recipient: age1yyzgmazjxkvwtfcv9re3lqmt2ru5dcrfu3sauysm0wzfwzvyap8qkjkq32 - enc: | + - enc: | -----BEGIN AGE ENCRYPTED FILE----- YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlVWpFK2RRSHRxVFVSdEdI S01BSEZQUTZCV0tvM1lpSFNYc3g3ek5QNjJrClNyVUtKYnRtWVRYRkE2SStWRVRR @@ -22,8 +27,8 @@ sops: ZUpnemRBSmlSZVpmRW0wNFhIK3BibVkKdD14ki8dJbYMjsBkC1Nm5TOM6M33eLJ6 IUrKDWeZXEVe2sMhBb31Zv+tinwtHSsvpxDIsjstpxtH+5wTyoQVdA== -----END AGE ENCRYPTED FILE----- - - recipient: age1elk6zwmcylwfk7gd4pjda7g29upftjvxys8py42s8d42jklnyv7s7dm9z2 - enc: | + recipient: age1yyzgmazjxkvwtfcv9re3lqmt2ru5dcrfu3sauysm0wzfwzvyap8qkjkq32 + - enc: | -----BEGIN AGE ENCRYPTED FILE----- YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1bFJDNDdsWGIzMDl3TmRr MStsZVFRa1dIVmJGU3krWWlpc2FZMU9EREF3CkdDZFc0Y3ZIMVZxNHorWFRHaWwy @@ -31,8 +36,8 @@ sops: NUZIYnZIMDRWTXpwTURMc2tzelp3VjAKHHBkHhz+t03W0ojsOBB2i3K4ZMUXvrwF 4mjNqNBcAJ1uHgJP7qvpNjxEW1LcsdQKmXavoqizX+XfLaA3zEwB0Q== -----END AGE ENCRYPTED FILE----- - - recipient: age1p05z980kdtngk9mw67hfev72h7xhslplpxfk9yskgmf0hl4lu3ls04zht9 - enc: | + recipient: age1elk6zwmcylwfk7gd4pjda7g29upftjvxys8py42s8d42jklnyv7s7dm9z2 + - enc: | -----BEGIN AGE ENCRYPTED FILE----- YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwTWR0N3UwdTB0UDZxRmV5 R3dkYUhZaElMbkxxSllTNWkrb05VSkJrMUNRCjZTUTlvVTU2MHY5ZS9oU2pCSlFu @@ -40,7 +45,8 @@ sops: WWZwbkR4dTFjK2NZcW9pTTNHd252N3cKiz8l9AWciFOBU+wcT9T1WA4bToPYfq8G Nf0uOoSWPTJ/2SRNkSu7FMumATH4ldQ6TFSwKda3mBfBwhnFzLq10Q== -----END AGE ENCRYPTED FILE----- - lastmodified: "2026-04-30T18:45:45Z" - mac: ENC[AES256_GCM,data:DD9NZcYQVSByaQvGAB7b/Wpk7SWBBsWtzAM9MkIHMmyxNomiPPUFQR6+18QDUCHQXk1xXMUi79bnTRz8SdoBXVjbHG8Qhy3n6D1sFeEgXC42pgem7hBPfmJlgcIPNYEguXPISLsp/Zx9ISEnH5Zul0v8/G2ACN7Y/U3jtaHx4U8=,iv:g1k16EhTR+t9jCpvhmiXYZV99aMk1DrS4frpl5q93lM=,tag:FigaXNw+IbpZ7E0a+ySb3g==,type:str] + recipient: age1p05z980kdtngk9mw67hfev72h7xhslplpxfk9yskgmf0hl4lu3ls04zht9 + lastmodified: "2026-05-28T21:04:07Z" + mac: ENC[AES256_GCM,data:L53UYFh5xtuMx19GKAg3jW7U0/DlwJ2usy/pup+4t1HQN3KHxMwbc4BzLYkLnRBTwKMJdfKXiYmmYiYvfbbWzsPtfXLxPnF/5ROiCJ2NlxAe86SmRy2nI++eTHAXRgexIhYyL7SchsroGRvW2B3aL1jV+Eu11fD9trA9Ex1EfuI=,iv:XrRJCFSgwW2+N+4FnWrFFZz8UEVzhuhpRtHGtf8dyqc=,tag:LcO4+ilwKdU+JPyjyKaGNw==,type:str] unencrypted_suffix: _unencrypted - version: 3.12.2 + version: 3.13.1 diff --git a/modules/lib/ssh-inventory.nix b/modules/lib/ssh-inventory.nix index 06e3b80..cfa677e 100644 --- a/modules/lib/ssh-inventory.nix +++ b/modules/lib/ssh-inventory.nix @@ -55,10 +55,10 @@ ); # Must come before inventory `Host` blocks and before `Host *`: LAN Gitea SSH is not a catalog PC, - # and `Host *` sets `IdentityAgent none` — without this, git@192.168.2.103 never sees rbw keys. + # and `Host *` sets `IdentityAgent none` — without this, git@nix-server never sees rbw keys. giteaSshBlock = identityAgent: '' - Host git.chiasson.cloud gitea casaos 192.168.2.103 - HostName 192.168.2.103 + Host git.chiasson.cloud gitea nix-server 192.168.2.238 + HostName 192.168.2.238 Port 222 User git IdentityAgent ${identityAgent} diff --git a/modules/system/default.nix b/modules/system/default.nix index a33339f..89af1f8 100644 --- a/modules/system/default.nix +++ b/modules/system/default.nix @@ -21,6 +21,7 @@ self.nixosModules.systemPalera1n self.nixosModules.systemCaching inputs.swiftshare.nixosModules.systemServiceSwiftshare + inputs.personal-website.nixosModules.systemServicePersonalWebsite self.nixosModules.systemServiceImmich ]; };