{ config, pkgs, ... }: let envFile = config.age.secrets.librechat-env.path; in { virtualisation.oci-containers = { containers.meilisearch = { image = "getmeili/meilisearch:v1.12.3"; autoStart = true; volumes = ["librechat_meili:/meili_data"]; environment = { MEILI_HTTP_ADDR = "0.0.0.0:7700"; MEILI_NO_ANALYTICS = "true"; }; environmentFiles = [envFile]; extraOptions = ["--ip=10.89.0.20" "--network=web"]; }; containers.rag_api = { image = "ghcr.io/danny-avila/librechat-rag-api-dev-lite:latest"; autoStart = true; environment = { RAG_PORT = "8000"; # pgvector connection to host Postgres DB_HOST = "10.89.0.1"; # your host on the 'web' network DB_PORT = "5432"; # embeddings: pick one (OpenAI default, or HF/Ollama per docs) # EMBEDDINGS_PROVIDER = "openai"; # RAG_OPENAI_API_KEY is read by RAG API (can also use OPENAI_API_KEY). }; environmentFiles = [envFile]; dependsOn = ["meilisearch"]; extraOptions = ["--add-host=postgres:10.89.0.1" "--ip=10.89.0.21" "--network=web"]; ports = ["127.0.0.1:8000:8000"]; # optional: expose to host for debugging }; containers.mongodb = { image = "mongo:7"; autoStart = true; volumes = [ "librechat_mongo:/data/db" "/var/backup/mongodb:/data/backups" ]; # Enable auth once users exist; see Mongo auth doc. # command = [ "mongod", "--auth" ]; extraOptions = ["--ip=10.89.0.22" "--network=web"]; }; containers.librechat = { image = "ghcr.io/danny-avila/librechat-dev-api:latest"; autoStart = true; ports = ["127.0.0.1:3040:3080"]; dependsOn = ["mongodb" "rag_api" "meilisearch"]; environment = { HOST = "0.0.0.0"; NODE_ENV = "production"; # Mongo URI (start without auth; switch to mongodb://user:pass@mongodb:27017/LibreChat after Step 4) MONGO_URI = "mongodb://mongodb:27017/LibreChat"; MEILI_HOST = "http://meilisearch:7700"; RAG_PORT = "8000"; RAG_API_URL = "http://rag_api:8000"; }; environmentFiles = [envFile]; volumes = [ # Config file still needs to be a bind mount for host management "/var/lib/librechat/librechat.yaml:/app/librechat.yaml:ro" # Use named volumes for application data "librechat_images:/app/client/public/images" "librechat_uploads:/app/uploads" "librechat_logs:/app/api/logs" ]; extraOptions = ["--ip=10.89.0.23" "--network=web"]; }; }; systemd.services."mongo-nightly-dump" = { serviceConfig = { Type = "oneshot"; ExecStart = '' ${pkgs.podman}/bin/podman exec mongodb \ sh -lc 'mongodump --uri="mongodb://adminUser:securePassword@localhost:27017/?authSource=admin" \ --out /data/backups/$(date +%F)' ''; ExecStartPost = '' # Clean up old backups from within the container ${pkgs.podman}/bin/podman exec mongodb \ sh -lc 'find /data/backups -maxdepth 1 -type d -mtime +14 -exec rm -rf {} +' ''; }; }; systemd.timers."mongo-nightly-dump" = { wantedBy = ["timers.target"]; timerConfig.OnCalendar = "daily"; timerConfig.RandomizedDelaySec = "15m"; }; services.traefik.dynamicConfigOptions.http = { services.librechat.loadBalancer.servers = [{url = "http://localhost:3040/";}]; routers.librechat = { rule = "Host(`chat.az-gruppe.com`)"; tls.certResolver = "ionos"; service = "librechat"; entrypoints = "websecure"; }; }; }