Add complete homelab documentation and configurations
Documentation: - OpenCode + LiteLLM integration guide - LiteLLM complete setup with 16 models - Gitea centralized configuration guide - Testing procedures and verification - API keys setup instructions Configurations: - OpenCode config pointing to LiteLLM - Updated LiteLLM config with all models - Nextcloud docker-compose template Scripts: - Gitea setup automation - OpenCode testing script Infrastructure: - Gitea: 192.168.88.200:3000 - LiteLLM: 192.168.88.27:4000 - Nextcloud: 192.168.88.62
This commit is contained in:
@@ -0,0 +1,311 @@
|
||||
#!/bin/bash
|
||||
################################################################################
|
||||
# Homelab Centralized Configuration via Gitea
|
||||
#
|
||||
# This script sets up a central homelab-configs repository and configures VMs
|
||||
# to pull their configurations from Gitea instead of managing per-VM configs
|
||||
################################################################################
|
||||
|
||||
set -e
|
||||
|
||||
# Configuration
|
||||
GITEA_URL="http://192.168.88.200:3000"
|
||||
GITEA_USER="jgitta"
|
||||
REPO_NAME="homelab-configs"
|
||||
LITELLM_API="http://192.168.88.27:4000"
|
||||
MASTER_KEY="litellm-local-key-change-in-production"
|
||||
|
||||
# Colors for output
|
||||
GREEN='\033[0;32m'
|
||||
BLUE='\033[0;34m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${BLUE}╔════════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e "${BLUE}║ Homelab Centralized Configuration Setup via Gitea ║${NC}"
|
||||
echo -e "${BLUE}╚════════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
|
||||
# Step 1: Create local repository
|
||||
echo -e "${BLUE}Step 1: Creating local homelab-configs repository...${NC}"
|
||||
TEMP_DIR=$(mktemp -d)
|
||||
cd "$TEMP_DIR"
|
||||
|
||||
git init
|
||||
git config user.name "$GITEA_USER"
|
||||
git config user.email "$GITEA_USER@jgitta.com"
|
||||
|
||||
# Create directory structure
|
||||
mkdir -p opencode litellm jellyfin
|
||||
|
||||
# Create OpenCode configuration
|
||||
cat > opencode/config.json << 'EOF'
|
||||
{
|
||||
"apiProvider": "openai",
|
||||
"apiBase": "http://192.168.88.27:4000",
|
||||
"apiKey": "litellm-local-key-change-in-production",
|
||||
"model": "gpt-4o",
|
||||
"timeout": 600,
|
||||
"maxTokens": 4096,
|
||||
"verbose": true
|
||||
}
|
||||
EOF
|
||||
echo -e "${GREEN}✅ Created opencode/config.json${NC}"
|
||||
|
||||
# Create LiteLLM reference
|
||||
cat > litellm/README.md << 'EOF'
|
||||
# LiteLLM API Gateway Reference
|
||||
|
||||
**Endpoint**: `http://192.168.88.27:4000`
|
||||
|
||||
**Master Authentication Key**: `litellm-local-key-change-in-production`
|
||||
|
||||
**Available Models** (16 total):
|
||||
|
||||
### OpenAI (5 models)
|
||||
- gpt-4o (latest, multimodal)
|
||||
- gpt-4o-mini (fast, cheap)
|
||||
- gpt-4-turbo
|
||||
- gpt-4
|
||||
- gpt-3.5-turbo
|
||||
|
||||
### Claude (6 models)
|
||||
- claude-3.5-sonnet (latest)
|
||||
- claude-opus-4 (flagship)
|
||||
- claude-3-opus
|
||||
- claude-3-sonnet
|
||||
- claude-3-haiku
|
||||
- claude-2.1
|
||||
|
||||
### Gemini (5 models)
|
||||
- gemini-2.0-flash (latest, ultra-fast)
|
||||
- gemini-2.0-pro
|
||||
- gemini-1.5-pro
|
||||
- gemini-1.5-flash
|
||||
- gemini-pro
|
||||
|
||||
**Configuration Location**: `/opt/litellm/config/litellm_config.yaml` (docker-server)
|
||||
|
||||
**Full Setup Guide**: See litellm-complete-setup.md in the main project folder
|
||||
EOF
|
||||
echo -e "${GREEN}✅ Created litellm/README.md${NC}"
|
||||
|
||||
# Create Jellyfin placeholder
|
||||
cat > jellyfin/README.md << 'EOF'
|
||||
# Jellyfin Configuration
|
||||
|
||||
Placeholder for Jellyfin service configuration.
|
||||
|
||||
This will be expanded as needed for centralized media server management.
|
||||
EOF
|
||||
echo -e "${GREEN}✅ Created jellyfin/README.md${NC}"
|
||||
|
||||
# Create main README
|
||||
cat > README.md << 'EOF'
|
||||
# 🏠 Homelab Centralized Configuration
|
||||
|
||||
Central Git repository for managing configurations across all homelab VMs and services.
|
||||
|
||||
## 📂 Repository Structure
|
||||
|
||||
```
|
||||
homelab-configs/
|
||||
├── opencode/ # OpenCode IDE configuration
|
||||
│ └── config.json # Points to LiteLLM API gateway
|
||||
├── litellm/ # LiteLLM API Gateway reference
|
||||
│ └── README.md # Model list and endpoint details
|
||||
├── jellyfin/ # Jellyfin media server configs
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
## 🔄 How VMs Use These Configs
|
||||
|
||||
Each VM's docker-compose pulls configs from this repo at startup:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
opencode:
|
||||
image: opencode:latest
|
||||
volumes:
|
||||
- opencode-config:/root/.opencode
|
||||
entrypoint: /bin/sh
|
||||
command: |
|
||||
-c "
|
||||
git clone $GITEA_URL/$GITEA_USER/$REPO_NAME.git /tmp/configs
|
||||
cp /tmp/configs/opencode/config.json /root/.opencode/config.json
|
||||
exec opencode
|
||||
"
|
||||
volumes:
|
||||
opencode-config:
|
||||
```
|
||||
|
||||
## 📝 Central Configuration Management Pattern
|
||||
|
||||
### To Update a Config for All VMs:
|
||||
|
||||
1. **Edit the config here**:
|
||||
```bash
|
||||
nano opencode/config.json
|
||||
```
|
||||
|
||||
2. **Commit and push**:
|
||||
```bash
|
||||
git add opencode/config.json
|
||||
git commit -m "Update OpenCode to use gpt-4o-mini"
|
||||
git push origin main
|
||||
```
|
||||
|
||||
3. **Next time VMs restart**, they automatically pull the latest:
|
||||
- Container starts
|
||||
- Runs: `git clone ... && cp /tmp/configs/...`
|
||||
- Gets latest config from this repo
|
||||
- Starts service with new config
|
||||
|
||||
**No per-VM configuration needed!**
|
||||
|
||||
## 🌐 Infrastructure Reference
|
||||
|
||||
| Service | URL/IP | Purpose |
|
||||
|---------|--------|---------|
|
||||
| Gitea | http://192.168.88.200:3000 | Central config repository |
|
||||
| LiteLLM API | http://192.168.88.27:4000 | Unified AI model gateway |
|
||||
| Nextcloud (next) | 192.168.88.62 | Running OpenCode |
|
||||
| Docker Server (siklos) | 192.168.88.27 | Hosting LiteLLM |
|
||||
|
||||
## 🚀 Key Features
|
||||
|
||||
- ✅ **Single Point of Configuration**: All VM configs in one repo
|
||||
- ✅ **Version Control**: Track all changes via git
|
||||
- ✅ **Zero Per-VM Setup**: Configs injected at container startup
|
||||
- ✅ **Easy Rollbacks**: Just `git revert` and re-deploy
|
||||
- ✅ **Centralized Secrets**: API keys managed in one place
|
||||
|
||||
## 📋 Adding New Services
|
||||
|
||||
To add a new service to centralized config:
|
||||
|
||||
1. Create directory: `mkdir -p servicename`
|
||||
2. Add config file: `touch servicename/config.json`
|
||||
3. Update the service's docker-compose to clone and use it
|
||||
4. Commit and push
|
||||
|
||||
## 🔒 Security Notes
|
||||
|
||||
- API keys stored here should be masked/excluded from public repos
|
||||
- Use `.env` files for sensitive data (not committed)
|
||||
- Each service's docker-compose should fetch configs at runtime
|
||||
- Rotate master keys periodically
|
||||
|
||||
## 📚 Documentation
|
||||
|
||||
- **LiteLLM Setup**: See `litellm-complete-setup.md`
|
||||
- **Model Information**: See `litellm/README.md`
|
||||
- **Testing Guide**: See `litellm-testing-verification.md`
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: April 25, 2026
|
||||
**Maintained By**: jgitta
|
||||
**Repository**: http://192.168.88.200:3000/jgitta/homelab-configs
|
||||
EOF
|
||||
echo -e "${GREEN}✅ Created README.md${NC}"
|
||||
|
||||
# Stage and commit
|
||||
git add .
|
||||
git commit -m "Initial homelab-configs setup - centralized configuration management
|
||||
|
||||
- OpenCode configuration pointing to LiteLLM gateway at 192.168.88.27:4000
|
||||
- LiteLLM API reference with all 16 available models
|
||||
- Jellyfin placeholder for future expansion
|
||||
- Central management pattern documentation
|
||||
- Infrastructure reference and usage guide"
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}✅ Local repository prepared${NC}"
|
||||
echo -e "${BLUE}Repository location: $TEMP_DIR${NC}"
|
||||
echo ""
|
||||
|
||||
# Step 2: Instructions for Gitea
|
||||
echo -e "${YELLOW}Step 2: Create repository in Gitea${NC}"
|
||||
echo ""
|
||||
echo "📍 Manual steps (takes 30 seconds):"
|
||||
echo " 1. Open: $GITEA_URL/user/repositories"
|
||||
echo " 2. Click: '+' (New Repository)"
|
||||
echo " 3. Fill in:"
|
||||
echo " - Name: $REPO_NAME"
|
||||
echo " - Description: Centralized configuration for all homelab VMs"
|
||||
echo " - Private: (your choice)"
|
||||
echo " 4. Click: 'Create Repository'"
|
||||
echo ""
|
||||
|
||||
# Step 3: Push to Gitea
|
||||
echo -e "${YELLOW}Step 3: Push repository to Gitea${NC}"
|
||||
echo ""
|
||||
echo "📋 After creating the repo in Gitea, run these commands:"
|
||||
echo ""
|
||||
echo " cd $TEMP_DIR"
|
||||
echo " git remote add origin $GITEA_URL/$GITEA_USER/$REPO_NAME.git"
|
||||
echo " git branch -M main"
|
||||
echo " git push -u origin main"
|
||||
echo ""
|
||||
echo "Or via SSH (if configured):"
|
||||
echo " git remote add origin ssh://git@192.168.88.200:22/$GITEA_USER/$REPO_NAME.git"
|
||||
echo " git branch -M main"
|
||||
echo " git push -u origin main"
|
||||
echo ""
|
||||
|
||||
# Step 4: Update Nextcloud docker-compose
|
||||
echo -e "${YELLOW}Step 4: Update Nextcloud (next) docker-compose${NC}"
|
||||
echo ""
|
||||
echo "📝 Update the OpenCode service in the Nextcloud VM's docker-compose.yml:"
|
||||
echo ""
|
||||
cat << 'DOCKER_COMPOSE_EXAMPLE'
|
||||
services:
|
||||
opencode:
|
||||
image: opencode:latest
|
||||
container_name: opencode
|
||||
volumes:
|
||||
- opencode-config:/root/.opencode
|
||||
- ./workspace:/workspace
|
||||
ports:
|
||||
- "8000:8000" # Adjust port as needed
|
||||
entrypoint: /bin/sh
|
||||
command: |
|
||||
-c "
|
||||
mkdir -p /tmp/configs
|
||||
git clone http://192.168.88.200:3000/jgitta/homelab-configs.git /tmp/configs || true
|
||||
mkdir -p /root/.opencode
|
||||
cp /tmp/configs/opencode/config.json /root/.opencode/config.json
|
||||
exec opencode
|
||||
"
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
opencode-config:
|
||||
DOCKER_COMPOSE_EXAMPLE
|
||||
|
||||
echo ""
|
||||
echo "🔄 Restart OpenCode after updating:"
|
||||
echo " ssh jgitta@192.168.88.62"
|
||||
echo " cd /path/to/docker-compose"
|
||||
echo " docker-compose down"
|
||||
echo " docker-compose up -d"
|
||||
echo ""
|
||||
|
||||
# Summary
|
||||
echo ""
|
||||
echo -e "${GREEN}╔════════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e "${GREEN}║ Setup Complete! ║${NC}"
|
||||
echo -e "${GREEN}╚════════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
echo "✨ Next steps:"
|
||||
echo " 1. Create repository in Gitea web UI"
|
||||
echo " 2. Push local repo from: $TEMP_DIR"
|
||||
echo " 3. Update Nextcloud docker-compose"
|
||||
echo " 4. Restart OpenCode service"
|
||||
echo ""
|
||||
echo "📚 After setup:"
|
||||
echo " - All configs managed in: $GITEA_URL/$GITEA_USER/$REPO_NAME"
|
||||
echo " - VMs automatically pull latest on startup"
|
||||
echo " - No per-VM configuration needed"
|
||||
echo ""
|
||||
@@ -0,0 +1,157 @@
|
||||
#!/bin/bash
|
||||
################################################################################
|
||||
# Quick Test Script - OpenCode + LiteLLM Integration
|
||||
#
|
||||
# Run this on your Nextcloud VM (next @ 192.168.88.62)
|
||||
# to verify the entire setup is working
|
||||
################################################################################
|
||||
|
||||
set -e
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
BLUE='\033[0;34m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
PASS_COUNT=0
|
||||
FAIL_COUNT=0
|
||||
|
||||
# Helper functions
|
||||
pass() {
|
||||
echo -e "${GREEN}✅ $1${NC}"
|
||||
((PASS_COUNT++))
|
||||
}
|
||||
|
||||
fail() {
|
||||
echo -e "${RED}❌ $1${NC}"
|
||||
((FAIL_COUNT++))
|
||||
}
|
||||
|
||||
info() {
|
||||
echo -e "${BLUE}ℹ️ $1${NC}"
|
||||
}
|
||||
|
||||
section() {
|
||||
echo ""
|
||||
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
echo -e "${BLUE}$1${NC}"
|
||||
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
}
|
||||
|
||||
# Main tests
|
||||
section "OpenCode + LiteLLM Integration Tests"
|
||||
|
||||
# Test 1: Config File
|
||||
section "Test 1: Configuration File"
|
||||
|
||||
if [ -f ~/.opencode/config.json ]; then
|
||||
pass "Config file exists at ~/.opencode/config.json"
|
||||
|
||||
# Check for correct API base
|
||||
if cat ~/.opencode/config.json | grep -q "192.168.88.27:4000"; then
|
||||
pass "Config points to LiteLLM gateway (192.168.88.27:4000)"
|
||||
else
|
||||
fail "Config does not point to LiteLLM gateway"
|
||||
fi
|
||||
|
||||
# Check for correct API provider
|
||||
if cat ~/.opencode/config.json | grep -q "openai"; then
|
||||
pass "Config uses OpenAI-compatible API provider"
|
||||
else
|
||||
fail "Config does not use OpenAI provider"
|
||||
fi
|
||||
else
|
||||
fail "Config file does not exist at ~/.opencode/config.json"
|
||||
info "Try restarting: docker-compose restart opencode"
|
||||
fi
|
||||
|
||||
# Test 2: Docker Container
|
||||
section "Test 2: Docker Container Status"
|
||||
|
||||
if docker ps | grep -q opencode; then
|
||||
pass "OpenCode container is running"
|
||||
else
|
||||
fail "OpenCode container is not running"
|
||||
info "Start it: docker-compose up -d opencode"
|
||||
fi
|
||||
|
||||
# Test 3: LiteLLM Gateway Access
|
||||
section "Test 3: LiteLLM Gateway Connectivity"
|
||||
|
||||
if timeout 5 docker exec opencode curl -s http://192.168.88.27:4000/models \
|
||||
-H "Authorization: Bearer litellm-local-key-change-in-production" > /dev/null 2>&1; then
|
||||
|
||||
MODEL_COUNT=$(docker exec opencode curl -s http://192.168.88.27:4000/models \
|
||||
-H "Authorization: Bearer litellm-local-key-change-in-production" | grep -o '"id"' | wc -l)
|
||||
|
||||
if [ "$MODEL_COUNT" -eq 16 ]; then
|
||||
pass "LiteLLM gateway is accessible with all 16 models"
|
||||
else
|
||||
fail "LiteLLM gateway returned $MODEL_COUNT models (expected 16)"
|
||||
fi
|
||||
else
|
||||
fail "Cannot reach LiteLLM gateway at 192.168.88.27:4000"
|
||||
info "Check: curl http://192.168.88.27:4000/models"
|
||||
fi
|
||||
|
||||
# Test 4: Gitea Accessibility
|
||||
section "Test 4: Gitea Repository Connectivity"
|
||||
|
||||
if timeout 5 docker exec opencode curl -s http://192.168.88.200:3000/api/v1/version > /dev/null 2>&1; then
|
||||
pass "Gitea is accessible at 192.168.88.200:3000"
|
||||
|
||||
GITEA_VERSION=$(docker exec opencode curl -s http://192.168.88.200:3000/api/v1/version | grep -o '"version":"[^"]*"' | cut -d'"' -f4)
|
||||
info "Gitea version: $GITEA_VERSION"
|
||||
else
|
||||
fail "Cannot reach Gitea at 192.168.88.200:3000"
|
||||
info "Check Gitea status on docker-server"
|
||||
fi
|
||||
|
||||
# Test 5: API Call Test (with placeholder keys)
|
||||
section "Test 5: API Gateway Routing"
|
||||
|
||||
info "Attempting test call to LiteLLM gateway..."
|
||||
info "(Expected to fail with 401 - testing placeholder keys)"
|
||||
|
||||
RESPONSE=$(curl -s -X POST http://192.168.88.27:4000/chat/completions \
|
||||
-H "Authorization: Bearer litellm-local-key-change-in-production" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"model": "gpt-4o", "messages": [{"role": "user", "content": "test"}]}')
|
||||
|
||||
if echo "$RESPONSE" | grep -q "401\|Incorrect API key\|invalid_api_key"; then
|
||||
pass "API gateway is routing correctly (401 = placeholder keys are expected)"
|
||||
info "This is GOOD - it means the system is working!"
|
||||
info "Once you add real API keys, you'll get actual responses"
|
||||
elif echo "$RESPONSE" | grep -q "error"; then
|
||||
fail "API returned an unexpected error: $(echo $RESPONSE | head -c 100)..."
|
||||
else
|
||||
pass "Unexpected successful response (may have real keys configured)"
|
||||
fi
|
||||
|
||||
# Summary
|
||||
section "Test Summary"
|
||||
|
||||
TOTAL=$((PASS_COUNT + FAIL_COUNT))
|
||||
echo ""
|
||||
echo -e "${GREEN}Passed: $PASS_COUNT/$TOTAL${NC}"
|
||||
|
||||
if [ $FAIL_COUNT -gt 0 ]; then
|
||||
echo -e "${RED}Failed: $FAIL_COUNT/$TOTAL${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}⚠️ Some tests failed. Check the troubleshooting guide:${NC}"
|
||||
echo " opencode-testing-guide.md"
|
||||
exit 1
|
||||
else
|
||||
echo -e "${GREEN}All tests passed!${NC}"
|
||||
echo ""
|
||||
echo -e "${GREEN}✨ Your setup is working correctly!${NC}"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " 1. Add real API keys to /opt/litellm/.env on docker-server"
|
||||
echo " 2. Restart LiteLLM: cd /opt/litellm && docker-compose restart"
|
||||
echo " 3. Test again: bash /path/to/quick-test-opencode.sh"
|
||||
echo " 4. Start using OpenCode with full LiteLLM integration!"
|
||||
echo ""
|
||||
fi
|
||||
Reference in New Issue
Block a user