feat: add gost proxy service for outbound ai traffic routing

- add gost http/https proxy service with authentication
- create x-proxy-env anchor for shared proxy configuration
- apply proxy settings to ai services (n8n, flowise, langfuse, etc.)
- add gost to wizard, welcome page, and final report
- generate gost credentials and proxy url in secrets script
- use wget healthcheck compatible with alpine-based gost image
This commit is contained in:
Yury Kossakovsky
2025-12-20 15:04:12 -07:00
parent 531d34a328
commit ed046b3c68
8 changed files with 310 additions and 221 deletions

View File

@@ -398,6 +398,21 @@ OPENAI_API_KEY=
# ============================================
CLOUDFLARE_TUNNEL_TOKEN=
# ============================================
# Gost Proxy Configuration (Optional)
# ============================================
# Internal HTTP proxy for AI services outbound traffic
# Credentials (auto-generated)
GOST_USERNAME=
GOST_PASSWORD=
# Proxy URL (auto-generated: http://user:pass@gost:8080)
GOST_PROXY_URL=
# Internal services bypass list (prevents internal Docker traffic from going through proxy)
GOST_NO_PROXY=localhost,127.0.0.1,postgres,redis,caddy,ollama,neo4j,qdrant,weaviate,clickhouse,minio,searxng,crawl4ai,gotenberg,langfuse-web,langfuse-worker,flowise,n8n,n8n-import,n8n-worker-1,n8n-worker-2,n8n-worker-3,n8n-worker-4,n8n-runner-1,n8n-runner-2,n8n-runner-3,n8n-runner-4,letta,lightrag,docling,postiz,ragflow,ragflow-mysql,ragflow-minio,ragflow-redis,ragflow-elasticsearch,ragapp,open-webui,comfyui,waha,libretranslate,paddleocr,gost
############
# Functions - Configuration for Functions
############

View File

@@ -36,6 +36,8 @@ The installer also makes the following powerful open-source tools **available fo
✅ [**Flowise**](https://flowiseai.com/) - A no-code/low-code AI agent builder that complements n8n perfectly, allowing you to create sophisticated AI applications with ease.
✅ [**Gost**](https://github.com/go-gost/gost) - Versatile HTTP/HTTPS proxy for routing AI service outbound traffic through a central proxy point
✅ [**Gotenberg**](https://gotenberg.dev/) - A stateless API for converting HTML, Markdown, Word, Excel, and other documents to PDF, PNG, or JPEG. Available only within the Docker network for internal use by n8n workflows and other services.
✅ [**Grafana**](https://grafana.com/) - An open-source platform for visualizing monitoring data, helping you understand system performance at a glance.

View File

@@ -34,12 +34,22 @@ volumes:
valkey-data:
weaviate_data:
# Shared proxy configuration for services that need outbound proxy support
x-proxy-env: &proxy-env
HTTP_PROXY: ${GOST_PROXY_URL:-}
HTTPS_PROXY: ${GOST_PROXY_URL:-}
http_proxy: ${GOST_PROXY_URL:-}
https_proxy: ${GOST_PROXY_URL:-}
NO_PROXY: ${GOST_NO_PROXY:-}
no_proxy: ${GOST_NO_PROXY:-}
x-n8n: &service-n8n
build:
context: ./n8n
dockerfile: Dockerfile.n8n
pull: true
environment: &service-n8n-env
<<: *proxy-env
DB_POSTGRESDB_DATABASE: postgres
DB_POSTGRESDB_HOST: postgres
DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
@@ -91,10 +101,10 @@ x-ollama: &service-ollama
container_name: ollama
restart: unless-stopped
environment:
- OLLAMA_CONTEXT_LENGTH=8192
- OLLAMA_FLASH_ATTENTION=1
- OLLAMA_KV_CACHE_TYPE=q8_0
- OLLAMA_MAX_LOADED_MODELS=2
OLLAMA_CONTEXT_LENGTH: 8192
OLLAMA_FLASH_ATTENTION: 1
OLLAMA_KV_CACHE_TYPE: q8_0
OLLAMA_MAX_LOADED_MODELS: 2
volumes:
- ollama_storage:/root/.ollama
@@ -128,9 +138,10 @@ services:
container_name: flowise
profiles: ["flowise"]
environment:
- PORT=3001
- FLOWISE_USERNAME=${FLOWISE_USERNAME}
- FLOWISE_PASSWORD=${FLOWISE_PASSWORD}
<<: *proxy-env
PORT: 3001
FLOWISE_USERNAME: ${FLOWISE_USERNAME}
FLOWISE_PASSWORD: ${FLOWISE_PASSWORD}
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
@@ -143,7 +154,8 @@ services:
container_name: open-webui
profiles: ["open-webui"]
environment:
- OLLAMA_BASE_URL=http://ollama:11434
<<: *proxy-env
OLLAMA_BASE_URL: http://ollama:11434
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
@@ -225,7 +237,7 @@ services:
volumes:
- qdrant_storage:/qdrant/storage
environment:
- QDRANT__SERVICE__API_KEY=${QDRANT_API_KEY}
QDRANT__SERVICE__API_KEY: ${QDRANT_API_KEY}
expose:
- "6333"
@@ -270,48 +282,48 @@ services:
- caddy-data:/data:rw
- caddy-config:/config:rw
environment:
- COMFYUI_HOSTNAME=${COMFYUI_HOSTNAME}
- COMFYUI_PASSWORD_HASH=${COMFYUI_PASSWORD_HASH}
- COMFYUI_USERNAME=${COMFYUI_USERNAME}
- DIFY_HOSTNAME=${DIFY_HOSTNAME}
- DOCLING_HOSTNAME=${DOCLING_HOSTNAME}
- DOCLING_PASSWORD_HASH=${DOCLING_PASSWORD_HASH}
- DOCLING_USERNAME=${DOCLING_USERNAME}
- FLOWISE_HOSTNAME=${FLOWISE_HOSTNAME}
- GRAFANA_HOSTNAME=${GRAFANA_HOSTNAME}
- LANGFUSE_HOSTNAME=${LANGFUSE_HOSTNAME}
- LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL:-internal}
- LETTA_HOSTNAME=${LETTA_HOSTNAME}
- LIGHTRAG_HOSTNAME=${LIGHTRAG_HOSTNAME}
- LT_HOSTNAME=${LT_HOSTNAME}
- LT_USERNAME=${LT_USERNAME}
- LT_PASSWORD_HASH=${LT_PASSWORD_HASH}
- N8N_HOSTNAME=${N8N_HOSTNAME}
- NEO4J_HOSTNAME=${NEO4J_HOSTNAME}
- WAHA_HOSTNAME=${WAHA_HOSTNAME}
- PADDLEOCR_HOSTNAME=${PADDLEOCR_HOSTNAME}
- PADDLEOCR_PASSWORD_HASH=${PADDLEOCR_PASSWORD_HASH}
- PADDLEOCR_USERNAME=${PADDLEOCR_USERNAME}
- PORTAINER_HOSTNAME=${PORTAINER_HOSTNAME}
- POSTIZ_HOSTNAME=${POSTIZ_HOSTNAME}
- POSTGRESUS_HOSTNAME=${POSTGRESUS_HOSTNAME}
- PROMETHEUS_HOSTNAME=${PROMETHEUS_HOSTNAME}
- PROMETHEUS_PASSWORD_HASH=${PROMETHEUS_PASSWORD_HASH}
- PROMETHEUS_USERNAME=${PROMETHEUS_USERNAME}
- QDRANT_HOSTNAME=${QDRANT_HOSTNAME}
- RAGAPP_HOSTNAME=${RAGAPP_HOSTNAME}
- RAGFLOW_HOSTNAME=${RAGFLOW_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}
- WELCOME_HOSTNAME=${WELCOME_HOSTNAME}
- WELCOME_PASSWORD_HASH=${WELCOME_PASSWORD_HASH}
- WELCOME_USERNAME=${WELCOME_USERNAME}
COMFYUI_HOSTNAME: ${COMFYUI_HOSTNAME}
COMFYUI_PASSWORD_HASH: ${COMFYUI_PASSWORD_HASH}
COMFYUI_USERNAME: ${COMFYUI_USERNAME}
DIFY_HOSTNAME: ${DIFY_HOSTNAME}
DOCLING_HOSTNAME: ${DOCLING_HOSTNAME}
DOCLING_PASSWORD_HASH: ${DOCLING_PASSWORD_HASH}
DOCLING_USERNAME: ${DOCLING_USERNAME}
FLOWISE_HOSTNAME: ${FLOWISE_HOSTNAME}
GRAFANA_HOSTNAME: ${GRAFANA_HOSTNAME}
LANGFUSE_HOSTNAME: ${LANGFUSE_HOSTNAME}
LETSENCRYPT_EMAIL: ${LETSENCRYPT_EMAIL:-internal}
LETTA_HOSTNAME: ${LETTA_HOSTNAME}
LIGHTRAG_HOSTNAME: ${LIGHTRAG_HOSTNAME}
LT_HOSTNAME: ${LT_HOSTNAME}
LT_USERNAME: ${LT_USERNAME}
LT_PASSWORD_HASH: ${LT_PASSWORD_HASH}
N8N_HOSTNAME: ${N8N_HOSTNAME}
NEO4J_HOSTNAME: ${NEO4J_HOSTNAME}
WAHA_HOSTNAME: ${WAHA_HOSTNAME}
PADDLEOCR_HOSTNAME: ${PADDLEOCR_HOSTNAME}
PADDLEOCR_PASSWORD_HASH: ${PADDLEOCR_PASSWORD_HASH}
PADDLEOCR_USERNAME: ${PADDLEOCR_USERNAME}
PORTAINER_HOSTNAME: ${PORTAINER_HOSTNAME}
POSTIZ_HOSTNAME: ${POSTIZ_HOSTNAME}
POSTGRESUS_HOSTNAME: ${POSTGRESUS_HOSTNAME}
PROMETHEUS_HOSTNAME: ${PROMETHEUS_HOSTNAME}
PROMETHEUS_PASSWORD_HASH: ${PROMETHEUS_PASSWORD_HASH}
PROMETHEUS_USERNAME: ${PROMETHEUS_USERNAME}
QDRANT_HOSTNAME: ${QDRANT_HOSTNAME}
RAGAPP_HOSTNAME: ${RAGAPP_HOSTNAME}
RAGFLOW_HOSTNAME: ${RAGFLOW_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}
WELCOME_HOSTNAME: ${WELCOME_HOSTNAME}
WELCOME_PASSWORD_HASH: ${WELCOME_PASSWORD_HASH}
WELCOME_USERNAME: ${WELCOME_USERNAME}
cap_drop:
- ALL
cap_add:
@@ -329,7 +341,27 @@ services:
restart: unless-stopped
command: tunnel --no-autoupdate run
environment:
- TUNNEL_TOKEN=${CLOUDFLARE_TUNNEL_TOKEN}
TUNNEL_TOKEN: ${CLOUDFLARE_TUNNEL_TOKEN}
logging:
driver: "json-file"
options:
max-size: "1m"
max-file: "1"
gost:
image: gogost/gost:latest
container_name: gost
profiles: ["gost"]
restart: unless-stopped
command:
- "-L"
- "http://${GOST_USERNAME}:${GOST_PASSWORD}@:8080"
healthcheck:
test: ["CMD-SHELL", "wget -q --spider http://localhost:8080 || exit 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 5s
logging:
driver: "json-file"
options:
@@ -351,6 +383,7 @@ services:
clickhouse:
condition: service_healthy
environment: &langfuse-worker-env
<<: *proxy-env
DATABASE_URL: postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/langfuse
SALT: ${LANGFUSE_SALT}
ENCRYPTION_KEY: ${ENCRYPTION_KEY}
@@ -504,9 +537,9 @@ services:
volumes:
- ./searxng:/etc/searxng:rw
environment:
- SEARXNG_BASE_URL=https://${SEARXNG_HOSTNAME:-localhost}/
- UWSGI_WORKERS=${SEARXNG_UWSGI_WORKERS:-4}
- UWSGI_THREADS=${SEARXNG_UWSGI_THREADS:-4}
SEARXNG_BASE_URL: https://${SEARXNG_HOSTNAME:-localhost}/
UWSGI_WORKERS: ${SEARXNG_UWSGI_WORKERS:-4}
UWSGI_THREADS: ${SEARXNG_UWSGI_THREADS:-4}
# cap_drop: - ALL # Temporarily commented out for first run
cap_add:
- CHOWN
@@ -606,8 +639,8 @@ services:
profiles: ["monitoring"]
restart: unless-stopped
environment:
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD:-admin}
- GF_PROVISIONING_PATH=/etc/grafana/provisioning
GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_ADMIN_PASSWORD:-admin}
GF_PROVISIONING_PATH: /etc/grafana/provisioning
volumes:
- grafana:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning
@@ -625,6 +658,8 @@ services:
shm_size: 1g # Recommended for browser operations
env_file:
- .env
environment:
<<: *proxy-env
deploy:
resources:
limits:
@@ -637,7 +672,7 @@ services:
profiles: ["gotenberg"]
restart: unless-stopped
environment:
- DISABLE_GOOGLE_CHROME=false
DISABLE_GOOGLE_CHROME: false
healthcheck:
test: ["CMD", "wget", "-qO", "/dev/null", "http://localhost:3000/health"]
interval: 30s
@@ -652,6 +687,7 @@ services:
volumes:
- letta_data:/var/lib/postgresql/data
environment:
<<: *proxy-env
OPENAI_API_KEY: ${OPENAI_API_KEY:-}
ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-}
OLLAMA_BASE_URL: ${OLLAMA_BASE_URL:-}
@@ -695,6 +731,8 @@ services:
container_name: ragapp
profiles: ["ragapp"]
restart: unless-stopped
environment:
<<: *proxy-env
portainer:
image: portainer/portainer-ce:latest
@@ -711,6 +749,7 @@ services:
profiles: ["postiz"]
restart: always
environment:
<<: *proxy-env
BACKEND_INTERNAL_URL: http://postiz:3000
DATABASE_URL: "postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/postgres?schema=postiz"
DISABLE_REGISTRATION: ${POSTIZ_DISABLE_REGISTRATION}
@@ -778,7 +817,7 @@ services:
profiles: ["comfyui"]
restart: unless-stopped
environment:
- CLI_ARGS=--listen 0.0.0.0 --cpu
CLI_ARGS: --listen 0.0.0.0 --cpu
volumes:
- comfyui_data:/home/runner
healthcheck:
@@ -793,22 +832,22 @@ services:
profiles: ["libretranslate"]
restart: unless-stopped
environment:
- LT_API_KEYS=${LT_API_KEYS:-false}
- LT_BATCH_LIMIT=${LT_BATCH_LIMIT:-}
- LT_CHAR_LIMIT=${LT_CHAR_LIMIT:-10000}
- LT_DEBUG=${LT_DEBUG:-false}
- LT_FRONTEND_LANGUAGE_SOURCE=${LT_FRONTEND_LANGUAGE_SOURCE:-auto}
- LT_FRONTEND_LANGUAGE_TARGET=${LT_FRONTEND_LANGUAGE_TARGET:-en}
- LT_FRONTEND_TIMEOUT=${LT_FRONTEND_TIMEOUT:-2000}
- LT_HOST=${LT_HOST:-0.0.0.0}
- LT_LOAD_ONLY=${LT_LOAD_ONLY:-}
- LT_METRICS=${LT_METRICS:-false}
- LT_PORT=${LT_PORT:-5000}
- LT_REQ_LIMIT=${LT_REQ_LIMIT:-}
- LT_SSL=${LT_SSL:-false}
- LT_SUGGESTIONS=${LT_SUGGESTIONS:-false}
- LT_THREADS=${LT_THREADS:-4}
- LT_UPDATE_MODELS=${LT_UPDATE_MODELS:-false}
LT_API_KEYS: ${LT_API_KEYS:-false}
LT_BATCH_LIMIT: ${LT_BATCH_LIMIT:-}
LT_CHAR_LIMIT: ${LT_CHAR_LIMIT:-10000}
LT_DEBUG: ${LT_DEBUG:-false}
LT_FRONTEND_LANGUAGE_SOURCE: ${LT_FRONTEND_LANGUAGE_SOURCE:-auto}
LT_FRONTEND_LANGUAGE_TARGET: ${LT_FRONTEND_LANGUAGE_TARGET:-en}
LT_FRONTEND_TIMEOUT: ${LT_FRONTEND_TIMEOUT:-2000}
LT_HOST: ${LT_HOST:-0.0.0.0}
LT_LOAD_ONLY: ${LT_LOAD_ONLY:-}
LT_METRICS: ${LT_METRICS:-false}
LT_PORT: ${LT_PORT:-5000}
LT_REQ_LIMIT: ${LT_REQ_LIMIT:-}
LT_SSL: ${LT_SSL:-false}
LT_SUGGESTIONS: ${LT_SUGGESTIONS:-false}
LT_THREADS: ${LT_THREADS:-4}
LT_UPDATE_MODELS: ${LT_UPDATE_MODELS:-false}
volumes:
- libretranslate_api_keys:/app/db
- libretranslate_models:/home/libretranslate/.local:rw
@@ -854,17 +893,17 @@ services:
profiles: ["waha"]
restart: unless-stopped
environment:
- WAHA_ENGINE=${WAHA_ENGINE}
- WAHA_API_KEY=${WAHA_API_KEY}
- WAHA_DASHBOARD_USERNAME=${WAHA_DASHBOARD_USERNAME}
- WAHA_DASHBOARD_PASSWORD=${WAHA_DASHBOARD_PASSWORD}
- WHATSAPP_SWAGGER_USERNAME=${WHATSAPP_SWAGGER_USERNAME}
- WHATSAPP_SWAGGER_PASSWORD=${WHATSAPP_SWAGGER_PASSWORD}
- WAHA_DASHBOARD_ENABLED=${WAHA_DASHBOARD_ENABLED:-true}
- WHATSAPP_SWAGGER_ENABLED=${WHATSAPP_SWAGGER_ENABLED:-true}
- WAHA_BASE_URL=http://waha:3000
- REDIS_URL=redis://redis:6379
- WHATSAPP_SESSIONS_POSTGRESQL_URL=postgres://postgres:${POSTGRES_PASSWORD}@postgres:5432/postgres?sslmode=disable
WAHA_ENGINE: ${WAHA_ENGINE}
WAHA_API_KEY: ${WAHA_API_KEY}
WAHA_DASHBOARD_USERNAME: ${WAHA_DASHBOARD_USERNAME}
WAHA_DASHBOARD_PASSWORD: ${WAHA_DASHBOARD_PASSWORD}
WHATSAPP_SWAGGER_USERNAME: ${WHATSAPP_SWAGGER_USERNAME}
WHATSAPP_SWAGGER_PASSWORD: ${WHATSAPP_SWAGGER_PASSWORD}
WAHA_DASHBOARD_ENABLED: ${WAHA_DASHBOARD_ENABLED:-true}
WHATSAPP_SWAGGER_ENABLED: ${WHATSAPP_SWAGGER_ENABLED:-true}
WAHA_BASE_URL: http://waha:3000
REDIS_URL: redis://redis:6379
WHATSAPP_SESSIONS_POSTGRESQL_URL: postgres://postgres:${POSTGRES_PASSWORD}@postgres:5432/postgres?sslmode=disable
depends_on:
redis:
condition: service_healthy
@@ -877,24 +916,25 @@ services:
profiles: ["ragflow"]
restart: unless-stopped
environment:
- SVR_HTTP_PORT=80
- REDIS_HOST=ragflow-redis
- REDIS_PORT=6379
- REDIS_PASSWORD=${RAGFLOW_REDIS_PASSWORD}
- MYSQL_HOST=ragflow-mysql
- MYSQL_PORT=3306
- MYSQL_USER=root
- MYSQL_PASSWORD=${RAGFLOW_MYSQL_ROOT_PASSWORD}
- MYSQL_DATABASE=rag_flow
- DOC_ENGINE=elasticsearch
- ES_HOST=ragflow-elasticsearch
- ES_PORT=9200
- ELASTIC_PASSWORD=${RAGFLOW_ELASTICSEARCH_PASSWORD}
- MINIO_HOST=ragflow-minio
- MINIO_PORT=9000
- MINIO_USER=minio
- MINIO_PASSWORD=${RAGFLOW_MINIO_ROOT_PASSWORD}
- MINIO_BUCKET=ragflow
<<: *proxy-env
SVR_HTTP_PORT: 80
REDIS_HOST: ragflow-redis
REDIS_PORT: 6379
REDIS_PASSWORD: ${RAGFLOW_REDIS_PASSWORD}
MYSQL_HOST: ragflow-mysql
MYSQL_PORT: 3306
MYSQL_USER: root
MYSQL_PASSWORD: ${RAGFLOW_MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: rag_flow
DOC_ENGINE: elasticsearch
ES_HOST: ragflow-elasticsearch
ES_PORT: 9200
ELASTIC_PASSWORD: ${RAGFLOW_ELASTICSEARCH_PASSWORD}
MINIO_HOST: ragflow-minio
MINIO_PORT: 9000
MINIO_USER: minio
MINIO_PASSWORD: ${RAGFLOW_MINIO_ROOT_PASSWORD}
MINIO_BUCKET: ragflow
volumes:
- ragflow_data:/ragflow
- ./ragflow/nginx.conf:/etc/nginx/sites-available/default:ro
@@ -914,8 +954,8 @@ services:
profiles: ["ragflow"]
restart: unless-stopped
environment:
- MYSQL_ROOT_PASSWORD=${RAGFLOW_MYSQL_ROOT_PASSWORD}
- MYSQL_DATABASE=rag_flow
MYSQL_ROOT_PASSWORD: ${RAGFLOW_MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: rag_flow
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -h localhost || exit 1"]
interval: 10s
@@ -933,8 +973,8 @@ services:
entrypoint: sh
command: -c 'mkdir -p /data/ragflow && minio server --address ":9000" --console-address ":9001" /data'
environment:
- MINIO_ROOT_USER=minio
- MINIO_ROOT_PASSWORD=${RAGFLOW_MINIO_ROOT_PASSWORD}
MINIO_ROOT_USER: minio
MINIO_ROOT_PASSWORD: ${RAGFLOW_MINIO_ROOT_PASSWORD}
healthcheck:
test: ["CMD", "mc", "ready", "local"]
interval: 5s
@@ -975,16 +1015,16 @@ services:
profiles: ["ragflow"]
restart: unless-stopped
environment:
- node.name=ragflow-es01
- discovery.type=single-node
- ELASTIC_PASSWORD=${RAGFLOW_ELASTICSEARCH_PASSWORD}
- bootstrap.memory_lock=false
- xpack.security.enabled=true
- xpack.security.http.ssl.enabled=false
- xpack.security.transport.ssl.enabled=false
- cluster.routing.allocation.disk.watermark.low=5gb
- cluster.routing.allocation.disk.watermark.high=3gb
- cluster.routing.allocation.disk.watermark.flood_stage=2gb
node.name: ragflow-es01
discovery.type: single-node
ELASTIC_PASSWORD: ${RAGFLOW_ELASTICSEARCH_PASSWORD}
bootstrap.memory_lock: false
xpack.security.enabled: true
xpack.security.http.ssl.enabled: false
xpack.security.transport.ssl.enabled: false
cluster.routing.allocation.disk.watermark.low: 5gb
cluster.routing.allocation.disk.watermark.high: 3gb
cluster.routing.allocation.disk.watermark.flood_stage: 2gb
ulimits:
memlock:
soft: -1
@@ -1015,76 +1055,67 @@ services:
profiles: ["lightrag"]
restart: unless-stopped
environment:
<<: *proxy-env
# Server Configuration
- HOST=0.0.0.0
- PORT=9621
- WEBUI_TITLE=LightRAG Knowledge Graph
- WEBUI_DESCRIPTION=Graph-based RAG with Knowledge Extraction
HOST: 0.0.0.0
PORT: 9621
WEBUI_TITLE: LightRAG Knowledge Graph
WEBUI_DESCRIPTION: Graph-based RAG with Knowledge Extraction
# Authentication (Built-in)
- AUTH_ACCOUNTS=${LIGHTRAG_USERNAME}:${LIGHTRAG_PASSWORD}
- LIGHTRAG_API_KEY=${LIGHTRAG_API_KEY}
AUTH_ACCOUNTS: ${LIGHTRAG_USERNAME}:${LIGHTRAG_PASSWORD}
LIGHTRAG_API_KEY: ${LIGHTRAG_API_KEY}
# LLM Configuration (Ollama)
- LLM_BINDING=ollama
- LLM_MODEL=qwen2.5:32b
- LLM_BINDING_HOST=http://ollama:11434
- OLLAMA_LLM_NUM_CTX=32768
- MAX_ASYNC=4
LLM_BINDING: ollama
LLM_MODEL: qwen2.5:32b
LLM_BINDING_HOST: http://ollama:11434
OLLAMA_LLM_NUM_CTX: 32768
MAX_ASYNC: 4
# Embedding Configuration (Ollama)
- EMBEDDING_BINDING=ollama
- EMBEDDING_MODEL=bge-m3:latest
- EMBEDDING_DIM=1024
- EMBEDDING_BINDING_HOST=http://ollama:11434
- OLLAMA_EMBEDDING_NUM_CTX=8192
- EMBEDDING_FUNC_MAX_ASYNC=16
- EMBEDDING_BATCH_NUM=32
EMBEDDING_BINDING: ollama
EMBEDDING_MODEL: bge-m3:latest
EMBEDDING_DIM: 1024
EMBEDDING_BINDING_HOST: http://ollama:11434
OLLAMA_EMBEDDING_NUM_CTX: 8192
EMBEDDING_FUNC_MAX_ASYNC: 16
EMBEDDING_BATCH_NUM: 32
# Query Configuration
- ENABLE_LLM_CACHE=true
- TOP_K=60
- CHUNK_TOP_K=20
- COSINE_THRESHOLD=0.2
- MAX_ENTITY_TOKENS=6000
- MAX_RELATION_TOKENS=8000
- MAX_TOTAL_TOKENS=30000
ENABLE_LLM_CACHE: true
TOP_K: 60
CHUNK_TOP_K: 20
COSINE_THRESHOLD: 0.2
MAX_ENTITY_TOKENS: 6000
MAX_RELATION_TOKENS: 8000
MAX_TOTAL_TOKENS: 30000
# Document Processing
- ENABLE_LLM_CACHE_FOR_EXTRACT=true
- SUMMARY_LANGUAGE=English
- CHUNK_SIZE=1200
- CHUNK_OVERLAP_SIZE=100
- SUMMARY_MAX_TOKENS=500
- SUMMARY_CONTEXT_SIZE=10000
ENABLE_LLM_CACHE_FOR_EXTRACT: true
SUMMARY_LANGUAGE: English
CHUNK_SIZE: 1200
CHUNK_OVERLAP_SIZE: 100
SUMMARY_MAX_TOKENS: 500
SUMMARY_CONTEXT_SIZE: 10000
# Storage Configuration (Flexible - uses PostgreSQL/Neo4j if available)
- LIGHTRAG_KV_STORAGE=JsonKVStorage
- LIGHTRAG_DOC_STATUS_STORAGE=JsonDocStatusStorage
- LIGHTRAG_GRAPH_STORAGE=${LIGHTRAG_GRAPH_STORAGE:-NetworkXStorage}
- LIGHTRAG_VECTOR_STORAGE=${LIGHTRAG_VECTOR_STORAGE:-NanoVectorDBStorage}
LIGHTRAG_KV_STORAGE: JsonKVStorage
LIGHTRAG_DOC_STATUS_STORAGE: JsonDocStatusStorage
LIGHTRAG_GRAPH_STORAGE: ${LIGHTRAG_GRAPH_STORAGE:-NetworkXStorage}
LIGHTRAG_VECTOR_STORAGE: ${LIGHTRAG_VECTOR_STORAGE:-NanoVectorDBStorage}
# PostgreSQL Configuration (if using PostgreSQL storage)
- POSTGRES_HOST=postgres
- POSTGRES_PORT=5432
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DATABASE=postgres
- POSTGRES_MAX_CONNECTIONS=12
- POSTGRES_VECTOR_INDEX_TYPE=HNSW
- POSTGRES_HNSW_M=16
- POSTGRES_HNSW_EF=200
POSTGRES_HOST: postgres
POSTGRES_PORT: 5432
POSTGRES_USER: postgres
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DATABASE: postgres
POSTGRES_MAX_CONNECTIONS: 12
POSTGRES_VECTOR_INDEX_TYPE: HNSW
POSTGRES_HNSW_M: 16
POSTGRES_HNSW_EF: 200
# Neo4j Configuration (if using Neo4j storage)
- NEO4J_URI=bolt://neo4j:7687
- NEO4J_USERNAME=${NEO4J_AUTH_USERNAME:-neo4j}
- NEO4J_PASSWORD=${NEO4J_AUTH_PASSWORD}
- NEO4J_DATABASE=neo4j
NEO4J_URI: bolt://neo4j:7687
NEO4J_USERNAME: ${NEO4J_AUTH_USERNAME:-neo4j}
NEO4J_PASSWORD: ${NEO4J_AUTH_PASSWORD}
NEO4J_DATABASE: neo4j
# Directories
- INPUT_DIR=/app/data/inputs
- WORKING_DIR=/app/data/rag_storage
INPUT_DIR: /app/data/inputs
WORKING_DIR: /app/data/rag_storage
volumes:
- lightrag_data:/app/data/rag_storage
- lightrag_inputs:/app/data/inputs
@@ -1109,10 +1140,11 @@ services:
profiles: ["docling"]
restart: unless-stopped
environment:
- DOCLING_SERVE_ENABLE_UI=1
- DOCLING_SERVE_ENABLE_REMOTE_SERVICES=${DOCLING_SERVE_ENABLE_REMOTE_SERVICES:-true}
- DOCLING_SERVE_LOAD_MODELS_AT_BOOT=${DOCLING_SERVE_LOAD_MODELS_AT_BOOT:-false}
- DOCLING_DEVICE=${DOCLING_DEVICE:-cpu}
<<: *proxy-env
DOCLING_SERVE_ENABLE_UI: 1
DOCLING_SERVE_ENABLE_REMOTE_SERVICES: ${DOCLING_SERVE_ENABLE_REMOTE_SERVICES:-true}
DOCLING_SERVE_LOAD_MODELS_AT_BOOT: ${DOCLING_SERVE_LOAD_MODELS_AT_BOOT:-false}
DOCLING_DEVICE: ${DOCLING_DEVICE:-cpu}
volumes:
- docling_cache:/opt/app-root/src/.cache
shm_size: 1g

View File

@@ -39,6 +39,36 @@ require_command "openssl" "Please ensure openssl is installed and available in y
TEMPLATE_FILE="$PROJECT_ROOT/.env.example"
OUTPUT_FILE="$PROJECT_ROOT/.env"
# Variables that get assigned the user's email address
EMAIL_VARS=(
"COMFYUI_USERNAME"
"DASHBOARD_USERNAME"
"DOCLING_USERNAME"
"FLOWISE_USERNAME"
"GOST_USERNAME"
"LANGFUSE_INIT_USER_EMAIL"
"LETSENCRYPT_EMAIL"
"LIGHTRAG_USERNAME"
"LT_USERNAME"
"PADDLEOCR_USERNAME"
"PROMETHEUS_USERNAME"
"RAGAPP_USERNAME"
"SEARXNG_USERNAME"
"WAHA_DASHBOARD_USERNAME"
"WEAVIATE_USERNAME"
"WELCOME_USERNAME"
"WHATSAPP_SWAGGER_USERNAME"
)
# All user input variables (EMAIL_VARS plus non-email vars)
USER_INPUT_VARS=(
"${EMAIL_VARS[@]}"
"N8N_WORKER_COUNT"
"NEO4J_AUTH_USERNAME"
"OPENAI_API_KEY"
"RUN_N8N_IMPORT"
)
# Variables to generate: varName="type:length"
# Types: password (alphanum), secret (base64), hex, base64, alphanum
declare -A VARS_TO_GENERATE=(
@@ -49,6 +79,7 @@ declare -A VARS_TO_GENERATE=(
["DOCLING_PASSWORD"]="password:32"
["ENCRYPTION_KEY"]="hex:64" # Langfuse Encryption Key (32 bytes -> 64 hex chars)
["FLOWISE_PASSWORD"]="password:32"
["GOST_PASSWORD"]="password:32"
["GRAFANA_ADMIN_PASSWORD"]="password:32"
["JWT_SECRET"]="base64:64" # 48 bytes -> 64 chars
["LANGFUSE_INIT_PROJECT_PUBLIC_KEY"]="langfuse_pk:32"
@@ -243,22 +274,10 @@ for key_from_existing in "${!existing_env_vars[@]}"; do
done
# Store user input values (potentially overwriting if user was re-prompted and gave new input)
generated_values["FLOWISE_USERNAME"]="$USER_EMAIL"
generated_values["DASHBOARD_USERNAME"]="$USER_EMAIL"
generated_values["LETSENCRYPT_EMAIL"]="$USER_EMAIL"
generated_values["PROMETHEUS_USERNAME"]="$USER_EMAIL"
generated_values["SEARXNG_USERNAME"]="$USER_EMAIL"
generated_values["LANGFUSE_INIT_USER_EMAIL"]="$USER_EMAIL"
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
generated_values["PADDLEOCR_USERNAME"]="$USER_EMAIL" # Set PaddleOCR username for Caddy
generated_values["LT_USERNAME"]="$USER_EMAIL" # Set LibreTranslate username for Caddy
generated_values["LIGHTRAG_USERNAME"]="$USER_EMAIL" # Set LightRAG username for built-in auth
generated_values["WAHA_DASHBOARD_USERNAME"]="$USER_EMAIL" # WAHA dashboard username default
generated_values["WHATSAPP_SWAGGER_USERNAME"]="$USER_EMAIL" # WAHA swagger username default
generated_values["DOCLING_USERNAME"]="$USER_EMAIL" # Set Docling username for Caddy
generated_values["WELCOME_USERNAME"]="$USER_EMAIL" # Set Welcome page username for Caddy
# Assign user email to all EMAIL_VARS
for var in "${EMAIL_VARS[@]}"; do
generated_values["$var"]="$USER_EMAIL"
done
# Create a temporary file for processing
@@ -267,26 +286,9 @@ TEMP_FILES+=("$TMP_ENV_FILE")
# Track whether our custom variables were found in the template
declare -A found_vars
found_vars["FLOWISE_USERNAME"]=0
found_vars["DASHBOARD_USERNAME"]=0
found_vars["LETSENCRYPT_EMAIL"]=0
found_vars["RUN_N8N_IMPORT"]=0
found_vars["PROMETHEUS_USERNAME"]=0
found_vars["SEARXNG_USERNAME"]=0
found_vars["OPENAI_API_KEY"]=0
found_vars["LANGFUSE_INIT_USER_EMAIL"]=0
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
found_vars["PADDLEOCR_USERNAME"]=0
found_vars["DOCLING_USERNAME"]=0
found_vars["LT_USERNAME"]=0
found_vars["LIGHTRAG_USERNAME"]=0
found_vars["WAHA_DASHBOARD_USERNAME"]=0
found_vars["WELCOME_USERNAME"]=0
found_vars["WHATSAPP_SWAGGER_USERNAME"]=0
for var in "${USER_INPUT_VARS[@]}"; do
found_vars["$var"]=0
done
# Read template, substitute domain, generate initial values
while IFS= read -r line || [[ -n "$line" ]]; do
@@ -333,8 +335,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" "RAGAPP_USERNAME" "PADDLEOCR_USERNAME" "LT_USERNAME" "LIGHTRAG_USERNAME" "WAHA_DASHBOARD_USERNAME" "WELCOME_USERNAME" "WHATSAPP_SWAGGER_USERNAME")
for uivar in "${user_input_vars[@]}"; do
for uivar in "${USER_INPUT_VARS[@]}"; do
if [[ "$varName" == "$uivar" ]]; then
is_user_input_var=1
# Mark as found if it's in template, value taken from generated_values if already set or blank
@@ -415,7 +416,7 @@ if [[ -z "${generated_values[SERVICE_ROLE_KEY]}" ]]; then
fi
# Add any custom variables that weren't found in the template
for var in "FLOWISE_USERNAME" "DASHBOARD_USERNAME" "LETSENCRYPT_EMAIL" "RUN_N8N_IMPORT" "OPENAI_API_KEY" "PROMETHEUS_USERNAME" "SEARXNG_USERNAME" "LANGFUSE_INIT_USER_EMAIL" "N8N_WORKER_COUNT" "WEAVIATE_USERNAME" "NEO4J_AUTH_USERNAME" "COMFYUI_USERNAME" "RAGAPP_USERNAME" "PADDLEOCR_USERNAME" "LT_USERNAME" "LIGHTRAG_USERNAME" "WAHA_DASHBOARD_USERNAME" "WELCOME_USERNAME" "WHATSAPP_SWAGGER_USERNAME" "DOCLING_USERNAME"; do
for var in "${USER_INPUT_VARS[@]}"; do
if [[ ${found_vars["$var"]} -eq 0 && ${generated_values[$var]+_} ]]; then
# Before appending, check if it's already in TMP_ENV_FILE to avoid duplicates
if ! grep -q -E "^${var}=" "$TMP_ENV_FILE"; then
@@ -514,6 +515,17 @@ fi
_update_or_add_env_var "WAHA_API_KEY_PLAIN" "${generated_values[WAHA_API_KEY_PLAIN]}"
_update_or_add_env_var "WAHA_API_KEY" "${generated_values[WAHA_API_KEY]}"
# Generate GOST_PROXY_URL if gost profile is active
if is_profile_active "gost"; then
if [[ -n "${generated_values[GOST_PASSWORD]}" && -n "${generated_values[GOST_USERNAME]}" ]]; then
generated_values["GOST_PROXY_URL"]="http://${generated_values[GOST_USERNAME]}:${generated_values[GOST_PASSWORD]}@gost:8080"
_update_or_add_env_var "GOST_PROXY_URL" "${generated_values[GOST_PROXY_URL]}"
fi
else
# Clear proxy URL if gost is not active
_update_or_add_env_var "GOST_PROXY_URL" ""
fi
# Hash passwords using caddy with bcrypt (consolidated loop)
SERVICES_NEEDING_HASH=("PROMETHEUS" "SEARXNG" "COMFYUI" "PADDLEOCR" "RAGAPP" "LT" "DOCLING" "WELCOME")

View File

@@ -44,6 +44,7 @@ base_services_data=(
"docling" "Docling (Universal Document Converter to Markdown/JSON)"
"dify" "Dify (AI Application Development Platform with LLMOps)"
"flowise" "Flowise (AI Agent Builder)"
"gost" "Gost Proxy (HTTP/HTTPS proxy for AI services outbound traffic)"
"gotenberg" "Gotenberg (Document Conversion API)"
"langfuse" "Langfuse Suite (AI Observability - includes Clickhouse, Minio)"
"letta" "Letta (Agent Server & SDK)"

View File

@@ -91,6 +91,9 @@ fi
if is_profile_active "open-webui"; then
echo -e " ${GREEN}*${NC} ${WHITE}Open WebUI${NC}: Register your account"
fi
if is_profile_active "gost"; then
echo -e " ${GREEN}*${NC} ${WHITE}Gost Proxy${NC}: Active - AI services route outbound traffic through proxy"
fi
echo ""
echo -e " ${WHITE}4.${NC} Run ${CYAN}make doctor${NC} if you experience any issues"

View File

@@ -422,6 +422,22 @@ if is_profile_active "cloudflare-tunnel"; then
}")
fi
# Gost Proxy (internal only)
if is_profile_active "gost"; then
SERVICES_ARRAY+=(" \"gost\": {
\"hostname\": null,
\"credentials\": {
\"username\": \"$(json_escape "$GOST_USERNAME")\",
\"password\": \"$(json_escape "$GOST_PASSWORD")\"
},
\"extra\": {
\"note\": \"Internal HTTP proxy for AI services\",
\"proxy_url\": \"$(json_escape "$GOST_PROXY_URL")\",
\"internal_api\": \"http://gost:8080\"
}
}")
fi
# Join array with commas and newlines
SERVICES_JSON=""
for i in "${!SERVICES_ARRAY[@]}"; do

View File

@@ -343,6 +343,14 @@
category: 'tools',
docsUrl: 'https://docs.crawl4ai.com'
},
'gost': {
name: 'Gost Proxy',
description: 'HTTP/HTTPS Proxy for Outbound Traffic',
icon: 'GP',
color: 'bg-[#4051B5]',
category: 'infra',
docsUrl: 'https://gost.run/en/'
},
'gotenberg': {
name: 'Gotenberg',
description: 'PDF Generator API',