Commit 6b1191d6 authored by Artem Baranovskyi's avatar Artem Baranovskyi
Browse files

Partial solution with Nginx user access separation (to be finished).

Summarising.
parent 5c4d4470
No related merge requests found
Showing with 420 additions and 19 deletions
+420 -19
......@@ -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
......@@ -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
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
......@@ -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
......
# 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)
......
#!/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
readme.MD 0 → 100644
### 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
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment