diff --git a/.env.example b/.env.example index eb7103e..068c510 100644 --- a/.env.example +++ b/.env.example @@ -144,9 +144,11 @@ NEO4J_HOSTNAME=neo4j.yourdomain.com GRAFANA_HOSTNAME=grafana.yourdomain.com PROMETHEUS_HOSTNAME=prometheus.yourdomain.com PORTAINER_HOSTNAME=portainer.yourdomain.com +POSTIZ_HOSTNAME=postiz.yourdomain.com LETTA_HOSTNAME=letta.yourdomain.com QDRANT_HOSTNAME=qdrant.yourdomain.com COMFYUI_HOSTNAME=comfyui.yourdomain.com +RAGAPP_HOSTNAME=ragapp.yourdomain.com LETSENCRYPT_EMAIL= # Everything below this point is optional. @@ -154,6 +156,14 @@ LETSENCRYPT_EMAIL= RUN_N8N_IMPORT= +############ +# [required] +# RAGApp credentials - used for Basic Auth in Caddy +############ + +RAGAPP_USERNAME= +RAGAPP_PASSWORD= + # # ####### @@ -315,3 +325,62 @@ COMPOSE_PROFILES="n8n,flowise,monitoring" PROMETHEUS_PASSWORD_HASH= SEARXNG_PASSWORD_HASH= COMFYUI_PASSWORD_HASH= +RAGAPP_PASSWORD_HASH= + +############ +# Postiz configuration +# Reference: https://docs.postiz.com/configuration/reference +# To protect Postiz via Caddy basic auth (optional), set these: +############ + +POSTIZ_DISABLE_REGISTRATION=false + +############ +# Postiz Social Media Integrations +# Leave blank if not used. Provide credentials from each platform. +############ + +X_API_KEY= +X_API_SECRET= + +LINKEDIN_CLIENT_ID= +LINKEDIN_CLIENT_SECRET= + +REDDIT_CLIENT_ID= +REDDIT_CLIENT_SECRET= + +GITHUB_CLIENT_ID= +GITHUB_CLIENT_SECRET= + +BEEHIIVE_API_KEY= +BEEHIIVE_PUBLICATION_ID= + +THREADS_APP_ID= +THREADS_APP_SECRET= + +FACEBOOK_APP_ID= +FACEBOOK_APP_SECRET= + +YOUTUBE_CLIENT_ID= +YOUTUBE_CLIENT_SECRET= + +TIKTOK_CLIENT_ID= +TIKTOK_CLIENT_SECRET= + +PINTEREST_CLIENT_ID= +PINTEREST_CLIENT_SECRET= + +DRIBBBLE_CLIENT_ID= +DRIBBBLE_CLIENT_SECRET= + +DISCORD_CLIENT_ID= +DISCORD_CLIENT_SECRET= +DISCORD_BOT_TOKEN_ID= + +SLACK_ID= +SLACK_SECRET= +SLACK_SIGNING_SECRET= + +MASTODON_URL=https://mastodon.social +MASTODON_CLIENT_ID= +MASTODON_CLIENT_SECRET= diff --git a/Caddyfile b/Caddyfile index 36d67df..68b11e4 100644 --- a/Caddyfile +++ b/Caddyfile @@ -25,6 +25,14 @@ reverse_proxy nginx:80 } +# RAGApp +{$RAGAPP_HOSTNAME} { + basic_auth { + {$RAGAPP_USERNAME} {$RAGAPP_PASSWORD_HASH} + } + reverse_proxy ragapp:8000 +} + # Langfuse {$LANGFUSE_HOSTNAME} { reverse_proxy langfuse-web:3000 @@ -58,6 +66,11 @@ reverse_proxy portainer:9000 } +# Postiz +{$POSTIZ_HOSTNAME} { + reverse_proxy postiz:5000 +} + # Letta {$LETTA_HOSTNAME} { reverse_proxy letta:8283 diff --git a/README.md b/README.md index 9c408ee..20d6c4d 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,9 @@ The installer also makes the following powerful open-source tools **available fo ✅ [**ComfyUI**](https://github.com/comfyanonymous/ComfyUI) - A powerful, node-based UI for Stable Diffusion workflows. Build and run image-generation pipelines visually, with support for custom nodes and extensions. +✅ [**RAGApp**](https://github.com/ragapp/ragapp) - Open-source application to build Retrieval-Augmented Generation (RAG) assistants over your data. Provides a web UI for chat and an HTTP API for integration with your workflows. + + ✅ [**Dify**](https://dify.ai/) - An open-source AI application development platform that provides comprehensive LLMOps capabilities, including workflow management, prompt engineering, RAG pipelines, and AI agent orchestration. Perfect for building production-ready AI applications. ✅ [**Qdrant**](https://qdrant.tech/) - A high-performance open-source vector store, specialized for AI. While Supabase also offers vector capabilities, Qdrant is included for its speed, making it ideal for demanding AI tasks. @@ -60,6 +63,8 @@ The installer also makes the following powerful open-source tools **available fo ✅ [**Portainer**](https://www.portainer.io/) - A lightweight, secure web UI to manage your Docker environment (containers, images, volumes, networks) with ease. +✅ [**Postiz**](https://postiz.com/) - An open-source social media scheduling and publishing platform. + ### Included Community Workflows Get started quickly with a vast library of pre-built automations (optional import during setup)! This collection includes over 300 workflows covering a wide range of use cases: @@ -137,6 +142,14 @@ After successful installation, your services are up and running! Here's how to g - **Prometheus:** `prometheus.yourdomain.com` (Typically used as a data source for Grafana) - **Portainer:** `portainer.yourdomain.com` (Protected by Caddy basic auth; on first login, complete Portainer admin setup) - **ComfyUI:** `comfyui.yourdomain.com` (Node-based Stable Diffusion UI) + - **Postiz:** `postiz.yourdomain.com` + +### Optional Internal Utility: Python Runner + +- **What it is**: An internal-only service to run your custom Python code inside the same Docker network as your other services (n8n, Postgres, Qdrant, etc.). No external ports are exposed, and it is not proxied by Caddy. +- **How to enable**: Select “Python Runner” in the Service Selection Wizard during install/update, or add the profile manually: `COMPOSE_PROFILES=...,python-runner`. +- **Where to put code**: Place your Python files in `python-runner/`. The default entry point is `python-runner/main.py`. +- **Dependencies**: Add them to `python-runner/requirements.txt`; they will be installed automatically on container start. 2. **Explore n8n:** @@ -216,6 +229,14 @@ This can be useful for removing old images and freeing up space, but be aware th Here are solutions to common issues you might encounter: +### Sites not loading even after following the instructions + +- **Symptom:** Your domains/sites do not open or return errors even though you completed all installation steps. +- **Likely cause:** Your VPS does not have enough resources for the set of services you selected. +- **What to try:** + 1. Check current CPU and RAM usage (e.g., with `top`/`htop`, `free -h`, and `docker stats`). If resources are saturated, upgrade the server or reduce the number of running services. + 2. Try a minimal configuration — start only `n8n` and verify it comes up. If it works in this minimal setup, enable other services gradually while monitoring the load. + ### Temporary "Dangerous Site" Warning in Browser - **Symptom:** Immediately after deploying the services, your browser (e.g., Chrome) might display a "Dangerous Site" or similar security warning when you try to access your services. This warning typically disappears after some time (e.g., within a few hours or by the next day). diff --git a/docker-compose.yml b/docker-compose.yml index b01b0ee..47c5b20 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -17,37 +17,41 @@ volumes: weaviate_data: portainer_data: comfyui_data: + postiz-config: + postiz-uploads: x-n8n: &service-n8n build: context: ./n8n pull: true environment: &service-n8n-env - DB_TYPE: postgresdb - DB_POSTGRESDB_HOST: postgres - DB_POSTGRESDB_USER: postgres - DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD} DB_POSTGRESDB_DATABASE: postgres - N8N_TRUST_PROXY: true - N8N_DIAGNOSTICS_ENABLED: false - N8N_PERSONALIZATION_ENABLED: false - N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY} - N8N_USER_MANAGEMENT_JWT_SECRET: ${N8N_USER_MANAGEMENT_JWT_SECRET} - WEBHOOK_URL: ${N8N_HOSTNAME:+https://}${N8N_HOSTNAME:-http://localhost:5678}/ - N8N_METRICS: true - NODE_ENV: production + DB_POSTGRESDB_HOST: postgres + DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD} + DB_POSTGRESDB_USER: postgres + DB_TYPE: postgresdb EXECUTIONS_MODE: queue - N8N_RUNNERS_ENABLED: true - QUEUE_HEALTH_CHECK_ACTIVE: true - QUEUE_BULL_REDIS_HOST: ${REDIS_HOST:-redis} - QUEUE_BULL_REDIS_PORT: ${REDIS_PORT:-6379} - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS: true - N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE: true - NODE_FUNCTION_ALLOW_BUILTIN: "*" - NODE_FUNCTION_ALLOW_EXTERNAL: cheerio,axios,moment,lodash + LANGCHAIN_API_KEY: ${LANGCHAIN_API_KEY} LANGCHAIN_ENDPOINT: ${LANGCHAIN_ENDPOINT} LANGCHAIN_TRACING_V2: ${LANGCHAIN_TRACING_V2} - LANGCHAIN_API_KEY: ${LANGCHAIN_API_KEY} + N8N_BINARY_DATA_MODE: filesystem + N8N_PAYLOAD_SIZE_MAX: 256 + N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE: true + N8N_DIAGNOSTICS_ENABLED: false + N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY} + N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS: true + N8N_METRICS: true + N8N_PERSONALIZATION_ENABLED: false + N8N_RUNNERS_ENABLED: true + N8N_TRUST_PROXY: true + N8N_USER_MANAGEMENT_JWT_SECRET: ${N8N_USER_MANAGEMENT_JWT_SECRET} + NODE_ENV: production + NODE_FUNCTION_ALLOW_BUILTIN: "*" + NODE_FUNCTION_ALLOW_EXTERNAL: cheerio,axios,moment,lodash + QUEUE_BULL_REDIS_HOST: ${REDIS_HOST:-redis} + QUEUE_BULL_REDIS_PORT: ${REDIS_PORT:-6379} + QUEUE_HEALTH_CHECK_ACTIVE: true + WEBHOOK_URL: ${N8N_HOSTNAME:+https://}${N8N_HOSTNAME:-http://localhost:5678}/ x-ollama: &service-ollama image: ollama/ollama:latest @@ -196,28 +200,32 @@ services: - caddy-data:/data:rw - caddy-config:/config:rw environment: - - N8N_HOSTNAME=${N8N_HOSTNAME} - - WEBUI_HOSTNAME=${WEBUI_HOSTNAME} - - FLOWISE_HOSTNAME=${FLOWISE_HOSTNAME} - - DIFY_HOSTNAME=${DIFY_HOSTNAME} - - SUPABASE_HOSTNAME=${SUPABASE_HOSTNAME} - - SEARXNG_HOSTNAME=${SEARXNG_HOSTNAME} - - LANGFUSE_HOSTNAME=${LANGFUSE_HOSTNAME} - - WEAVIATE_HOSTNAME=${WEAVIATE_HOSTNAME} - - QDRANT_HOSTNAME=${QDRANT_HOSTNAME} - - NEO4J_HOSTNAME=${NEO4J_HOSTNAME} - - LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL:-internal} - - PROMETHEUS_HOSTNAME=${PROMETHEUS_HOSTNAME} - - GRAFANA_HOSTNAME=${GRAFANA_HOSTNAME} - - LETTA_HOSTNAME=${LETTA_HOSTNAME} - - PROMETHEUS_USERNAME=${PROMETHEUS_USERNAME} - - PROMETHEUS_PASSWORD_HASH=${PROMETHEUS_PASSWORD_HASH} - - SEARXNG_USERNAME=${SEARXNG_USERNAME} - - SEARXNG_PASSWORD_HASH=${SEARXNG_PASSWORD_HASH} - - PORTAINER_HOSTNAME=${PORTAINER_HOSTNAME} - COMFYUI_HOSTNAME=${COMFYUI_HOSTNAME} - - COMFYUI_USERNAME=${COMFYUI_USERNAME} - COMFYUI_PASSWORD_HASH=${COMFYUI_PASSWORD_HASH} + - COMFYUI_USERNAME=${COMFYUI_USERNAME} + - DIFY_HOSTNAME=${DIFY_HOSTNAME} + - FLOWISE_HOSTNAME=${FLOWISE_HOSTNAME} + - GRAFANA_HOSTNAME=${GRAFANA_HOSTNAME} + - LANGFUSE_HOSTNAME=${LANGFUSE_HOSTNAME} + - LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL:-internal} + - LETTA_HOSTNAME=${LETTA_HOSTNAME} + - N8N_HOSTNAME=${N8N_HOSTNAME} + - NEO4J_HOSTNAME=${NEO4J_HOSTNAME} + - PORTAINER_HOSTNAME=${PORTAINER_HOSTNAME} + - POSTIZ_HOSTNAME=${POSTIZ_HOSTNAME} + - PROMETHEUS_HOSTNAME=${PROMETHEUS_HOSTNAME} + - PROMETHEUS_PASSWORD_HASH=${PROMETHEUS_PASSWORD_HASH} + - PROMETHEUS_USERNAME=${PROMETHEUS_USERNAME} + - QDRANT_HOSTNAME=${QDRANT_HOSTNAME} + - RAGAPP_HOSTNAME=${RAGAPP_HOSTNAME} + - RAGAPP_PASSWORD_HASH=${RAGAPP_PASSWORD_HASH} + - RAGAPP_USERNAME=${RAGAPP_USERNAME} + - SEARXNG_HOSTNAME=${SEARXNG_HOSTNAME} + - SEARXNG_PASSWORD_HASH=${SEARXNG_PASSWORD_HASH} + - SEARXNG_USERNAME=${SEARXNG_USERNAME} + - SUPABASE_HOSTNAME=${SUPABASE_HOSTNAME} + - WEAVIATE_HOSTNAME=${WEAVIATE_HOSTNAME} + - WEBUI_HOSTNAME=${WEBUI_HOSTNAME} cap_drop: - ALL cap_add: @@ -593,6 +601,12 @@ services: retries: 5 start_period: 10s + ragapp: + image: ragapp/ragapp:latest + container_name: ragapp + profiles: ["ragapp"] + restart: unless-stopped + portainer: image: portainer/portainer-ce:latest container_name: portainer @@ -602,6 +616,64 @@ services: - portainer_data:/data - ${DOCKER_SOCKET_LOCATION:-/var/run/docker.sock}:/var/run/docker.sock + postiz: + image: ghcr.io/gitroomhq/postiz-app:latest + container_name: postiz + restart: always + environment: + BACKEND_INTERNAL_URL: http://postiz:3000 + DATABASE_URL: "postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/postgres?schema=postiz" + DISABLE_REGISTRATION: ${POSTIZ_DISABLE_REGISTRATION} + FRONTEND_URL: ${POSTIZ_HOSTNAME:+https://}${POSTIZ_HOSTNAME} + IS_GENERAL: "true" # Required for self-hosting. + JWT_SECRET: ${JWT_SECRET} + MAIN_URL: ${POSTIZ_HOSTNAME:+https://}${POSTIZ_HOSTNAME} + NEXT_PUBLIC_BACKEND_URL: ${POSTIZ_HOSTNAME:+https://}${POSTIZ_HOSTNAME}/api + NEXT_PUBLIC_UPLOAD_DIRECTORY: "/uploads" + REDIS_URL: "redis://redis:6379" + STORAGE_PROVIDER: "local" + UPLOAD_DIRECTORY: "/uploads" + # Social Media API Settings + X_API_KEY: ${X_API_KEY} + X_API_SECRET: ${X_API_SECRET} + LINKEDIN_CLIENT_ID: ${LINKEDIN_CLIENT_ID} + LINKEDIN_CLIENT_SECRET: ${LINKEDIN_CLIENT_SECRET} + REDDIT_CLIENT_ID: ${REDDIT_CLIENT_ID} + REDDIT_CLIENT_SECRET: ${REDDIT_CLIENT_SECRET} + GITHUB_CLIENT_ID: ${GITHUB_CLIENT_ID} + GITHUB_CLIENT_SECRET: ${GITHUB_CLIENT_SECRET} + BEEHIIVE_API_KEY: ${BEEHIIVE_API_KEY} + BEEHIIVE_PUBLICATION_ID: ${BEEHIIVE_PUBLICATION_ID} + THREADS_APP_ID: ${THREADS_APP_ID} + THREADS_APP_SECRET: ${THREADS_APP_SECRET} + FACEBOOK_APP_ID: ${FACEBOOK_APP_ID} + FACEBOOK_APP_SECRET: ${FACEBOOK_APP_SECRET} + YOUTUBE_CLIENT_ID: ${YOUTUBE_CLIENT_ID} + YOUTUBE_CLIENT_SECRET: ${YOUTUBE_CLIENT_SECRET} + TIKTOK_CLIENT_ID: ${TIKTOK_CLIENT_ID} + TIKTOK_CLIENT_SECRET: ${TIKTOK_CLIENT_SECRET} + PINTEREST_CLIENT_ID: ${PINTEREST_CLIENT_ID} + PINTEREST_CLIENT_SECRET: ${PINTEREST_CLIENT_SECRET} + DRIBBBLE_CLIENT_ID: ${DRIBBBLE_CLIENT_ID} + DRIBBBLE_CLIENT_SECRET: ${DRIBBBLE_CLIENT_SECRET} + DISCORD_CLIENT_ID: ${DISCORD_CLIENT_ID} + DISCORD_CLIENT_SECRET: ${DISCORD_CLIENT_SECRET} + DISCORD_BOT_TOKEN_ID: ${DISCORD_BOT_TOKEN_ID} + SLACK_ID: ${SLACK_ID} + SLACK_SECRET: ${SLACK_SECRET} + SLACK_SIGNING_SECRET: ${SLACK_SIGNING_SECRET} + MASTODON_URL: ${MASTODON_URL} + MASTODON_CLIENT_ID: ${MASTODON_CLIENT_ID} + MASTODON_CLIENT_SECRET: ${MASTODON_CLIENT_SECRET} + volumes: + - postiz-config:/config/ + - postiz-uploads:/uploads/ + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_healthy + comfyui: image: yanwk/comfyui-boot:cu124-slim container_name: comfyui @@ -616,3 +688,13 @@ services: interval: 10s timeout: 5s retries: 5 + + python-runner: + image: python:3.11-slim + container_name: python-runner + profiles: ["python-runner"] + restart: unless-stopped + working_dir: /app + command: /bin/sh -c 'if [ -f /app/requirements.txt ]; then python -m pip install --no-cache-dir -r /app/requirements.txt; fi; python /app/main.py' + volumes: + - ./python-runner:/app diff --git a/n8n-installer-developer-guide.md b/n8n-installer-developer-guide.md index 9be7ad3..7b02530 100644 --- a/n8n-installer-developer-guide.md +++ b/n8n-installer-developer-guide.md @@ -305,6 +305,56 @@ volumes: --- +## 🐍 Internal Utility Service: python-runner (Optional) + +**Purpose**: Lightweight internal container to run custom user Python scripts inside the compose network without exposing any ports. + +- **Image**: `python:3.11-slim` +- **Profiles**: `python-runner` (disabled by default; enabled via wizard or `.env`) +- **Mount**: `./python-runner:/app` +- **Command**: Installs `requirements.txt` if present, then runs `python /app/main.py`. +- **Network**: Joins the default compose network (`localai_default`), so it can reach other services by their container names (e.g., `n8n`, `postgres`, `redis`, `qdrant`). +- **Security/Exposure**: No external ports, no reverse proxy, no domains. Internal-only. + +### How to enable (Wizard) + +- Run `sudo bash ./scripts/install.sh` (initial) or `sudo bash ./scripts/update.sh` (update) and select **Python Runner** in the wizard. + +### How to enable (manually) + +Add the profile to `.env` so it is managed by the normal startup flow: +```bash +COMPOSE_PROFILES="...,python-runner" +``` + +Or start on-demand from the CLI without changing `.env`: +```bash +docker compose -p localai --profile python-runner up -d python-runner +``` + +### Where to put your code + +- Local path: `python-runner/` +- Entry file: `python-runner/main.py` +- Optional deps: `python-runner/requirements.txt` (installed automatically on container start) + +### Developing and running your script + +1) Edit `python-runner/main.py` with your logic. Example: connect to `postgres` using the hostname `postgres` and credentials from `.env`. +2) Add dependencies to `python-runner/requirements.txt` if needed. +3) Start or restart the service: +```bash +docker compose -p localai --profile python-runner up -d --force-recreate python-runner +``` +4) View logs: +```bash +docker compose -p localai logs -f python-runner +``` + +This service is intentionally minimal to avoid conflicts and can be extended by users as needed. + +--- + ## 🌐 Network Architecture ### **Caddyfile Configuration** diff --git a/python-runner/main.py b/python-runner/main.py new file mode 100644 index 0000000..e2ec0d2 --- /dev/null +++ b/python-runner/main.py @@ -0,0 +1,3 @@ +print("Python runner is up!") + + diff --git a/python-runner/requirements.txt b/python-runner/requirements.txt new file mode 100644 index 0000000..e69de29 diff --git a/scripts/03_generate_secrets.sh b/scripts/03_generate_secrets.sh index 783758f..36159b1 100755 --- a/scripts/03_generate_secrets.sh +++ b/scripts/03_generate_secrets.sh @@ -52,6 +52,7 @@ declare -A VARS_TO_GENERATE=( # Dify environment variables ["DIFY_SECRET_KEY"]="secret:64" # Dify application secret key (maps to SECRET_KEY in Dify) ["COMFYUI_PASSWORD"]="password:32" # Added ComfyUI basic auth password + ["RAGAPP_PASSWORD"]="password:32" # Added RAGApp basic auth password ) # Initialize existing_env_vars and attempt to read .env if it exists @@ -409,6 +410,7 @@ generated_values["LANGFUSE_INIT_USER_EMAIL"]="$USER_EMAIL" generated_values["N8N_WORKER_COUNT"]="$N8N_WORKER_COUNT" generated_values["WEAVIATE_USERNAME"]="$USER_EMAIL" # Set Weaviate username for Caddy generated_values["COMFYUI_USERNAME"]="$USER_EMAIL" # Set ComfyUI username for Caddy +generated_values["RAGAPP_USERNAME"]="$USER_EMAIL" # Set RAGApp username for Caddy if [[ -n "$OPENAI_API_KEY" ]]; then generated_values["OPENAI_API_KEY"]="$OPENAI_API_KEY" @@ -438,6 +440,7 @@ found_vars["N8N_WORKER_COUNT"]=0 found_vars["WEAVIATE_USERNAME"]=0 found_vars["NEO4J_AUTH_USERNAME"]=0 found_vars["COMFYUI_USERNAME"]=0 +found_vars["RAGAPP_USERNAME"]=0 # Read template, substitute domain, generate initial values while IFS= read -r line || [[ -n "$line" ]]; do @@ -484,7 +487,7 @@ while IFS= read -r line || [[ -n "$line" ]]; do # This 'else' block is for lines from template not covered by existing values or VARS_TO_GENERATE. # Check if it is one of the user input vars - these are handled by found_vars later if not in template. is_user_input_var=0 # Reset for each line - user_input_vars=("FLOWISE_USERNAME" "DASHBOARD_USERNAME" "LETSENCRYPT_EMAIL" "RUN_N8N_IMPORT" "PROMETHEUS_USERNAME" "SEARXNG_USERNAME" "OPENAI_API_KEY" "LANGFUSE_INIT_USER_EMAIL" "N8N_WORKER_COUNT" "WEAVIATE_USERNAME" "NEO4J_AUTH_USERNAME" "COMFYUI_USERNAME") + user_input_vars=("FLOWISE_USERNAME" "DASHBOARD_USERNAME" "LETSENCRYPT_EMAIL" "RUN_N8N_IMPORT" "PROMETHEUS_USERNAME" "SEARXNG_USERNAME" "OPENAI_API_KEY" "LANGFUSE_INIT_USER_EMAIL" "N8N_WORKER_COUNT" "WEAVIATE_USERNAME" "NEO4J_AUTH_USERNAME" "COMFYUI_USERNAME" "RAGAPP_USERNAME") for uivar in "${user_input_vars[@]}"; do if [[ "$varName" == "$uivar" ]]; then is_user_input_var=1 @@ -689,6 +692,18 @@ if [[ -z "$FINAL_COMFYUI_HASH" && -n "$COMFYUI_PLAIN_PASS" ]]; then fi _update_or_add_env_var "COMFYUI_PASSWORD_HASH" "$FINAL_COMFYUI_HASH" +# --- RAGAPP --- +RAGAPP_PLAIN_PASS="${generated_values["RAGAPP_PASSWORD"]}" +FINAL_RAGAPP_HASH="${generated_values[RAGAPP_PASSWORD_HASH]}" +if [[ -z "$FINAL_RAGAPP_HASH" && -n "$RAGAPP_PLAIN_PASS" ]]; then + NEW_HASH=$(_generate_and_get_hash "$RAGAPP_PLAIN_PASS") + if [[ -n "$NEW_HASH" ]]; then + FINAL_RAGAPP_HASH="$NEW_HASH" + generated_values["RAGAPP_PASSWORD_HASH"]="$NEW_HASH" + fi +fi +_update_or_add_env_var "RAGAPP_PASSWORD_HASH" "$FINAL_RAGAPP_HASH" + if [ $? -eq 0 ]; then # This $? reflects the status of the last mv command from the last _update_or_add_env_var call. # For now, assuming if we reached here and mv was fine, primary operations were okay. diff --git a/scripts/04_wizard.sh b/scripts/04_wizard.sh index f899421..55c91e2 100755 --- a/scripts/04_wizard.sh +++ b/scripts/04_wizard.sh @@ -55,7 +55,7 @@ base_services_data=( "flowise" "Flowise (AI Agent Builder)" "monitoring" "Monitoring Suite (Prometheus, Grafana, cAdvisor, Node-Exporter)" "portainer" "Portainer (Docker management UI)" - "cloudflare-tunnel" "Cloudflare Tunnel (Zero-Trust Secure Access)" + "cloudflare-tunnel" "Cloudflare Tunnel (Zero-Trust Secure Access)" "postiz" "Postiz (Social publishing platform)" "langfuse" "Langfuse Suite (AI Observability - includes Clickhouse, Minio)" "qdrant" "Qdrant (Vector Database)" @@ -65,8 +65,10 @@ base_services_data=( "letta" "Letta (Agent Server & SDK)" "gotenberg" "Gotenberg (Document Conversion API)" "crawl4ai" "Crawl4ai (Web Crawler for AI)" + "ragapp" "RAGApp (Open-source RAG UI + API)" "open-webui" "Open WebUI (ChatGPT-like Interface)" "searxng" "SearXNG (Private Metasearch Engine)" + "python-runner" "Python Runner (Run your custom Python code from ./python-runner)" "ollama" "Ollama (Local LLM Runner - select hardware in next step)" "comfyui" "ComfyUI (Node-based Stable Diffusion UI)" ) @@ -103,7 +105,7 @@ done # Use whiptail to display the checklist CHOICES=$(whiptail --title "Service Selection Wizard" --checklist \ - "Choose the services you want to deploy.\nUse ARROW KEYS to navigate, SPACEBAR to select/deselect, ENTER to confirm." 32 90 17 \ + "Choose the services you want to deploy.\nUse ARROW KEYS to navigate, SPACEBAR to select/deselect, ENTER to confirm." 32 90 20 \ "${services[@]}" \ 3>&1 1>&2 2>&3) diff --git a/scripts/06_final_report.sh b/scripts/06_final_report.sh index f3a597c..0197eba 100755 --- a/scripts/06_final_report.sh +++ b/scripts/06_final_report.sh @@ -135,6 +135,26 @@ if is_profile_active "portainer"; then echo "(Note: On first login, Portainer will prompt to set up an admin user.)" fi +if is_profile_active "postiz"; then + echo + echo "================================= Postiz ==============================" + echo + echo "Host: ${POSTIZ_HOSTNAME:-}" + echo "Internal Access (e.g., from n8n): http://postiz:5000" +fi + +if is_profile_active "ragapp"; then + echo + echo "================================= RAGApp ==============================" + echo + echo "Host: ${RAGAPP_HOSTNAME:-}" + echo "Internal Access (e.g., from n8n): http://ragapp:8000" + echo "User: ${RAGAPP_USERNAME:-}" + echo "Password: ${RAGAPP_PASSWORD:-}" + echo "Admin: https://${RAGAPP_HOSTNAME:-}/admin" + echo "API Docs: https://${RAGAPP_HOSTNAME:-}/docs" +fi + if is_profile_active "comfyui"; then echo echo "================================= ComfyUI =============================" @@ -175,6 +195,17 @@ if is_profile_active "gotenberg"; then echo " Office to PDF: POST /forms/libreoffice/convert" fi +if is_profile_active "python-runner"; then + echo + echo "================================= Python Runner ========================" + echo + echo "Internal Container DNS: python-runner" + echo "Mounted Code Directory: ./python-runner (host) -> /app (container)" + echo "Entry File: /app/main.py" + echo "(Note: Internal-only service with no exposed ports; view output via logs)" + echo "Logs: docker compose -p localai logs -f python-runner" +fi + if is_profile_active "n8n" || is_profile_active "langfuse"; then echo echo "================================= Redis (Valkey) ======================"