diff --git a/hosts/linode/l002/nginx.nix b/hosts/linode/l002/nginx.nix index 34873e5..093b1e1 100644 --- a/hosts/linode/l002/nginx.nix +++ b/hosts/linode/l002/nginx.nix @@ -42,6 +42,14 @@ proxyPass = "http://10.20.40.104:3080"; }; }; + "affine.joshuabell.xyz" = { + enableACME = true; + forceSSL = true; + locations."/" = { + proxyWebsockets = true; + proxyPass = "http://10.20.40.104:3010"; + }; + }; "gist.joshuabell.xyz" = { enableACME = true; forceSSL = true; diff --git a/hosts/lio/containers.nix b/hosts/lio/containers.nix new file mode 100644 index 0000000..8456969 --- /dev/null +++ b/hosts/lio/containers.nix @@ -0,0 +1,65 @@ +{ + config, + ... +}: +{ + + # NOTE some useful links + # nixos containers: https://blog.beardhatcode.be/2020/12/Declarative-Nixos-Containers.html + # https://nixos.wiki/wiki/NixOS_Containers + options = {}; + + imports = [ + ./containers/tests.nix + ./containers/librechat.nix + ./containers/affine.nix + ]; + + config = { + ## Give internet access + # networking.nat.enable = true; + # networking.nat.internalInterfaces = [ "ve-*" ]; + # networking.nat.externalInterface = "eth0"; + + virtualisation.oci-containers.backend = "docker"; + + security.acme.acceptTerms = true; + security.acme.defaults.email = "admin@joshuabell.xyz"; + services.nginx = { + enable = true; + recommendedGzipSettings = true; + recommendedOptimisation = true; + 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 + }; + }; + "_" = { + default = true; + locations."/" = { + return = "404"; # or 444 for drop + }; + }; + }; + }; + + networking.firewall.allowedTCPPorts = [ + 80 + 443 + ]; + }; +} diff --git a/hosts/lio/containers/affine.nix b/hosts/lio/containers/affine.nix new file mode 100644 index 0000000..8019beb --- /dev/null +++ b/hosts/lio/containers/affine.nix @@ -0,0 +1,135 @@ +{ + config, + pkgs, + ... +}: +let + cfg = config.services.affine; +in +{ + options.services.affine = + let + lib = pkgs.lib; + in + { + port = lib.mkOption { + type = lib.types.port; + default = 3010; + description = "Port number for the AFFiNE service"; + }; + dataDir = lib.mkOption { + type = lib.types.path; + default = "/var/lib/affine"; + description = "Directory to store AFFiNE data"; + }; + }; + + config = { + systemd.services.create-affine-network = { + description = "Create Docker network for LibreChat"; + serviceConfig.Type = "oneshot"; + wantedBy = [ "multi-user.target" ]; + script = '' + if ! ${pkgs.docker}/bin/docker network inspect affine-network >/dev/null 2>&1; then + ${pkgs.docker}/bin/docker network create affine-network + fi + ''; + }; + + virtualisation.oci-containers.containers = { + ############# + # AFFiNE # + ############# + # NOTE settings live in `/var/lib/librechat` manually right now + # Note to remove limits from user need to mark user as subscriber in the database manually + # docker exec it affine_postgres psql -U affine + # select id, feature, configs from features; + # select * from users; + # select * from user_features; + # feature_id = YOUR FEATURE ID YOU WANT TO ASSIGN (get it from 'List possible feature id's') + # user_id = YOUR USER ID YOU WANT TO CHANGE (get it from 'List users with id's') + # update user_features set feature_id = 35 where user_id = 'xxxxxx-xxxx-xxxxxxx-xxxx-xxxxxxxxxxxx'; + affine = { + user = "root"; + image = "ghcr.io/toeverything/affine-graphql:stable"; + ports = [ + "10.20.40.104:${toString cfg.port}:${toString cfg.port}" + ]; + dependsOn = [ + "affine_redis" + "affine_postgres" + "affine_migration" + ]; + environment = { + REDIS_SERVER_HOST = "affine_redis"; + DATABASE_URL = "postgresql://affine:password@affine_postgres:5432/affine"; + }; + volumes = [ + "${cfg.dataDir}/storage:/root/.affine/storage" + "${cfg.dataDir}/config:/root/.affine/config" + ]; + extraOptions = [ + "--network=affine-network" + ]; + }; + + affine_migration = { + user = "root"; + image = "ghcr.io/toeverything/affine-graphql:stable"; + dependsOn = [ + "affine_redis" + "affine_postgres" + ]; + volumes = [ + "${cfg.dataDir}/storage:/root/.affine/storage" + "${cfg.dataDir}/config:/root/.affine/config" + ]; + environment = { + REDIS_SERVER_HOST = "affine_redis"; + DATABASE_URL = "postgresql://affine:password@affine_postgres:5432/affine"; + }; + cmd = [ + "sh" + "-c" + "node ./scripts/self-host-predeploy.js" + ]; + extraOptions = [ "--network=affine-network" ]; + }; + + affine_redis = { + user = "root"; + image = "redis"; + extraOptions = [ + "--network=affine-network" + "--health-cmd=\"CMD-SHELL redis-cli ping\"" + "--health-interval=30s" + "--health-timeout=10s" + "--health-retries=3" + "--health-start-period=30s" + ]; + }; + + affine_postgres = { + user = "root"; + image = "postgres:16"; + environment = { + POSTGRES_USER = "affine"; + POSTGRES_PASSWORD = "password"; + POSTGRES_DB = "affine"; + POSTGRES_INITDB_ARGS = "--data-checksums"; + }; + volumes = [ + "${cfg.dataDir}/postgres:/var/lib/postgresql/data" + ]; + extraOptions = [ + "--network=affine-network" + "--health-cmd=\"CMD-SHELL pg_isready -U affine\"" + "--health-interval=10s" + "--health-timeout=5s" + "--health-retries=5" + "--health-start-period=30s" + ]; + }; + }; + }; +} diff --git a/hosts/lio/containers/librechat.nix b/hosts/lio/containers/librechat.nix new file mode 100644 index 0000000..cad1fe1 --- /dev/null +++ b/hosts/lio/containers/librechat.nix @@ -0,0 +1,147 @@ +{ + config, + pkgs, + ... +}: +let + cfg = config.services.librechat; +in +{ + options.services.librechat = + let + lib = pkgs.lib; + in + { + port = lib.mkOption { + type = lib.types.port; + default = 3080; + description = "Port number for the LibreChat API service"; + }; + ragPort = lib.mkOption { + type = lib.types.port; + default = 8000; + description = "Port number for the RAG API service"; + }; + dataDir = lib.mkOption { + type = lib.types.path; + default = "/var/lib/librechat"; + description = "Directory to store LibreChat data"; + }; + }; + + config = { + systemd.services.create-librechat-network = { + description = "Create Docker network for LibreChat"; + serviceConfig.Type = "oneshot"; + wantedBy = [ "multi-user.target" ]; + script = '' + if ! ${pkgs.docker}/bin/docker network inspect librechat-network >/dev/null 2>&1; then + ${pkgs.docker}/bin/docker network create librechat-network + fi + ''; + }; + + virtualisation.oci-containers.containers = { + ############# + # librechat # + ############# + # NOTE settings live in `/var/lib/librechat` manually right now + librechat = { + user = "root"; + image = "ghcr.io/danny-avila/librechat-dev:latest"; + ports = [ + "10.20.40.104:${toString cfg.port}:${toString cfg.port}" + ]; + dependsOn = [ + "librechat_mongodb" + "librechat_rag_api" + ]; + environment = { + HOST = "0.0.0.0"; + MONGO_URI = "mongodb://librechat_mongodb:27017/LibreChat"; + MEILI_HOST = "http://librechat_meilisearch:7700"; + RAG_PORT = toString cfg.ragPort; + RAG_API_URL = "http://librechat_rag_api:${toString cfg.ragPort}"; + # DEBUG_CONSOLE = "true"; + # DEBUG_LOGGING = "true"; + }; + environmentFiles = [ "${cfg.dataDir}/.env" ]; + volumes = [ + "${cfg.dataDir}/.env:/app/.env" + "${cfg.dataDir}/librechat.yaml:/app/librechat.yaml" + "${cfg.dataDir}/images:/app/client/public/images" + "${cfg.dataDir}/logs:/app/api/logs" + ]; + extraOptions = [ + "--network=librechat-network" + "--add-host=azureproxy:10.20.40.180" + ]; + }; + + librechat_mongodb = { + user = "root"; + image = "mongo"; + volumes = [ + "${cfg.dataDir}/data-node:/data/db" + ]; + cmd = [ + "mongod" + "--noauth" + ]; + extraOptions = [ "--network=librechat-network" ]; + }; + + librechat_meilisearch = { + user = "root"; + image = "getmeili/librechat_meilisearch:v1.7.3"; + environment = { + MEILI_HOST = "http://librechat_meilisearch:7700"; + MEILI_NO_ANALYTICS = "true"; + }; + volumes = [ + "${cfg.dataDir}/meili_data_v1.7:/meili_data" + ]; + extraOptions = [ "--network=librechat-network" ]; + }; + + librechat_vectordb = { + user = "root"; + image = "ankane/pgvector:latest"; + environment = { + POSTGRES_DB = "mydatabase"; + POSTGRES_USER = "myuser"; + POSTGRES_PASSWORD = "mypassword"; + }; + volumes = [ + "${cfg.dataDir}/pgdata2:/var/lib/postgresql/data" + ]; + extraOptions = [ "--network=librechat-network" ]; + }; + + librechat_rag_api = { + user = "root"; + image = "ghcr.io/danny-avila/librechat-rag-api-dev-lite:latest"; + environment = { + DB_HOST = "librechat_vectordb"; + RAG_PORT = toString cfg.ragPort; + OPENAI_API_KEY = "not_using_openai"; + }; + dependsOn = [ "librechat_vectordb" ]; + environmentFiles = [ "${cfg.dataDir}/.env" ]; + extraOptions = [ "--network=librechat-network" ]; + }; + + # TODO revisit local whisper, for now I am using groq free for STT + # librechat_whisper = { + # user = "root"; + # image = "onerahmet/openai-whisper-asr-webservice:latest"; + # # ports = [ "8080:8080" ]; + # environment = { + # ASR_MODEL = "base"; # You can change to small, medium, large, etc. + # ASR_ENGINE = "openai_whisper"; + # }; + # extraOptions = [ "--network=librechat-network" ]; + # }; + }; + }; +} diff --git a/hosts/lio/containers/tests.nix b/hosts/lio/containers/tests.nix new file mode 100644 index 0000000..b4c6659 --- /dev/null +++ b/hosts/lio/containers/tests.nix @@ -0,0 +1,39 @@ +{ + ... +}: +{ + options = { }; + + config = { + # Random test, visit http://192.168.100.11/ + containers.wasabi = { + ephemeral = true; + autoStart = true; + privateNetwork = true; + hostAddress = "192.168.100.2"; + localAddress = "192.168.100.11"; + config = + { config, pkgs, ... }: + { + system.stateVersion = "24.11"; + services.httpd.enable = true; + services.httpd.adminAddr = "foo@example.org"; + networking.firewall = { + enable = true; + allowedTCPPorts = [ 80 ]; + }; + }; + }; + + virtualisation.oci-containers.containers = { + # Example of defining a container, visit http://localhost:8085/ + "nginx_simple" = { + # autoStart = true; this is default true + image = "nginx:latest"; + ports = [ + "127.0.0.1:8085:80" + ]; + }; + }; + }; +} diff --git a/hosts/lio/containers_test.nix b/hosts/lio/containers_test.nix deleted file mode 100644 index 12e9bdd..0000000 --- a/hosts/lio/containers_test.nix +++ /dev/null @@ -1,232 +0,0 @@ -{ - config, - pkgs, - ... -}: -{ - - # NOTE some useful links - # nixos containers: https://blog.beardhatcode.be/2020/12/Declarative-Nixos-Containers.html - # https://nixos.wiki/wiki/NixOS_Containers - # - - options.services.librechat = - let - lib = pkgs.lib; - in - { - enable = lib.mkEnableOption "LibreChat service"; - port = lib.mkOption { - type = lib.types.port; - default = 3080; - description = "Port number for the LibreChat API service"; - }; - ragPort = lib.mkOption { - type = lib.types.port; - default = 8000; - description = "Port number for the RAG API service"; - }; - dataDir = lib.mkOption { - type = lib.types.path; - default = "/var/lib/librechat"; - description = "Directory to store LibreChat data"; - }; - }; - - config = { - ## Give internet access - # networking.nat.enable = true; - # networking.nat.internalInterfaces = [ "ve-*" ]; - # networking.nat.externalInterface = "eth0"; - - # Random test - containers.wasabi = { - ephemeral = true; - autoStart = true; - privateNetwork = true; - hostAddress = "192.168.100.2"; - localAddress = "192.168.100.11"; - config = - { config, pkgs, ... }: - { - system.stateVersion = "24.11"; - services.httpd.enable = true; - services.httpd.adminAddr = "foo@example.org"; - networking.firewall = { - enable = true; - allowedTCPPorts = [ 80 ]; - }; - }; - }; - - virtualisation.oci-containers = { - backend = "docker"; # or "podman" - containers = { - # Example of defining a container from the compose file - "test_nginx" = { - # autoStart = true; this is default true - image = "nginx:latest"; - ports = [ - "127.0.0.1:8085:80" - ]; - }; - - ############# - # librechat # - ############# - # NOTE settings live in `/var/lib/librechat` manually right now - librechat = { - user = "root"; - image = "ghcr.io/danny-avila/librechat-dev:latest"; - ports = [ - "${toString config.services.librechat.port}:${toString config.services.librechat.port}" - ]; - dependsOn = [ - "librechat_mongodb" - "librechat_rag_api" - ]; - environment = { - HOST = "0.0.0.0"; - MONGO_URI = "mongodb://librechat_mongodb:27017/LibreChat"; - MEILI_HOST = "http://librechat_meilisearch:7700"; - RAG_PORT = toString config.services.librechat.ragPort; - RAG_API_URL = "http://librechat_rag_api:${toString config.services.librechat.ragPort}"; - # DEBUG_CONSOLE = "true"; - # DEBUG_LOGGING = "true"; - }; - environmentFiles = [ "${config.services.librechat.dataDir}/.env" ]; - volumes = [ - "${config.services.librechat.dataDir}/.env:/app/.env" - "${config.services.librechat.dataDir}/librechat.yaml:/app/librechat.yaml" - "${config.services.librechat.dataDir}/images:/app/client/public/images" - "${config.services.librechat.dataDir}/logs:/app/api/logs" - ]; - extraOptions = [ - "--network=librechat-network" - "--add-host=azureproxy:10.20.40.180" - ]; - }; - - librechat_mongodb = { - user = "root"; - image = "mongo"; - volumes = [ - "${config.services.librechat.dataDir}/data-node:/data/db" - ]; - cmd = [ - "mongod" - "--noauth" - ]; - extraOptions = [ "--network=librechat-network" ]; - }; - - librechat_meilisearch = { - user = "root"; - image = "getmeili/librechat_meilisearch:v1.7.3"; - environment = { - MEILI_HOST = "http://librechat_meilisearch:7700"; - MEILI_NO_ANALYTICS = "true"; - }; - volumes = [ - "${config.services.librechat.dataDir}/meili_data_v1.7:/meili_data" - ]; - extraOptions = [ "--network=librechat-network" ]; - }; - - librechat_vectordb = { - user = "root"; - image = "ankane/pgvector:latest"; - environment = { - POSTGRES_DB = "mydatabase"; - POSTGRES_USER = "myuser"; - POSTGRES_PASSWORD = "mypassword"; - }; - volumes = [ - "${config.services.librechat.dataDir}/pgdata2:/var/lib/postgresql/data" - ]; - extraOptions = [ "--network=librechat-network" ]; - }; - - librechat_rag_api = { - user = "root"; - image = "ghcr.io/danny-avila/librechat-rag-api-dev-lite:latest"; - environment = { - DB_HOST = "librechat_vectordb"; - RAG_PORT = toString config.services.librechat.ragPort; - OPENAI_API_KEY = "not_using_openai"; - }; - dependsOn = [ "librechat_vectordb" ]; - environmentFiles = [ "${config.services.librechat.dataDir}/.env" ]; - extraOptions = [ "--network=librechat-network" ]; - }; - - # TODO revisit local whisper, for now I am using groq free for STT - # librechat_whisper = { - # user = "root"; - # image = "onerahmet/openai-whisper-asr-webservice:latest"; - # # ports = [ "8080:8080" ]; - # environment = { - # ASR_MODEL = "base"; # You can change to small, medium, large, etc. - # ASR_ENGINE = "openai_whisper"; - # }; - # extraOptions = [ "--network=librechat-network" ]; - # }; - - ######### - # grist # - ######### - - }; - }; - - systemd.services.create-librechat-network = { - description = "Create Docker network for LibreChat"; - serviceConfig.Type = "oneshot"; - wantedBy = [ "multi-user.target" ]; - script = '' - if ! ${pkgs.docker}/bin/docker network inspect librechat-network >/dev/null 2>&1; then - ${pkgs.docker}/bin/docker network create librechat-network - fi - ''; - }; - - security.acme.acceptTerms = true; - security.acme.defaults.email = "admin@joshuabell.xyz"; - services.nginx = { - enable = true; - recommendedGzipSettings = true; - recommendedOptimisation = true; - 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 - }; - }; - "_" = { - default = true; - locations."/" = { - return = "404"; # or 444 for drop - }; - }; - }; - }; - - networking.firewall.allowedTCPPorts = [ - 80 - 443 - ]; - }; -} diff --git a/hosts/lio/flake.nix b/hosts/lio/flake.nix index 1ab145a..ee884e0 100644 --- a/hosts/lio/flake.nix +++ b/hosts/lio/flake.nix @@ -43,7 +43,7 @@ modules = [ ./configuration.nix ./hardware-configuration.nix - ./containers_test.nix + ./containers.nix ( { pkgs, ... }: {