From 343f5d7b52a77fe0e3e155a631c6253d4544ed4c Mon Sep 17 00:00:00 2001 From: "RingOfStorms (Joshua Bell)" Date: Tue, 11 Feb 2025 17:05:41 -0600 Subject: [PATCH] bunch of random crap --- .../lio => components}/containers/affine.nix | 0 components/containers/inventory.nix | 166 ++++++++++++++++++ .../containers/librechat.nix | 2 +- components/containers/mathesar.nix | 159 +++++++++++++++++ components/containers/pgadmin.nix | 53 ++++++ .../lio => components}/containers/tests.nix | 0 hosts/linode/l002/nginx.nix | 8 + hosts/lio/containers.nix | 44 ++--- 8 files changed, 410 insertions(+), 22 deletions(-) rename {hosts/lio => components}/containers/affine.nix (100%) create mode 100644 components/containers/inventory.nix rename {hosts/lio => components}/containers/librechat.nix (98%) create mode 100644 components/containers/mathesar.nix create mode 100644 components/containers/pgadmin.nix rename {hosts/lio => components}/containers/tests.nix (100%) diff --git a/hosts/lio/containers/affine.nix b/components/containers/affine.nix similarity index 100% rename from hosts/lio/containers/affine.nix rename to components/containers/affine.nix diff --git a/components/containers/inventory.nix b/components/containers/inventory.nix new file mode 100644 index 0000000..6169ab9 --- /dev/null +++ b/components/containers/inventory.nix @@ -0,0 +1,166 @@ +{ + config, + lib, + ... +}: + +let + name = "inventory"; + app = "pg-${name}"; + + hostDataDir = "/var/lib/${name}"; + + localAddress = "192.168.100.110"; + pg_port = 54433; + pg_dataDir = "/var/lib/postgres"; + # pgadmin_port = 5050; + # pgadmin_dataDir = "/var/lib/pgadmin"; + + binds = [ + { + host = "${hostDataDir}/postgres"; + container = pg_dataDir; + user = "postgres"; + uid = config.ids.uids.postgres; + } + # { + # host = "${hostDataDir}/pgadmin"; + # container = pgadmin_dataDir; + # user = "pgadmin"; + # uid = 1020; + # } + ]; +in +{ + + users = lib.foldl ( + acc: bind: + { + users.${bind.user} = { + isSystemUser = true; + home = bind.host; + createHome = true; + uid = bind.uid; + group = bind.user; + }; + groups.${bind.user}.gid = bind.uid; + } + // acc + ) { } binds; + + containers.${app} = { + ephemeral = true; + autoStart = true; + privateNetwork = true; + hostAddress = "192.168.100.2"; + localAddress = localAddress; + bindMounts = lib.foldl ( + acc: bind: + { + "${bind.container}" = { + hostPath = bind.host; + isReadOnly = false; + }; + } + // acc + ) { } binds; + config = + { config, pkgs, ... }: + { + system.stateVersion = "24.11"; + + users = lib.foldl ( + acc: bind: + { + users.${bind.user} = { + isSystemUser = true; + home = bind.container; + uid = bind.uid; + group = bind.user; + }; + groups.${bind.user}.gid = bind.uid; + } + // acc + ) { } binds; + + services.postgresql = { + enable = true; + package = pkgs.postgresql_17.withJIT; + enableJIT = true; + extensions = with pkgs.postgresql17Packages; [ + # NOTE add extensions here + pgvector + postgis + ]; + settings.port = pg_port; + enableTCPIP = true; + authentication = '' + local all all trust + host all all 127.0.0.1/8 trust + host all all ::1/128 trust + host all all 192.168.100.0/24 trust + ''; + identMap = '' + # ArbitraryMapName systemUser dbUser + superuser_map root ${name} + + # Let other names login as themselves + superuser_map /^(.*)$ \1 + ''; + ensureDatabases = [ name ]; + ensureUsers = [ + { + name = name; + ensureDBOwnership = true; + ensureClauses = { + login = true; + superuser = true; + }; + } + ]; + dataDir = + (lib.findFirst (bind: bind.user == "postgres") (throw "No postgres bind found") binds).container; + }; + + # services.pgadmin = { + # enable = true; + # port = pgadmin_port; + # openFirewall = true; + # initialEmail = "admin@test.com"; + # initialPasswordFile = (builtins.toFile "password" "password"); + # }; + + # TODO set this up, had issues since it shares users with postgres service and my bind mounts relys on createhome in that exact directory. + # services.postgresqlBackup = { + # enable = true; + # compression = "gzip"; + # compressionLevel = 9; + # databases = [ cfg.database ]; + # location = "${cfg.dataDir}/backup"; + # startAt = "02:30"; # Adjust the backup time as needed + # }; + + networking.firewall = { + enable = true; + allowedTCPPorts = [ pg_port ]; + }; + + # Health check to ensure database is ready + systemd.services.postgresql-healthcheck = { + description = "PostgreSQL Health Check"; + after = [ "postgresql.service" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type = "oneshot"; + ExecStart = '' + ${pkgs.postgresql_17}/bin/pg_isready \ + -U ${name} \ + -d ${name} \ + -h localhost \ + -p ${toString pg_port} + ''; + }; + }; + }; + }; +} diff --git a/hosts/lio/containers/librechat.nix b/components/containers/librechat.nix similarity index 98% rename from hosts/lio/containers/librechat.nix rename to components/containers/librechat.nix index cad1fe1..f96fb61 100644 --- a/hosts/lio/containers/librechat.nix +++ b/components/containers/librechat.nix @@ -15,7 +15,7 @@ in port = lib.mkOption { type = lib.types.port; default = 3080; - description = "Port number for the LibreChat API service"; + description = "Port number for the LibreChat"; }; ragPort = lib.mkOption { type = lib.types.port; diff --git a/components/containers/mathesar.nix b/components/containers/mathesar.nix new file mode 100644 index 0000000..ae1bec4 --- /dev/null +++ b/components/containers/mathesar.nix @@ -0,0 +1,159 @@ +{ + config, + pkgs, + ... +}: +let + cfg = config.services.mathesar; +in +{ + options.services.mathesar = + let + lib = pkgs.lib; + in + { + port = lib.mkOption { + type = lib.types.port; + default = 3081; + description = "Port number for the Mathesar"; + }; + dataDir = lib.mkOption { + type = lib.types.path; + default = "/var/lib/mathesar"; + description = "Directory to store Mathesar data"; + }; + secretKey = lib.mkOption { + type = lib.types.str; + # echo $(cat /dev/urandom | LC_CTYPE=C tr -dc 'a-zA-Z0-9' | head -c 50) + # https://docs.djangoproject.com/en/4.2/ref/settings/#secret-key + description = "Secret key for Django security features"; + }; + domainName = lib.mkOption { + type = lib.types.str; + default = "http://10.20.40.104"; + description = "Custom domain(s) for accessing Mathesar"; + }; + postgresDb = lib.mkOption { + type = lib.types.str; + default = "mathesar_django"; + description = "Database name for Mathesar"; + }; + postgresUser = lib.mkOption { + type = lib.types.str; + default = "mathesar"; + description = "Database user for Mathesar"; + }; + postgresPassword = lib.mkOption { + type = lib.types.str; + default = "mathesar"; + description = "Database password for Mathesar"; + }; + postgresHost = lib.mkOption { + type = lib.types.str; + default = "mathesar_db"; + description = "Host running the PostgreSQL database"; + }; + postgresPort = lib.mkOption { + type = lib.types.port; + default = 3082; + description = "Port on which PostgreSQL is running"; + }; + allowedHosts = lib.mkOption { + type = lib.types.str; + default = "*"; + description = "Allowed hosts for Mathesar web service. "; + }; + }; + + config = { + systemd.services.create-mathesar-network = { + description = "Create Docker network for Mathesar"; + serviceConfig.Type = "oneshot"; + wantedBy = [ "multi-user.target" ]; + script = '' + if ! ${pkgs.docker}/bin/docker network inspect mathesar_network >/dev/null 2>&1; then + ${pkgs.docker}/bin/docker network create mathesar_network + fi + ''; + }; + + virtualisation.oci-containers.containers = { + ################ + # mathesar_service + ################ + mathesar_service = { + user = "root"; + image = "mathesar/mathesar:latest"; + dependsOn = [ "mathesar_db" ]; + environment = { + SECRET_KEY = cfg.secretKey; + DOMAIN_NAME = cfg.domainName; + POSTGRES_DB = cfg.postgresDb; + POSTGRES_USER = cfg.postgresUser; + POSTGRES_PASSWORD = cfg.postgresPassword; + POSTGRES_HOST = cfg.postgresHost; + POSTGRES_PORT = (toString cfg.postgresPort); + DJANGO_SETTINGS_MODULE = "config.settings.production"; + # Allowed hosts is * to allow all traffic on service. + # The caddy proxy handles the rest. + ALLOWED_HOSTS = "*"; + }; + volumes = [ + "${cfg.dataDir}/static:/code/static" + "${cfg.dataDir}/media:/code/media" + ]; + extraOptions = [ + "--network=mathesar_network" + "--expose=8000" + ]; + }; + + ################ + # mathesar_db (PostgreSQL Database) + ################ + mathesar_db = { + user = "root"; + image = "postgres:13"; + environment = { + POSTGRES_DB = cfg.postgresDb; + POSTGRES_USER = cfg.postgresUser; + POSTGRES_PASSWORD = cfg.postgresPassword; + PGPORT = toString cfg.postgresPort; + }; + volumes = [ + "${cfg.dataDir}/pgdata:/var/lib/postgresql/data" + ]; + extraOptions = [ + "--network=mathesar_network" + "--expose=${toString cfg.postgresPort}" + ]; + }; + + ############## + # caddy-reverse-proxy + ############## + caddy_reverse_proxy = { + user = "root"; + image = "mathesar/mathesar-caddy:latest"; + ports = [ + "10.20.40.104:${toString cfg.port}:80" + ]; + environment = { + SECRET_KEY = cfg.secretKey; + DOMAIN_NAME = cfg.domainName; + POSTGRES_DB = cfg.postgresDb; + POSTGRES_USER = cfg.postgresUser; + POSTGRES_PASSWORD = cfg.postgresPassword; + POSTGRES_HOST = cfg.postgresHost; + POSTGRES_PORT = toString cfg.postgresPort; + }; + volumes = [ + "${cfg.dataDir}/media:/code/media" + "${cfg.dataDir}/static:/code/static" + "${cfg.dataDir}/caddy:/data" + ]; + extraOptions = [ "--network=mathesar_network" ]; + }; + }; + }; +} diff --git a/components/containers/pgadmin.nix b/components/containers/pgadmin.nix new file mode 100644 index 0000000..fd2b63c --- /dev/null +++ b/components/containers/pgadmin.nix @@ -0,0 +1,53 @@ +{ + config, + pkgs, + ... +}: +let + cfg = config.customServices.pgadmin; +in +{ + options.customServices.pgadmin = + let + lib = pkgs.lib; + in + { + port = lib.mkOption { + type = lib.types.port; + default = 3085; + description = "Port number for the PGAdmin interface"; + }; + dataDir = lib.mkOption { + type = lib.types.path; + default = "/var/lib/pgadmin"; + description = "Directory to store PGAdmin data"; + }; + }; + + config = { + virtualisation.oci-containers.containers = { + ############# + # pgadmin # + ############# + # NOTE settings live in `/var/lib/librechat` manually right now + pgadmin = { + user = "root"; + image = "dpage/pgadmin4:latest"; + ports = [ + "10.20.40.104:${toString cfg.port}:${toString cfg.port}" + ]; + environment = { + PGADMIN_LISTEN_PORT = toString cfg.port; + PGADMIN_DEFAULT_EMAIL = "admin@db.joshuabell.xyz"; + PGADMIN_DEFAULT_PASSWORD = "password"; + }; + volumes = [ + "${cfg.dataDir}:/var/lib/pgadmin" + ]; + extraOptions = [ + "--network=host" + ]; + }; + }; + }; +} diff --git a/hosts/lio/containers/tests.nix b/components/containers/tests.nix similarity index 100% rename from hosts/lio/containers/tests.nix rename to components/containers/tests.nix diff --git a/hosts/linode/l002/nginx.nix b/hosts/linode/l002/nginx.nix index f3034c9..a00124e 100644 --- a/hosts/linode/l002/nginx.nix +++ b/hosts/linode/l002/nginx.nix @@ -54,6 +54,14 @@ proxyPass = "http://10.20.40.104:3080"; }; }; + "db.joshuabell.xyz" = { + enableACME = true; + forceSSL = true; + locations."/" = { + proxyWebsockets = true; + proxyPass = "http://10.20.40.104:3085"; + }; + }; "gist.joshuabell.xyz" = { enableACME = true; forceSSL = true; diff --git a/hosts/lio/containers.nix b/hosts/lio/containers.nix index 7eb2ea6..da75037 100644 --- a/hosts/lio/containers.nix +++ b/hosts/lio/containers.nix @@ -1,5 +1,4 @@ { - config, ... }: { @@ -7,12 +6,12 @@ # NOTE some useful links # nixos containers: https://blog.beardhatcode.be/2020/12/Declarative-Nixos-Containers.html # https://nixos.wiki/wiki/NixOS_Containers - options = {}; + options = { }; imports = [ - ./containers/tests.nix - ./containers/librechat.nix - # ./containers/affine.nix + ../../components/containers/librechat.nix + ../../components/containers/inventory.nix + ../../components/containers/pgadmin.nix ]; config = { @@ -21,6 +20,9 @@ # networking.nat.internalInterfaces = [ "ve-*" ]; # networking.nat.externalInterface = "eth0"; + # mathesar + # services.mathesar.secretKey = "mImvhwyu0cFmtUNOAyOjm6qozWjEmHyrGIpOTZXWW7lnkj5RP3"; + virtualisation.oci-containers.backend = "docker"; security.acme.acceptTerms = true; @@ -32,22 +34,22 @@ recommendedProxySettings = true; recommendedTlsSettings = true; virtualHosts = { - "local.belljm.com" = { - # enableACME = true; - # forceSSL = true; - locations."/".proxyPass = "http://${config.containers.wasabi.localAddress}:80"; - }; - "127.0.0.1" = { - locations."/wasabi/" = { - extraConfig = '' - rewrite ^/wasabi/(.*) /$1 break; - ''; - proxyPass = "http://${config.containers.wasabi.localAddress}:80/"; - }; - locations."/" = { - return = "404"; # or 444 for drop - }; - }; + # "local.belljm.com" = { + # # enableACME = true; + # # forceSSL = true; + # locations."/".proxyPass = "http://${config.containers.wasabi.localAddress}:80"; + # }; + # "127.0.0.1" = { + # locations."/wasabi/" = { + # extraConfig = '' + # rewrite ^/wasabi/(.*) /$1 break; + # ''; + # proxyPass = "http://${config.containers.wasabi.localAddress}:80/"; + # }; + # locations."/" = { + # return = "404"; # or 444 for drop + # }; + # }; "_" = { default = true; locations."/" = {