From 6b1191d68c46123474a781c54aa96108952a41f8 Mon Sep 17 00:00:00 2001
From: Artem Baranovskyi <artem.baranovsky1980@gmail.com>
Date: Fri, 28 Feb 2025 23:04:36 +0200
Subject: [PATCH] Partial solution with Nginx user access separation (to be
 finished). Summarising.

---
 .env.Example                |  23 ++-
 docker-compose.yml          |  59 ++++++-
 nginx/nginx.conf            |  39 +++++
 ollama-models/Dockerfile    |   3 +
 ollama-models/load_model.py |   4 +-
 ollama-models/start.sh      |  12 +-
 readme.MD                   | 299 ++++++++++++++++++++++++++++++++++++
 7 files changed, 420 insertions(+), 19 deletions(-)
 create mode 100644 nginx/nginx.conf
 create mode 100644 readme.MD

diff --git a/.env.Example b/.env.Example
index ea1554d..375ab87 100644
--- a/.env.Example
+++ b/.env.Example
@@ -2,8 +2,9 @@ HF_TOKEN=
 LANGCHAIN_API_KEY=
 
 PORT=3000
-FLOWISE_USERNAME=
-FLOWISE_PASSWORD=
+# Flowise student's access creds on http://localhost:3000/
+FLOWISE_USERNAME=student
+FLOWISE_PASSWORD=student
 
 APIKEY_PATH=/root/.flowise
 SECRETKEY_PATH=/root/.flowise
@@ -14,7 +15,21 @@ DATABASE_TYPE=postgres
 DATABASE_PORT=5432
 DATABASE_HOST=localhost
 DATABASE_NAME=flowise
-DATABASE_USER=
-DATABASE_PASSWORD=
+DATABASE_USER=user
+DATABASE_PASSWORD=pass
 PGSSLMODE=require
 
+OLLAMA_CPU=1
+OLLAMA_KEEP_ALIVE=5m
+OLLAMA_NUM_PARALLEL=1
+OLLAMA_HOST=http://localhost:11435
+#MODEL_NAME=llama3.2:1b
+MODEL_NAME=bartowski/DeepSeek-R1-Distill-Qwen-14B-GGUF
+OLLAMA_MODEL=llama3.2:1b
+MODEL=llama3.2:1b
+
+# Nginx
+NGINX_PORT=8080
+# Nginx admin access creds on http://localhost:8080/
+ADMIN_USER=admin
+ADMIN_PASSWORD=admin
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
index 67bdf25..2997740 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -23,14 +23,16 @@ services:
     container_name: flowiseai
     hostname: flowise
     healthcheck:
-      test: wget --no-verbose --tries=1 --spider http://localhost:${PORT}
-      interval: 5s
-      timeout: 5s
-      retries: 5
+      test: ["CMD", "curl", "-f", "http://localhost:3000/api/v1/health"]
+      interval: 60s
+      timeout: 20s
+      retries: 10
+      start_period: 120s
     ports:
       - ${PORT}:${PORT}
     volumes:
       - ./flowiseai:/root/.flowise
+    env_file: .env
     environment:
       DEBUG: 'false'
       PORT: ${PORT}
@@ -46,9 +48,12 @@ services:
       DATABASE_NAME: ${DATABASE_NAME}
       DATABASE_USER: ${DATABASE_USER}
       DATABASE_PASSWORD: ${DATABASE_PASSWORD}
+#      DATABASE_URL: postgresql://${DATABASE_USER}:${DATABASE_PASSWORD}@flowise-db:${DATABASE_PORT}/${DATABASE_NAME}?sslmode=disable
     depends_on:
-      - ollama
-      - flowise-db
+      flowise-db:
+        condition: service_healthy
+      ollama:
+        condition: service_started
     entrypoint: /bin/sh -c "sleep 3; flowise start"
     networks:
       - flowise_network
@@ -62,16 +67,54 @@ services:
     volumes:
       - ollama_data:/root/.ollama
     ports:
-      - "11434:11434"
+      - "11435:11434"
+    env_file: .env
     environment:
       HF_TOKEN: ${HF_TOKEN}
       GIN_MODE: ${GIN_MODE}
+      OLLAMA_CPU: "1"
+      OLLAMA_HOST: ${OLLAMA_HOST}
+      OLLAMA_MODEL: ${OLLAMA_MODEL}
+      MODEL_NAME: ${MODEL_NAME}
+    networks:
+      - flowise_network
+
+  nginx:
+    image: nginx:alpine
+    ports:
+      - "${NGINX_PORT}:80"
+    volumes:
+      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
+      - ./nginx/.htpasswd:/etc/nginx/.htpasswd
+    depends_on:
+      - flowise
+      - htpasswd-generator
+#      flowise:
+#        condition: service_healthy
+#      htpasswd-generator:
+#        condition: service_completed_successfully
+    networks:
+      - flowise_network
+
+  htpasswd-generator:
+    image: httpd:alpine
+    command: sh -c "htpasswd -Bbn $${ADMIN_USER} $${ADMIN_PASSWORD} > /etc/nginx/.htpasswd"
+    env_file: .env
+    environment:
+      ADMIN_USER: ${ADMIN_USER}
+      ADMIN_PASSWORD: ${ADMIN_PASSWORD}
+    volumes:
+      - ./nginx:/etc/nginx
     networks:
       - flowise_network
+    restart: on-failure
 
 volumes:
   flowise-db-data:
   ollama_data:
 
 networks:
-  flowise_network:
\ No newline at end of file
+  flowise_network:
+    driver: bridge
+    name: flowise_network
+    attachable: true
\ No newline at end of file
diff --git a/nginx/nginx.conf b/nginx/nginx.conf
new file mode 100644
index 0000000..afff986
--- /dev/null
+++ b/nginx/nginx.conf
@@ -0,0 +1,39 @@
+events {}
+
+http {
+    server {
+        listen 80;
+
+        # Public chat interface
+        location / {
+            proxy_pass http://flowise:3000;
+            proxy_set_header Host $host;
+            proxy_set_header X-Real-IP $remote_addr;
+        }
+
+        # Admin API (protected)
+        location /api/v1/ {
+            #allow 192.168.1.0/24; # Access only from internal network
+            #deny all;
+
+            # Basic Auth for admins
+            auth_basic "Admin Area";
+            auth_basic_user_file /etc/nginx/.htpasswd;
+
+            # Flowise auth headers
+            proxy_set_header Authorization $http_authorization;
+            proxy_pass_header Authorization;
+
+            proxy_pass http://flowise:3000;
+            proxy_set_header Host $host;
+            proxy_set_header X-Real-IP $remote_addr;
+        }
+
+        # Exclude login endpoint from basic auth
+        location /api/v1/login {
+            proxy_pass http://flowise:3000;
+            proxy_set_header Host $host;
+            proxy_set_header X-Real-IP $remote_addr;
+        }
+    }
+}
\ No newline at end of file
diff --git a/ollama-models/Dockerfile b/ollama-models/Dockerfile
index 229c55f..92622ce 100644
--- a/ollama-models/Dockerfile
+++ b/ollama-models/Dockerfile
@@ -20,6 +20,9 @@ COPY load_model.py /app/load_model.py
 ARG HF_TOKEN
 ENV HF_TOKEN=${HF_TOKEN}
 
+ARG MODEL_NAME
+ENV MODEL_NAME=${MODEL_NAME}
+
 COPY start.sh /app/start.sh
 RUN chmod +x /app/start.sh
 
diff --git a/ollama-models/load_model.py b/ollama-models/load_model.py
index 3436565..0f75719 100644
--- a/ollama-models/load_model.py
+++ b/ollama-models/load_model.py
@@ -1,3 +1,4 @@
+# load_model.py
 import os
 from transformers import AutoModelForCausalLM, AutoTokenizer
 
@@ -6,8 +7,7 @@ hf_token = os.environ.get("HF_TOKEN")
 if hf_token is None:
     raise ValueError("Hugging Face token is not set")
 
-model_name = "meta-llama/Llama-3.2-1B"
-
+model_name = os.environ.get("MODEL_NAME")
 model = AutoModelForCausalLM.from_pretrained(model_name)
 tokenizer = AutoTokenizer.from_pretrained(model_name)
 
diff --git a/ollama-models/start.sh b/ollama-models/start.sh
index 112bcad..0aed2fa 100644
--- a/ollama-models/start.sh
+++ b/ollama-models/start.sh
@@ -1,13 +1,15 @@
 #!/bin/bash
-
-MODEL_NAME="llama3.2:1b"
+# start.sh
 
 if ! ollama list | grep -q "$MODEL_NAME"; then
   echo "Model is not found. Loading..."
-  ollama pull "$MODEL_NAME"
+  HUGGING_FACE_HUB_TOKEN=${HF_TOKEN} ollama pull "$MODEL_NAME"
 else
   echo "Model is already loaded."
 fi
 
-ollama run "$MODEL_NAME" &
-ollama serve
\ No newline at end of file
+ollama serve &
+sleep 10
+ollama run "$MODEL_NAME"
+
+tail -f /dev/null
\ No newline at end of file
diff --git a/readme.MD b/readme.MD
new file mode 100644
index 0000000..679199f
--- /dev/null
+++ b/readme.MD
@@ -0,0 +1,299 @@
+### IMPETUS Educational Chatbot Project
+
+The **IMPETUS** project focuses on developing specialized chatbots for educational purposes, analyzing student-bot interactions to optimize learning experiences. The initiative leverages **LangChain** for chatbot prototyping and **Flowise** for workflow management, with emphasis on secure deployment, database integration, and access control.
+
+---
+
+### Project Overview
+**Primary Goal**: Investigate optimization strategies for educational chatbots and identify effective prompting techniques to maximize student engagement.  
+**Focus Areas**:
+- Interaction analytics via custom database logging
+- Secure deployment architecture for chatbot interfaces
+- Migration from SQLite to PostgreSQL for long-term scalability
+- Access control separation between admin/student interfaces
+
+**Core Technologies**:
+- **LangChain**: Python-based framework for LLM pipeline construction ([Documentation](https://python.langchain.com/docs/tutorials/))
+- **Flowise**: Drag-and-drop UI for chatbot workflows ([GitHub Integration Example](https://github.com/AXRoux/Flowise-LangChain))
+- **Docker**: Containerization for service isolation and deployment reproducibility
+
+**Project Repositories**:  
+[https://transfer.hft-stuttgart.de/gitlab/22baar1mst/flowise-ollama](https://transfer.hft-stuttgart.de/gitlab/22baar1mst/flowise-ollama)
+
+[https://github.com/ArtemBaranovsky/flowise-ollama](https://github.com/ArtemBaranovsky/flowise-ollama) (mirror)
+
+### Key Objectives
+1. **Global Service Installation**:
+    - Dockerize Flowise/LangChain for system-wide availability
+    - Separate student-facing chat interface (port 3000) from admin panel
+
+2. **Database Migration**:
+    - Replace SQLite with PostgreSQL for production-grade reliability
+    - Implement volume persistence for critical data
+
+3. **Security Hardening**:
+    - Isolate administrative endpoints via Nginx routing
+    - Implement Basic Auth with fallback to JWT/OAuth2
+
+4. **LLM Infrastructure**:
+    - Integrate Ollama for local model management
+    - Configure RAG (Retrieval-Augmented Generation) workflows
+
+---
+
+### Implementation Highlights
+
+#### 1. Dockerized Architecture
+```yaml  
+# docker-compose.yml (simplified)  
+services:  
+  flowise:  
+    image: flowiseai/flowise:latest  
+    ports: ["3000:3000"]  
+    depends_on: [postgres, ollama]  
+
+  postgres:  
+    image: postgres:16-alpine  
+    volumes: ["./pgdata:/var/lib/postgresql/data"]  
+
+  ollama:  
+    build: ./ollama-models  
+    ports: ["11435:11434"]  
+
+  nginx:  
+    image: nginx:alpine  
+    ports: ["8080:80"]  
+    configs: ["./nginx/:/etc/nginx/"]  
+```  
+
+#### 2. Access Control Implementation
+```nginx  
+# nginx.conf (security routing)  
+location /admin/ {  
+  auth_basic "Restricted Area";  
+  auth_basic_user_file /etc/nginx/.htpasswd;  
+  proxy_pass http://flowise:3000/api/v1/;  
+}  
+
+location /chat/ {  
+  proxy_pass http://flowise:3000/;  
+}  
+```  
+
+#### 3. Ollama Model Integration
+```Dockerfile  
+# Custom Ollama Dockerfile  
+FROM ollama/ollama  
+RUN ollama pull ${MODEL_NAME}  
+CMD ["ollama", "serve"]  
+```  
+
+---
+
+### Challenges & Solutions
+
+| Challenge | Resolution |  
+|-----------|------------|  
+| **Flowise Admin/Chat Interface Collision** | Implemented Nginx path-based routing with Basic Auth |  
+| **SQLite Scalability Limitations** | Migrated to PostgreSQL with automated schema migration |  
+| **Model Loading Failures** | Created pre-loading script for Ollama containers |  
+| **Student Access Exploits** | Added IP filtering + rate limiting in Nginx |  
+
+Stable implemented version of this simple solution is at https://transfer.hft-stuttgart.de/gitlab/22baar1mst/flowise-ollama/-/commit/5c4d44705f550546423afcd06bc7e69a54e4276a
+
+
+**Unresolved Issues**:
+- Basic Auth bypass vulnerabilities in shared port configuration
+- LangChain migration incomplete due to time constraints
+
+---
+
+### Deployment Workflow
+
+1. **Infrastructure Setup**:
+```bash  
+ssh impetus@193.196.53.83 -i <key.pem>  
+docker-compose up -d --build  
+```  
+
+2. **Environment Configuration**:
+```.env  
+DATABASE_URL=postgresql://user:pass@postgres:5432/db  
+OLLAMA_MODEL=llama2-uncensored  
+NGINX_PORT=8080  
+```  
+
+3. **Security Hardening**:
+```bash  
+# Generate admin credentials  
+htpasswd -c ./nginx/.htpasswd admin  
+```  
+
+---
+
+### Future Development Plan
+
+1. **LangChain Migration**:
+    - Port Flowise workflows to LangChain agents
+    - Implement dual interface system:
+        - `/chat` – student-facing endpoint
+        - `/admin` – JWT-protected management UI
+
+2. **Enhanced Security**:
+    - Implement OAuth2 via Keycloak/Linkding
+    - Add audit logging for all admin actions
+
+3. **CI/CD Pipeline**:
+    - Automated Docker builds on GitLab
+    - Canary deployment strategy
+
+4. **Analytics Integration**:
+    - ClickHouse for interaction telemetry
+    - Grafana dashboard for usage metrics
+
+---
+
+### Conclusion
+The IMPETUS project demonstrates a viable architecture for educational chatbots using Dockerized LLM components. While Flowise provided rapid prototyping capabilities, future work will focus on transitioning to LangChain for greater flexibility. The current implementation achieves:
+- Isolated PostgreSQL database with persistent storage
+- Basic access control through Nginx
+- Local LLM management via Ollama
+
+**Next Steps**: Address security vulnerabilities in access control and complete LangChain migration using [Flowise-LangChain integration templates](https://volcano-ice-cd6.notion.site/Introduction-to-Practical-Building-LLM-Applications-with-Flowise-LangChain-03d6d75bfd20495d96dfdae964bea5a5).
+
+---
+
+(Due to technical issues, the search service is temporarily unavailable.)
+
+### Deployment Guide: Flowise-Ollama Chatbot System
+
+#### Prerequisites
+1. **Docker** and **Docker Compose** installed
+2. **Hugging Face Account** (for accessing LLM models)
+3. Minimum **8GB RAM** and **20GB Disk Space**
+
+---
+
+### Step-by-Step Deployment
+
+#### 1. Clone Repository
+```bash  
+git clone https://transfer.hft-stuttgart.de/gitlab/22baar1mst/flowise-ollama.git  
+cd flowise-ollama  
+```  
+
+#### 2. Configure Environment
+Create `.env` file or copy from .env.Example:
+```ini  
+# Database  
+DATABASE_NAME=flowise  
+DATABASE_USER=admin  
+DATABASE_PASSWORD=SecurePass123!  
+DATABASE_TYPE=postgres  
+DATABASE_PORT=5432  
+
+# Flowise  
+PORT=3000  
+FLOWISE_USERNAME=admin  
+FLOWISE_PASSWORD=AdminSecure456!  
+
+# Ollama  
+HF_TOKEN=your_huggingface_token  
+GIN_MODE=release  
+```  
+
+Don't forget to register and use credentials for
+HF_TOKEN=
+LANGCHAIN_API_KEY=
+
+
+#### 3. Start Services
+```bash  
+docker-compose up -d --build  
+```  
+*This will:*
+- Launch PostgreSQL database with persistent storage
+- Start Flowise with Ollama integration
+- Automatically load specified LLM models
+
+#### 4. Verify Services
+```bash  
+docker ps -a  
+```  
+Expected output:
+```  
+CONTAINER ID   IMAGE                      STATUS                   PORTS  
+a1b2c3d4e5f6   flowiseai/flowise:latest   Up 5 minutes (healthy)   0.0.0.0:3000->3000/tcp  
+g7h8i9j0k1l2   postgres:16-alpine         Up 5 minutes (healthy)   5432/tcp  
+m3n4o5p6q7r8   ollama                     Up 5 minutes            0.0.0.0:11434->11434/tcp  
+```  
+
+#### 5. Access Flowise UI
+1. Open `http://localhost:3000` in browser
+2. Log in using credentials from `.env`:
+    - **Username**: `admin`
+    - **Password**: `AdminSecure456!`
+
+#### 6. Import Chatflow
+1. Navigate to **Chatflows** → **Add New**
+2. Import `Ollama_RAG_Chatflow.json` (drag-and-drop or use file picker)
+3. Configure RAG parameters:
+   ```json  
+   {  
+     "model": "llama2-uncensored",  
+     "temperature": 0.7,  
+     "max_tokens": 500  
+   }  
+   ```  
+
+#### 7. Test Ollama Integration
+```bash  
+curl http://localhost:11434/api/tags  
+```  
+Expected response:
+```json  
+{"models":[{"name":"llama2-uncensored","modified_at":"2024-03-15T12:34:56.789Z"}]}  
+```  
+
+---
+
+### Key Endpoints
+| Service | URL | Port |  
+|---------|-----|------|  
+| Flowise UI | `http://<server-ip>:3000` | 3000 |  
+| Ollama API | `http://<server-ip>:11434` | 11434 |  
+| PostgreSQL | `postgres://admin:SecurePass123!@localhost:5432/flowise` | 5432 |  
+
+---
+
+### Troubleshooting
+1. **Healthcheck Failures**:
+   ```bash  
+   docker logs flowiseai --tail 50  
+   docker exec -it flowise-db psql -U admin -d flowise  
+   ```  
+
+2. **Model Loading Issues**:
+   ```bash  
+   docker exec ollama ollama list  
+   docker exec ollama ollama pull llama2-uncensored  
+   ```  
+
+3. **Port Conflicts**:  
+   Update `PORT` in `.env` and restart:
+   ```bash  
+   docker-compose down && docker-compose up -d  
+   ```  
+
+---
+
+### Security Recommendations
+1. Add Nginx reverse proxy with SSL
+2. Implement IP whitelisting for `/api/v1` endpoints
+3. Rotate database credentials monthly
+4. Monitor Ollama GPU utilization:
+   ```bash  
+   docker stats ollama  
+   ```  
+
+This deployment provides a fully functional educational chatbot system with RAG capabilities. For advanced configuration, refer to [Flowise-Ollama Integration Guide](https://github.com/ArtemBaranovsky/flowise-ollama).
\ No newline at end of file
-- 
GitLab