feat: fix Presenton Azure OpenAI integration and add project documentation

- Add CLAUDE.md with comprehensive project documentation for Claude Code
- Fix Presenton to use LiteLLM proxy instead of direct Azure OpenAI calls
- Add LiteLLM proxy service to Presenton docker-compose
- Create .env.example and litellm-config.yaml.example templates
- Update .gitignore to exclude litellm-config.yaml but allow .env.example files
- Presenton now successfully connects to Azure OpenAI via LiteLLM proxy

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
SamoilenkoVadym 2025-11-06 09:19:27 +00:00
parent 117de92709
commit 0f40ef007f
5 changed files with 342 additions and 0 deletions

2
.gitignore vendored
View file

@ -51,6 +51,7 @@ desktop.ini
# Secrets and credentials
.env
.env.*
!.env.example
*.key
*.pem
*.p12
@ -58,6 +59,7 @@ desktop.ini
credentials.json
secrets.yaml
config/secrets/
litellm-config.yaml
# Database dumps and large backups
*.sql

260
CLAUDE.md Normal file
View file

@ -0,0 +1,260 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
This is a production infrastructure for AI-Impress, running on OVH server (ubuntu@51.89.231.46). The project uses a three-tier synchronization system:
1. **Syncthing** - Real-time bidirectional sync between Mac and server (10-30 seconds)
2. **GitHub** - Version control at git@github.com:SamoilenkoVadym/OVHserver.git
3. **rsync** - Full system backup for disaster recovery
**Critical:** You work with LOCAL files on Mac at `/Volumes/SSD/Aimpress_Cloud_Prod/`. Syncthing automatically syncs changes to the server. Never SSH into the server to make changes - always work locally.
## Architecture
### Directory Structure
```
/Volumes/SSD/Aimpress_Cloud_Prod/
├── opt/ # Main services (synced to server /opt)
│ ├── 00-infrastructure/ # Core: Traefik, PostgreSQL, Redis, Vault, RabbitMQ, Loki
│ ├── 01-security/ # Authentik (SSO), Vaultwarden
│ ├── 02-core/ # n8n (automation), Evolution API (WhatsApp), Supabase
│ ├── 03-business/ # Odoo (ERP), Outline (wiki), Documenso, Wiki.js
│ ├── 04-tools/ # Portainer, Grafana, Prometheus, Uptime Kuma
│ ├── 05-backups/ # Backup scripts and data (NOT in Git)
│ └── 06-webflow/ # Landing pages
├── data/ # Application data (synced to server /data)
├── home/ # Ubuntu user files (synced to server /home/ubuntu)
└── mnt/ # Mounted disks, backups, PostgreSQL data (synced to server /mnt)
```
### Technology Stack
- **Orchestration:** Docker + Docker Compose (all services are containerized)
- **Reverse Proxy:** Traefik with automatic SSL (Let's Encrypt via Cloudflare)
- **Databases:** PostgreSQL (shared: postgres-main), Redis (redis-main), RabbitMQ
- **Secrets:** HashiCorp Vault (do NOT commit secrets)
- **SSO:** Authentik (Single Sign-On for all services)
- **Monitoring:** Prometheus + Grafana + Loki + Uptime Kuma
- **Networks:** Docker networks - `traefik-public` (external), `database-internal` (external)
### Service Dependencies
Services MUST start in this order:
1. Traefik
2. PostgreSQL, Redis, RabbitMQ
3. Vault
4. Authentik
5. All other services
## Common Development Commands
### Docker Operations
```bash
# View running containers on server
ssh ubuntu@51.89.231.46 "docker ps"
# View logs for a container
ssh ubuntu@51.89.231.46 "docker logs <container_name>"
# Restart a service (via docker-compose)
ssh ubuntu@51.89.231.46 "cd /opt/<category>/<service> && docker compose restart"
# View service status
ssh ubuntu@51.89.231.46 "cd /opt/<category>/<service> && docker compose ps"
```
### Managing Services
Each service has a `docker-compose.yml` file in its directory:
- Traefik: `/opt/00-infrastructure/traefik/docker-compose.yml`
- n8n-shared: `/opt/02-core/n8n-shared/docker-compose.yml` (includes 4 workers)
- Odoo: `/opt/03-business/odoo/docker-compose.yml`
- etc.
To deploy/update a service:
1. Edit the `docker-compose.yml` locally
2. Wait for Syncthing sync (10-30 seconds)
3. SSH to server: `ssh ubuntu@51.89.231.46 "cd /opt/<path> && docker compose up -d"`
### Syncthing Operations
```bash
# Check Syncthing status on Mac
brew services list | grep syncthing
# Check Syncthing status on server
ssh ubuntu@51.89.231.46 "systemctl --user status syncthing"
# View sync size
du -sh /Volumes/SSD/Aimpress_Cloud_Prod/{opt,data,home,mnt}
```
### Backup Operations
Backup scripts are in `/opt/05-backups/scripts/`:
- `backup-full-enhanced.sh` - Comprehensive backup with auto-discovery
- Scripts use Restic for incremental backups to Cloudflare R2
- See `/opt/05-backups/SCRIPTS-REGISTRY.md` for full script inventory
## Git Workflow
### Automated Git Hooks
**pre-commit hook:**
- Blocks commits containing `.env`, `.key`, `.pem` files
- Warns about potential secrets
- Can override with `--no-verify` (use carefully)
**post-commit hook:**
- Automatically pushes every commit to GitHub
- Works with main/master branches
### Commit Message Format
```
<type>: <short description>
<optional detailed explanation>
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
```
**Types:**
- `feat:` - New feature
- `fix:` - Bug fix
- `refactor:` - Code refactoring
- `docs:` - Documentation
- `chore:` - Maintenance (configs, dependencies)
- `perf:` - Performance improvement
### What NOT to Commit
Excluded via `.gitignore`:
- Dependencies: `node_modules/`, `__pycache__/`, `venv/`
- Secrets: `.env`, `*.key`, `*.pem`, `credentials.json`
- Backups: `opt/05-backups/`, `*.sql.gz`, `*.tar.gz`
- Data: `**/docker-data/`, `**/volumes/`
- Logs: `*.log`, `logs/`
- System: `.DS_Store`, `.cache/`
## Key Configuration Patterns
### Traefik Labels
Services use Traefik labels for routing:
```yaml
labels:
- "traefik.enable=true"
- "traefik.http.routers.<service>.rule=Host(`<service>.ai-impress.com`)"
- "traefik.http.routers.<service>.entrypoints=websecure"
- "traefik.http.routers.<service>.tls.certresolver=cloudflare"
- "traefik.http.services.<service>.loadbalancer.server.port=<port>"
```
### Environment Variables
Services use `.env` files (NOT committed to Git):
- Database credentials reference shared PostgreSQL: `postgres-main`
- Redis credentials reference shared Redis: `redis-main`
- Passwords stored as `${VAR_NAME}` in docker-compose.yml
### Network Configuration
Services connect to external Docker networks:
```yaml
networks:
traefik-public:
external: true
database-internal:
external: true
```
## Important Architecture Notes
### n8n Configuration
n8n-shared runs in queue mode with Redis:
- 1 main instance (n8n-shared) handles UI and API
- 4 worker instances process jobs from Redis queue
- Workers 1-2: High concurrency (20 jobs)
- Workers 3-4: Medium concurrency (15 jobs)
- Webhooks and OAuth endpoints bypass authentication for external access
### Database Architecture
- Single PostgreSQL instance (`postgres-main`) serves multiple services
- Each service has its own database (e.g., `n8n_shared`, `odoo_db`)
- Connection via `database-internal` network
- Data stored in `/mnt/psql-data/`
### SSL & Domain Management
All services use:
- Domain: `*.ai-impress.com`
- SSL via Traefik + Cloudflare DNS challenge
- Certificates stored in `/opt/00-infrastructure/traefik/acme/`
## Workflow for Claude Code
When making changes:
1. **Read** local files from `/Volumes/SSD/Aimpress_Cloud_Prod/`
2. **Edit** files locally (never SSH to make changes)
3. **Wait** 10-30 seconds for Syncthing to sync to server
4. **Commit** with descriptive message using format above
5. **Verify** changes on server if needed (via SSH to view logs/status)
When adding new services:
1. Create directory in appropriate `/opt/<category>/` folder
2. Create `docker-compose.yml` with Traefik labels
3. Create `.env` file (will be auto-ignored by Git)
4. Add to appropriate Docker networks
5. Document in project structure files
6. Test on server, then commit
## Important Security Notes
- **Never commit secrets** - pre-commit hook will block `.env` files
- **Use Vault** for sensitive credentials when possible
- **Authentik SSO** protects most admin interfaces
- **Traefik middleware** can add authentication to services
- Database passwords are in `.env` files, referenced as `${VAR_NAME}`
## Troubleshooting
### Service Won't Start
1. Check logs: `ssh ubuntu@51.89.231.46 "docker logs <container>"`
2. Verify networks exist: `ssh ubuntu@51.89.231.46 "docker network ls"`
3. Check if port is already in use
4. Verify Traefik is running first
### Syncthing Issues
1. Check status on both Mac and server
2. View sync conflicts in Syncthing UI
3. Check `.stignore` for exclusion patterns
4. Verify folder permissions
### Database Connection Issues
1. Ensure `postgres-main` container is running
2. Check `database-internal` network exists
3. Verify credentials in `.env` file
4. Check PostgreSQL logs: `ssh ubuntu@51.89.231.46 "docker logs postgres-main"`
## Reference Documentation
- Detailed structure: `.claude/project-structure.md`
- Workflow details: `.claude/workflow.md`
- Backup scripts: `opt/05-backups/SCRIPTS-REGISTRY.md`
- Main README: `README.md`

View file

@ -0,0 +1,43 @@
# ===========================================
# PRESENTON - AI PRESENTATION GENERATOR
# Azure OpenAI Configuration
# ===========================================
# ============================================
# LLM PROVIDER - LiteLLM Proxy (Azure OpenAI)
# ============================================
LLM=custom
CUSTOM_LLM_URL=http://litellm-proxy:4000
CUSTOM_LLM_API_KEY=presenton-proxy-key-2025
CUSTOM_MODEL=gpt-5
TOOL_CALLS=true
# ============================================
# IMAGE GENERATION - Azure DALL-E 3
# ============================================
IMAGE_PROVIDER=dall-e-3
OPENAI_API_KEY=your-azure-dalle3-api-key-here
# Azure DALL-E 3 Base URL (if needed)
# Note: Presenton may need custom configuration for Azure DALL-E endpoint
# Standard endpoint: https://vsam-mhmldl4f-swedencentral.cognitiveservices.azure.com/openai/deployments/dall-e-3
# ============================================
# ADVANCED FEATURES
# ============================================
# Allow changing API keys in UI
CAN_CHANGE_KEYS=true
# Enable extended reasoning (for GPT-5)
EXTENDED_REASONING=true
# Disable anonymous telemetry
DISABLE_ANONYMOUS_TELEMETRY=true
# Web grounding (search capabilities)
# WEB_GROUNDING=false
# ============================================
# DATABASE (Optional - SQLite by default)
# ============================================
# DATABASE_URL=sqlite:///app_data/presenton.db

View file

@ -1,16 +1,39 @@
version: '3.8'
services:
litellm-proxy:
image: ghcr.io/berriai/litellm:main-latest
container_name: litellm-proxy
restart: unless-stopped
networks:
- presenton-internal
volumes:
- ./litellm-config.yaml:/app/config.yaml
command: ["--config", "/app/config.yaml", "--host", "0.0.0.0", "--port", "4000"]
environment:
- LITELLM_MASTER_KEY=presenton-proxy-key-2025
deploy:
resources:
limits:
cpus: '1'
memory: 1G
reservations:
cpus: '0.5'
memory: 256M
presenton:
image: ghcr.io/presenton/presenton:latest
container_name: presenton
restart: unless-stopped
networks:
- traefik-public
- presenton-internal
env_file:
- .env
volumes:
- ./app_data:/app_data
depends_on:
- litellm-proxy
deploy:
resources:
limits:
@ -30,3 +53,4 @@ services:
networks:
traefik-public:
external: true
presenton-internal:

View file

@ -0,0 +1,13 @@
model_list:
- model_name: gpt-5
litellm_params:
model: azure/gpt-5
api_base: https://your-azure-resource.cognitiveservices.azure.com
api_key: os.environ/AZURE_API_KEY
api_version: "2025-01-01-preview"
litellm_settings:
drop_params: true
general_settings:
master_key: "presenton-proxy-key-2025"