From acc0dac23452602c7660dc97a662e2ed8cd55b7d Mon Sep 17 00:00:00 2001 From: plasmagoat Date: Mon, 21 Jul 2025 22:33:04 +0200 Subject: [PATCH] tofu workflow --- .forgejo/workflows/tofu.yml | 44 +++ flake.lock | 17 + flake.nix | 68 +++- hive.nix | 34 +- .../{default.nix => configuration.nix} | 23 +- machines/auth/bootstrap/service-accounts.nix | 2 +- .../{definition.nix => configuration.nix} | 1 + machines/mail/configuration.nix | 11 + .../mail/{definition.nix => networking.nix} | 7 - .../{definition.nix => configuration.nix} | 2 + machines/photos/configuration.nix | 10 + machines/photos/ente.nix | 25 ++ machines/photos/minio.nix | 6 + .../{definition.nix => configuration.nix} | 2 + modules/nixos/default.nix | 3 + modules/nixos/ente.nix | 351 ++++++++++++++++++ nixos/hosts/forgejo/forgejo.nix | 15 +- nixos/hosts/forgejo/storage.nix | 18 +- nixos/hosts/sandbox/host.nix | 15 - nixos/hosts/sandbox/networking.nix | 6 - nixos/hosts/sandbox/sandbox.nix | 4 - nixos/hosts/sandbox/storage.nix | 11 - nixos/hosts/sandbox/warpgate.nix | 35 -- overlays/default.nix | 23 ++ pkgs/default.nix | 6 + pkgs/ente-web.nix | 91 +++++ 26 files changed, 674 insertions(+), 156 deletions(-) create mode 100644 .forgejo/workflows/tofu.yml rename machines/_default/{default.nix => configuration.nix} (50%) rename machines/auth/{definition.nix => configuration.nix} (69%) create mode 100644 machines/mail/configuration.nix rename machines/mail/{definition.nix => networking.nix} (65%) rename machines/monitor/{definition.nix => configuration.nix} (80%) create mode 100644 machines/photos/configuration.nix create mode 100644 machines/photos/ente.nix create mode 100644 machines/photos/minio.nix rename machines/sandbox/{definition.nix => configuration.nix} (52%) create mode 100644 modules/nixos/default.nix create mode 100644 modules/nixos/ente.nix delete mode 100644 nixos/hosts/sandbox/host.nix delete mode 100644 nixos/hosts/sandbox/networking.nix delete mode 100644 nixos/hosts/sandbox/sandbox.nix delete mode 100644 nixos/hosts/sandbox/storage.nix delete mode 100644 nixos/hosts/sandbox/warpgate.nix create mode 100644 overlays/default.nix create mode 100644 pkgs/default.nix create mode 100644 pkgs/ente-web.nix diff --git a/.forgejo/workflows/tofu.yml b/.forgejo/workflows/tofu.yml new file mode 100644 index 0000000..f150719 --- /dev/null +++ b/.forgejo/workflows/tofu.yml @@ -0,0 +1,44 @@ +on: + push: + workflow_dispatch: + +jobs: + apply: + name: OpenTofu + # Ensure 'nixos-latest' runner has Docker, SSH client, and basic Nix tools installed. + # It seems it already does. + runs-on: nixos-latest + env: + PROXMOX_API_URL: https://192.168.1.205:8006/api2/json + # PROXMOX_API_TOKEN_ID: nixos-builder.lab + # PROXMOX_API_TOKEN_SECRET: nixos-builder.lab + + steps: + - name: Install dependencies + run: | + nix-env -iA nixpkgs.nodejs + nix-env -iA nixpkgs.openssh + nix-env -iA nixpkgs.opentofu + + - uses: actions/checkout@v3 + + - name: OpenTofu fmt + id: fmt + run: tofu fmt -check + continue-on-error: true + + - name: OpenTofu Init + id: init + run: tofu init + working-directory: /infrastructure/proxmox + + - name: OpenTofu Validate + id: validate + run: tofu validate -no-color + working-directory: /infrastructure/proxmox + + - name: OpenTofu Plan + id: plan + run: tofu plan -no-color + working-directory: /infrastructure/proxmox + continue-on-error: true diff --git a/flake.lock b/flake.lock index 3d6d35c..39e8693 100644 --- a/flake.lock +++ b/flake.lock @@ -186,6 +186,22 @@ "type": "github" } }, + "nixpkgs-unstable": { + "locked": { + "lastModified": 1752480373, + "narHash": "sha256-JHQbm+OcGp32wAsXTE/FLYGNpb+4GLi5oTvCxwSoBOA=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "62e0f05ede1da0d54515d4ea8ce9c733f12d9f08", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, "nixpkgs_2": { "locked": { "lastModified": 1752624097, @@ -205,6 +221,7 @@ "inputs": { "colmena": "colmena", "nixpkgs": "nixpkgs_2", + "nixpkgs-unstable": "nixpkgs-unstable", "simple-nixos-mailserver": "simple-nixos-mailserver", "sops-nix": "sops-nix" } diff --git a/flake.nix b/flake.nix index 9f15ca5..8918622 100644 --- a/flake.nix +++ b/flake.nix @@ -2,17 +2,18 @@ description = "Declarative NixOS HomeLab"; inputs = { + # Nixpkgs nixpkgs.url = "github:nixos/nixpkgs"; + # You can access packages and modules from different nixpkgs revs + # at the same time. Here's an working example: + nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable"; + # Also see the 'unstable-packages' overlay at 'overlays/default.nix'. # systems.url = "github:nix-systems/default"; - sops-nix = { - url = "github:Mic92/sops-nix"; - inputs.nixpkgs.follows = "nixpkgs"; - }; + sops-nix.url = "github:Mic92/sops-nix"; + sops-nix.inputs.nixpkgs.follows = "nixpkgs"; - simple-nixos-mailserver = { - url = "gitlab:simple-nixos-mailserver/nixos-mailserver"; - inputs.nixpkgs.follows = "nixpkgs"; - }; + simple-nixos-mailserver.url = "gitlab:simple-nixos-mailserver/nixos-mailserver"; + simple-nixos-mailserver.inputs.nixpkgs.follows = "nixpkgs"; # home-manager = { # url = "home-manager"; # inputs.nixpkgs.follows = "nixpkgs"; @@ -30,11 +31,56 @@ simple-nixos-mailserver, ... } @ inputs: let - overlays = [ - colmena.overlays.default + inherit (self) outputs; + # Supported systems for your flake packages, shell, etc. + systems = [ + "x86_64-linux" ]; + # This is a function that generates an attribute by calling a function you + # pass to it, with each system as an argument + forAllSystems = nixpkgs.lib.genAttrs systems; in { + # Custom packages + # Accessible through 'nix build', 'nix shell', etc + packages = forAllSystems (system: import ./pkgs nixpkgs.legacyPackages.${system}); + + # Formatter for your nix files, available through 'nix fmt' + # Other options beside 'alejandra' include 'nixpkgs-fmt' + formatter = forAllSystems (system: nixpkgs.legacyPackages.${system}.alejandra); + + # Custom packages and modifications, exported as overlays + overlays = import ./overlays {inherit inputs;}; + + # Reusable nixos modules + nixosModules = import ./modules/nixos; + colmenaHive = colmena.lib.makeHive self.outputs.colmena; - colmena = (import ./hive.nix) (inputs // {inherit overlays;}); + colmena = { + meta = { + nixpkgs = import nixpkgs { + system = "x86_64-linux"; + overlays = [ + outputs.overlays.additions + outputs.overlays.modifications + outputs.overlays.unstable-packages + + colmena.overlays.default + ]; + config.allowUnfree = true; + }; + + specialArgs = { + inherit inputs outputs; + }; + }; + + defaults = import ./machines/_default/configuration.nix; + + sandbox = import ./machines/sandbox/configuration.nix; + auth = import ./machines/auth/configuration.nix; + mail = import ./machines/mail/configuration.nix; + monitor = import ./machines/monitor/configuration.nix; + photos = import ./machines/photos/configuration.nix; + }; }; } diff --git a/hive.nix b/hive.nix index 05f8896..e0fc390 100644 --- a/hive.nix +++ b/hive.nix @@ -4,36 +4,9 @@ inputs @ { sops-nix, simple-nixos-mailserver, # home-manager, - overlays, + outputs, ... }: { - meta = { - nixpkgs = import nixpkgs { - system = "x86_64-linux"; - }; - specialArgs.flakeInputs = inputs; - }; - - defaults = { - lib, - name, - config, - ... - }: { - imports = [ - ./machines/_default - ./machines/modules - sops-nix.nixosModules.sops - # home-manager.nixosModules.home-manager - ]; - nixpkgs = { - inherit overlays; - system = lib.mkDefault "x86_64-linux"; - config.allowUnfree = true; - }; - deployment.tags = [config.nixpkgs.system name]; - }; - sandbox = {name, ...}: { imports = [./machines/${name}/definition.nix]; deployment.tags = ["sandbox"]; @@ -56,4 +29,9 @@ inputs @ { ]; deployment.tags = ["mail"]; }; + + photos = {name, ...}: { + imports = [./machines/${name}/definition.nix]; + deployment.tags = ["ente"]; + }; } diff --git a/machines/_default/default.nix b/machines/_default/configuration.nix similarity index 50% rename from machines/_default/default.nix rename to machines/_default/configuration.nix index c038ebf..3d38005 100644 --- a/machines/_default/default.nix +++ b/machines/_default/configuration.nix @@ -1,10 +1,15 @@ { - lib, name, + config, + lib, + inputs, ... }: { imports = [ ./common_config.nix + ../modules + inputs.sops-nix.nixosModules.sops + # inputs.home-manager.nixosModules.home-manager ]; networking.hostName = name; @@ -13,7 +18,7 @@ replaceUnknownProfiles = lib.mkDefault true; buildOnTarget = lib.mkDefault false; targetHost = lib.mkDefault "${name}.lab"; - tags = lib.mkDefault ["homelab"]; + tags = lib.mkDefault [config.nixpkgs.system name "homelab"]; }; sops = { @@ -21,20 +26,6 @@ defaultSopsFile = ../../secrets/secrets.yaml; }; - # home-manager = { - # useGlobalPkgs = true; - # useUserPackages = true; - # users.cottand = { - # imports = with flakeInputs.cottand.homeManagerModules; [cli]; - # home.stateVersion = "22.11"; - # }; - # users.root = { - # imports = with flakeInputs.cottand.homeManagerModules; [cli]; - # home.stateVersion = "22.11"; - # }; - # }; - - # consulNode.enable = lib.mkDefault true; nodeExporter.enable = lib.mkDefault true; journalLog.enable = lib.mkDefault true; } diff --git a/machines/auth/bootstrap/service-accounts.nix b/machines/auth/bootstrap/service-accounts.nix index 09a552e..dc37282 100644 --- a/machines/auth/bootstrap/service-accounts.nix +++ b/machines/auth/bootstrap/service-accounts.nix @@ -17,7 +17,7 @@ } { "id": "forgejo", - "email": "forgejo@procopius.dk", + "email": "git@procopius.dk", "password": "${config.sops.placeholder."service_accounts/forgejo/password"}", "displayName": "Forgejo", "groups": [ diff --git a/machines/auth/definition.nix b/machines/auth/configuration.nix similarity index 69% rename from machines/auth/definition.nix rename to machines/auth/configuration.nix index 133c5c1..9f51678 100644 --- a/machines/auth/definition.nix +++ b/machines/auth/configuration.nix @@ -6,5 +6,6 @@ ./redis.nix ]; + deployment.tags = ["authelia" "sso" "ldap" "lldap"]; system.stateVersion = "25.05"; } diff --git a/machines/mail/configuration.nix b/machines/mail/configuration.nix new file mode 100644 index 0000000..15700a3 --- /dev/null +++ b/machines/mail/configuration.nix @@ -0,0 +1,11 @@ +{inputs, ...}: { + imports = [ + ./mailserver.nix + ./networking.nix + inputs.simple-nixos-mailserver.nixosModule + ]; + + deployment.tags = ["mail"]; + + system.stateVersion = "25.05"; +} diff --git a/machines/mail/definition.nix b/machines/mail/networking.nix similarity index 65% rename from machines/mail/definition.nix rename to machines/mail/networking.nix index 97607b0..10eca15 100644 --- a/machines/mail/definition.nix +++ b/machines/mail/networking.nix @@ -1,8 +1,4 @@ { - imports = [ - ./mailserver.nix - ]; - networking = { interfaces.eth0.ipv4.addresses = [ { @@ -13,7 +9,4 @@ nameservers = ["192.168.1.53"]; defaultGateway = "192.168.1.1"; }; - deployment.targetHost = "192.168.1.25"; - - system.stateVersion = "25.05"; } diff --git a/machines/monitor/definition.nix b/machines/monitor/configuration.nix similarity index 80% rename from machines/monitor/definition.nix rename to machines/monitor/configuration.nix index 64dfb92..04496f2 100644 --- a/machines/monitor/definition.nix +++ b/machines/monitor/configuration.nix @@ -10,5 +10,7 @@ ./jellyfin-exporter.nix ]; + deployment.tags = ["grafana" "prometheus"]; + system.stateVersion = "25.05"; } diff --git a/machines/photos/configuration.nix b/machines/photos/configuration.nix new file mode 100644 index 0000000..db54baf --- /dev/null +++ b/machines/photos/configuration.nix @@ -0,0 +1,10 @@ +{outputs, ...}: { + imports = [ + outputs.nixosModules.ente + ./ente.nix + ]; + + deployment.tags = ["ente"]; + + system.stateVersion = "25.05"; +} diff --git a/machines/photos/ente.nix b/machines/photos/ente.nix new file mode 100644 index 0000000..abca1d9 --- /dev/null +++ b/machines/photos/ente.nix @@ -0,0 +1,25 @@ +{ + services.ente.api = { + enable = true; + enableLocalDB = true; + + domain = "ente-v2.procopius.dk"; + settings = { + # apps = { + # accounts = "https://accounts.procopius.dk"; + # cast = "https://cast.procopius.dk"; + # public-albums = "https://albums.procopius.dk"; + # }; + }; + }; + services.ente.web = { + enable = true; + domains = { + api = "ente-v2.procopius.dk"; + accounts = "accounts.procopius.dk"; + albums = "albums.procopius.dk"; + cast = "cast.procopius.dk"; + photos = "photos.procopius.dk"; + }; + }; +} diff --git a/machines/photos/minio.nix b/machines/photos/minio.nix new file mode 100644 index 0000000..c3d6ee2 --- /dev/null +++ b/machines/photos/minio.nix @@ -0,0 +1,6 @@ +{ + services.minio = { + enable = true; + rootCredentialsFile = "/etc/nixos/minio-root-credentials"; + }; +} diff --git a/machines/sandbox/definition.nix b/machines/sandbox/configuration.nix similarity index 52% rename from machines/sandbox/definition.nix rename to machines/sandbox/configuration.nix index 8033946..6c1ca72 100644 --- a/machines/sandbox/definition.nix +++ b/machines/sandbox/configuration.nix @@ -1,3 +1,5 @@ { + deployment.tags = ["sandbox"]; + system.stateVersion = "25.05"; } diff --git a/modules/nixos/default.nix b/modules/nixos/default.nix new file mode 100644 index 0000000..a0250d5 --- /dev/null +++ b/modules/nixos/default.nix @@ -0,0 +1,3 @@ +{ + ente = import ./ente.nix; +} diff --git a/modules/nixos/ente.nix b/modules/nixos/ente.nix new file mode 100644 index 0000000..283e4ec --- /dev/null +++ b/modules/nixos/ente.nix @@ -0,0 +1,351 @@ +{ + config, + lib, + pkgs, + utils, + ... +}: let + inherit + (lib) + getExe + mkDefault + mkEnableOption + mkIf + mkMerge + mkOption + mkPackageOption + optional + types + ; + + cfgApi = config.services.ente.api; + cfgWeb = config.services.ente.web; + + webPackage = enteApp: + cfgWeb.package.override { + inherit enteApp; + enteMainUrl = "https://${cfgWeb.domains.photos}"; + extraBuildEnv = { + NEXT_PUBLIC_ENTE_ENDPOINT = "https://${cfgWeb.domains.api}"; + NEXT_PUBLIC_ENTE_ALBUMS_ENDPOINT = "https://${cfgWeb.domains.albums}"; + NEXT_TELEMETRY_DISABLED = "1"; + }; + }; + + defaultUser = "ente"; + defaultGroup = "ente"; + dataDir = "/var/lib/ente"; + + yamlFormat = pkgs.formats.yaml {}; +in { + options.services.ente = { + web = { + enable = mkEnableOption "Ente web frontend (Photos, Albums)"; + package = mkPackageOption pkgs "ente-web" {}; + + domains = { + api = mkOption { + type = types.str; + description = '' + The domain under which the api is served. This will NOT serve the api itself, + but is a required setting to host the frontends! This will automatically be set + for you if you enable both the api server and web frontends. + ''; + }; + + accounts = mkOption { + type = types.str; + description = "The domain under which the accounts frontend will be served."; + }; + + cast = mkOption { + type = types.str; + description = "The domain under which the cast frontend will be served."; + }; + + albums = mkOption { + type = types.str; + description = "The domain under which the albums frontend will be served."; + }; + + photos = mkOption { + type = types.str; + description = "The domain under which the photos frontend will be served."; + }; + }; + }; + + api = { + enable = mkEnableOption "Museum (API server for ente.io)"; + package = mkPackageOption pkgs "museum" {}; + nginx.enable = mkEnableOption "nginx proxy for the API server"; + + user = mkOption { + type = types.str; + default = defaultUser; + description = "User under which museum runs."; + }; + + group = mkOption { + type = types.str; + default = defaultGroup; + description = "Group under which museum runs."; + }; + + domain = mkOption { + type = types.str; + description = "The domain under which the api will be served."; + }; + + enableLocalDB = mkEnableOption "the automatic creation of a local postgres database for museum."; + + settings = mkOption { + description = '' + Museum yaml configuration. Refer to upstream [local.yaml](https://github.com/ente-io/ente/blob/main/server/configurations/local.yaml) for more information. + You can specify secret values in this configuration by setting `somevalue._secret = "/path/to/file"` instead of setting `somevalue` directly. + ''; + default = {}; + type = types.submodule { + freeformType = yamlFormat.type; + options = { + apps = { + public-albums = mkOption { + type = types.str; + default = "https://albums.ente.io"; + description = '' + If you're running a self hosted instance and wish to serve public links, + set this to the URL where your albums web app is running. + ''; + }; + + cast = mkOption { + type = types.str; + default = "https://cast.ente.io"; + description = '' + Set this to the URL where your cast page is running. + This is for browser and chromecast casting support. + ''; + }; + + accounts = mkOption { + type = types.str; + default = "https://accounts.ente.io"; + description = '' + Set this to the URL where your accounts page is running. + This is primarily for passkey support. + ''; + }; + }; + + db = { + host = mkOption { + type = types.str; + description = "The database host"; + }; + + port = mkOption { + type = types.port; + default = 5432; + description = "The database port"; + }; + + name = mkOption { + type = types.str; + description = "The database name"; + }; + + user = mkOption { + type = types.str; + description = "The database user"; + }; + }; + }; + }; + }; + }; + }; + + config = mkMerge [ + (mkIf cfgApi.enable { + services.postgresql = mkIf cfgApi.enableLocalDB { + enable = true; + ensureUsers = [ + { + name = "ente"; + ensureDBOwnership = true; + } + ]; + ensureDatabases = ["ente"]; + }; + + services.ente.web.domains.api = mkIf cfgWeb.enable cfgApi.domain; + services.ente.api.settings = { + log-file = mkDefault ""; + db = mkIf cfgApi.enableLocalDB { + host = "/run/postgresql"; + port = 5432; + name = "ente"; + user = "ente"; + }; + }; + + systemd.services.ente = { + description = "Ente.io Museum API Server"; + after = ["network.target"] ++ optional cfgApi.enableLocalDB "postgresql.service"; + requires = optional cfgApi.enableLocalDB "postgresql.service"; + wantedBy = ["multi-user.target"]; + + preStart = '' + # Generate config including secret values. YAML is a superset of JSON, so we can use this here. + ${utils.genJqSecretsReplacementSnippet cfgApi.settings "/run/ente/local.yaml"} + + # Setup paths + mkdir -p ${dataDir}/configurations + ln -sTf /run/ente/local.yaml ${dataDir}/configurations/local.yaml + ''; + + serviceConfig = { + ExecStart = getExe cfgApi.package; + Type = "simple"; + Restart = "on-failure"; + + AmbientCapablities = []; + CapabilityBoundingSet = []; + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + PrivateMounts = true; + PrivateTmp = true; + PrivateUsers = false; + ProcSubset = "pid"; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + ProtectSystem = "strict"; + RestrictAddressFamilies = [ + "AF_INET" + "AF_INET6" + "AF_NETLINK" + "AF_UNIX" + ]; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + SystemCallFilter = "@system-service"; + UMask = "077"; + + BindReadOnlyPaths = [ + "${cfgApi.package}/share/museum/migrations:${dataDir}/migrations" + "${cfgApi.package}/share/museum/mail-templates:${dataDir}/mail-templates" + ]; + + User = cfgApi.user; + Group = cfgApi.group; + + SyslogIdentifier = "ente"; + StateDirectory = "ente"; + WorkingDirectory = dataDir; + RuntimeDirectory = "ente"; + }; + + # Environment MUST be called local, otherwise we cannot log to stdout + environment = { + ENVIRONMENT = "local"; + GIN_MODE = "release"; + }; + }; + + users = { + users = mkIf (cfgApi.user == defaultUser) { + ${defaultUser} = { + description = "ente.io museum service user"; + inherit (cfgApi) group; + isSystemUser = true; + home = dataDir; + }; + }; + groups = mkIf (cfgApi.group == defaultGroup) {${defaultGroup} = {};}; + }; + + services.nginx = mkIf cfgApi.nginx.enable { + enable = true; + upstreams.museum = { + servers."localhost:8080" = {}; + extraConfig = '' + zone museum 64k; + keepalive 20; + ''; + }; + + virtualHosts.${cfgApi.domain} = { + forceSSL = mkDefault false; + locations."/".proxyPass = "http://museum"; + extraConfig = '' + client_max_body_size 4M; + ''; + }; + }; + }) + (mkIf cfgWeb.enable { + services.ente.api.settings = mkIf cfgApi.enable { + apps = { + accounts = "https://${cfgWeb.domains.accounts}"; + cast = "https://${cfgWeb.domains.cast}"; + public-albums = "https://${cfgWeb.domains.albums}"; + }; + + webauthn = { + rpid = cfgWeb.domains.accounts; + rporigins = ["https://${cfgWeb.domains.accounts}"]; + }; + }; + + services.nginx = let + domainFor = app: cfgWeb.domains.${app}; + in { + enable = true; + virtualHosts.${domainFor "accounts"} = { + forceSSL = mkDefault false; + locations."/" = { + root = webPackage "accounts"; + tryFiles = "$uri $uri.html /index.html"; + extraConfig = '' + add_header Access-Control-Allow-Origin 'https://${cfgWeb.domains.api}'; + ''; + }; + }; + virtualHosts.${domainFor "cast"} = { + forceSSL = mkDefault false; + locations."/" = { + root = webPackage "cast"; + tryFiles = "$uri $uri.html /index.html"; + extraConfig = '' + add_header Access-Control-Allow-Origin 'https://${cfgWeb.domains.api}'; + ''; + }; + }; + virtualHosts.${domainFor "photos"} = { + serverAliases = [ + (domainFor "albums") # the albums app is shared with the photos frontend + ]; + forceSSL = mkDefault false; + locations."/" = { + root = webPackage "photos"; + tryFiles = "$uri $uri.html /index.html"; + extraConfig = '' + add_header Access-Control-Allow-Origin 'https://${cfgWeb.domains.api}'; + ''; + }; + }; + }; + }) + ]; + + meta.maintainers = with lib.maintainers; [oddlama]; +} diff --git a/nixos/hosts/forgejo/forgejo.nix b/nixos/hosts/forgejo/forgejo.nix index f59029d..11ed29f 100644 --- a/nixos/hosts/forgejo/forgejo.nix +++ b/nixos/hosts/forgejo/forgejo.nix @@ -16,6 +16,11 @@ in { user = "forgejo"; group = "forgejo"; stateDir = "/srv/forgejo"; + secrets = { + mailer = { + PASSWD = ; + }; + }; settings = { # https://forgejo.org/docs/latest/admin/config-cheat-sheet/ server = { @@ -34,8 +39,7 @@ in { PROTOCOL = "smtp+starttls"; SMTP_ADDR = "mail.procopius.dk"; - USER = "admin@procopius.dk"; - PASSWD = "mikael"; + USER = "git@procopius.dk"; }; database = { DB_TYPE = lib.mkForce "postgres"; @@ -57,9 +61,9 @@ in { ZOMBIE_TASK_TIMEOUT = "30m"; }; ldap = { - AUTHORIZATION_NAME = "My LDAP"; - HOST = "ldap.example.com"; - PORT = 389; + AUTHORIZATION_NAME = "LLDAP"; + HOST = "auth.lab"; + PORT = 3890; ENABLE_TLS = false; USER_SEARCH_BASE = "ou=users,dc=example,dc=com"; USER_FILTER = "(&(objectClass=user)(sAMAccountName=%[1]s))"; @@ -86,7 +90,6 @@ in { security = { INSTALL_LOCK = true; - SECRET_KEY = config.sops.secrets."forgejo-secret-key".path; # can be another secret }; }; }; diff --git a/nixos/hosts/forgejo/storage.nix b/nixos/hosts/forgejo/storage.nix index f944371..d17421c 100644 --- a/nixos/hosts/forgejo/storage.nix +++ b/nixos/hosts/forgejo/storage.nix @@ -1,26 +1,12 @@ { - # services.nfs.client = { - # enable = true; - # idmapd.enable = true; - # }; - - # environment.etc."idmapd.conf".text = '' - # [General] - # Domain = localdomain - - # [Mapping] - # Nobody-User = nobody - # Nobody-Group = nogroup - # ''; - - boot.supportedFilesystems = [ "nfs" ]; + boot.supportedFilesystems = ["nfs"]; services.rpcbind.enable = true; fileSystems."/srv/forgejo" = { device = "192.168.1.226:/volume1/data/forgejo"; fsType = "nfs4"; - options = [ "x-systemd.automount" "noatime" "_netdev" ]; + options = ["x-systemd.automount" "noatime" "_netdev"]; }; systemd.tmpfiles.rules = [ diff --git a/nixos/hosts/sandbox/host.nix b/nixos/hosts/sandbox/host.nix deleted file mode 100644 index 41e1816..0000000 --- a/nixos/hosts/sandbox/host.nix +++ /dev/null @@ -1,15 +0,0 @@ -{ - config, - pkgs, - modulesPath, - lib, - ... -}: { - imports = [ - ../../templates/base.nix - ./networking.nix - ./storage.nix - ./sandbox.nix - ./warpgate.nix - ]; -} diff --git a/nixos/hosts/sandbox/networking.nix b/nixos/hosts/sandbox/networking.nix deleted file mode 100644 index e1419e9..0000000 --- a/nixos/hosts/sandbox/networking.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ config, lib, pkgs, ... }: -{ - networking.hostName = "sandbox"; - networking.interfaces.ens18.useDHCP = true; - networking.defaultGateway = "192.168.1.1"; -} diff --git a/nixos/hosts/sandbox/sandbox.nix b/nixos/hosts/sandbox/sandbox.nix deleted file mode 100644 index dc93e49..0000000 --- a/nixos/hosts/sandbox/sandbox.nix +++ /dev/null @@ -1,4 +0,0 @@ -{ config, pkgs, modulesPath, lib, ... }: - -{ -} diff --git a/nixos/hosts/sandbox/storage.nix b/nixos/hosts/sandbox/storage.nix deleted file mode 100644 index c94b739..0000000 --- a/nixos/hosts/sandbox/storage.nix +++ /dev/null @@ -1,11 +0,0 @@ -{ - boot.supportedFilesystems = ["nfs"]; - - services.rpcbind.enable = true; - - # fileSystems."/mnt/nas" = { - # device = "192.168.1.226:/volume1/docker"; - # fsType = "nfs"; - # options = [ "noatime" "vers=4" "rsize=8192" "wsize=8192" ]; - # }; -} diff --git a/nixos/hosts/sandbox/warpgate.nix b/nixos/hosts/sandbox/warpgate.nix deleted file mode 100644 index 7c24ad8..0000000 --- a/nixos/hosts/sandbox/warpgate.nix +++ /dev/null @@ -1,35 +0,0 @@ -{ - virtualisation = { - containers.enable = true; - oci-containers.backend = "podman"; - - podman = { - enable = true; - - # Create a `docker` alias for podman, to use it as a drop-in replacement - dockerCompat = true; - - # Required for containers under podman-compose to be able to talk to each other. - defaultNetwork.settings.dns_enabled = true; - }; - }; - virtualisation.oci-containers.containers = { - warpgate = { - image = "ghcr.io/warp-tech/warpgate"; - ports = [ - "2222:2222" - "8888:8888" - ]; - volumes = [ - "/srv/warpgate/data:/data" - ]; - }; - }; - - systemd.tmpfiles.rules = [ - "d /srv/warpgate 0755 root root -" - "d /srv/warpgate/data 0755 root root -" - ]; - - networking.firewall.allowedTCPPorts = [8888]; -} diff --git a/overlays/default.nix b/overlays/default.nix new file mode 100644 index 0000000..7bfcb4c --- /dev/null +++ b/overlays/default.nix @@ -0,0 +1,23 @@ +# This file defines overlays +{inputs, ...}: { + # This one brings our custom packages from the 'pkgs' directory + additions = final: _prev: import ../pkgs final.pkgs; + + # This one contains whatever you want to overlay + # You can change versions, add patches, set compilation flags, anything really. + # https://nixos.wiki/wiki/Overlays + modifications = final: prev: { + # example = prev.example.overrideAttrs (oldAttrs: rec { + # ... + # }); + }; + + # When applied, the unstable nixpkgs set (declared in the flake inputs) will + # be accessible through 'pkgs.unstable' + unstable-packages = final: _prev: { + unstable = import inputs.nixpkgs-unstable { + system = final.system; + config.allowUnfree = true; + }; + }; +} diff --git a/pkgs/default.nix b/pkgs/default.nix new file mode 100644 index 0000000..f5abee4 --- /dev/null +++ b/pkgs/default.nix @@ -0,0 +1,6 @@ +# Custom packages, that can be defined similarly to ones from nixpkgs +# You can build them using 'nix build .#example' +pkgs: { + # example = pkgs.callPackage ./example { }; + ente-web = pkgs.callPackage ./ente-web.nix {}; +} diff --git a/pkgs/ente-web.nix b/pkgs/ente-web.nix new file mode 100644 index 0000000..8aa0fa6 --- /dev/null +++ b/pkgs/ente-web.nix @@ -0,0 +1,91 @@ +{ + lib, + stdenv, + fetchFromGitHub, + fetchYarnDeps, + nodejs, + yarnConfigHook, + yarnBuildHook, + nix-update-script, + extraBuildEnv ? {}, + # This package contains serveral sub-applications. This specifies which of them you want to build. + enteApp ? "photos", + # Accessing some apps (such as account) directly will result in a hardcoded redirect to ente.io. + # To prevent users from accidentally logging in to ente.io instead of the selfhosted instance, you + # can set this parameter to override these occurrences with your own url. Must include the schema. + # Example: https://my-ente.example.com + enteMainUrl ? null, +}: +stdenv.mkDerivation (finalAttrs: { + pname = "ente-web-${enteApp}"; + version = "1.0.4"; + + src = fetchFromGitHub { + owner = "ente-io"; + repo = "ente"; + sparseCheckout = ["web"]; + tag = "photos-v${finalAttrs.version}"; + fetchSubmodules = true; + hash = "sha256-M1kAZgqjbWNn6LqymtWRmAk/v0vWEGbyS50lVrsr85o="; + }; + sourceRoot = "${finalAttrs.src.name}/web"; + + offlineCache = fetchYarnDeps { + yarnLock = "${finalAttrs.src}/web/yarn.lock"; + hash = "sha256-EYhYwy6+7bgWckU/7SfL1PREWw9JUgKxWadSVtoZwXs="; + }; + + nativeBuildInputs = [ + yarnConfigHook + yarnBuildHook + nodejs + ]; + + # See: https://github.com/ente-io/ente/blob/main/web/apps/photos/.env + env = extraBuildEnv; + + # Replace hardcoded ente.io urls if desired + postPatch = lib.optionalString (enteMainUrl != null) '' + substituteInPlace \ + apps/payments/src/services/billing.ts \ + apps/photos/src/pages/shared-albums.tsx \ + --replace-fail "https://ente.io" ${lib.escapeShellArg enteMainUrl} + + substituteInPlace \ + apps/accounts/src/pages/index.tsx \ + --replace-fail "https://web.ente.io" ${lib.escapeShellArg enteMainUrl} + ''; + + yarnBuildScript = "build:${enteApp}"; + installPhase = let + distName = + if enteApp == "payments" + then "dist" + else "out"; + in '' + runHook preInstall + + cp -r apps/${enteApp}/${distName} $out + + runHook postInstall + ''; + + passthru.updateScript = nix-update-script { + extraArgs = [ + "--version-regex" + "photos-v(.*)" + ]; + }; + + meta = { + description = "Ente application web frontends"; + homepage = "https://ente.io/"; + changelog = "https://github.com/ente-io/ente/releases"; + license = lib.licenses.agpl3Only; + maintainers = with lib.maintainers; [ + pinpox + oddlama + ]; + platforms = lib.platforms.all; + }; +})