# Centralized Configuration via Gitea - Implementation Guide **Date**: April 25, 2026 **Goal**: Manage all VM configurations from a single Gitea repository **Result**: Zero per-VM configuration needed, all configs auto-fetched at startup --- ## 🎯 What This Achieves Instead of managing configs on each VM: ``` OLD (Per-VM): VM1: nano ~/.opencode/config.json VM2: nano ~/.opencode/config.json VM3: nano ~/.opencode/config.json ...repeat for every VM ``` With centralized Gitea: ``` NEW (Single location): Gitea repo: edit opencode/config.json once All VMs: automatically pull latest on startup ``` --- ## 📋 Implementation Steps ### Step 1: Create the Gitea Repository (2 minutes) 1. Go to: **http://192.168.88.27:3002** 2. Click **+** (top right) → **New Repository** 3. Fill in: - **Repository name**: `homelab-configs` - **Description**: "Centralized configuration for all homelab VMs" - **Visibility**: Public (or Private if you prefer) 4. Click **Create Repository** ### Step 2: Prepare and Push Configuration Files (5 minutes) Run the setup script: ```bash bash /home/jgitta/Documents/Claude/Projects/Homelab\ Infrastructure/gitea-centralized-setup.sh ``` This will: 1. ✅ Create local git repository with all configs 2. ✅ Show you the push commands to run 3. ✅ Display next steps **OR manually:** ```bash # Create and commit configs locally cd ~/homelab-configs git init git config user.name "jgitta" git config user.email "jgitta@jgitta.com" # Add files (see script for structure) git add . git commit -m "Initial homelab-configs setup" # Add remote and push git remote add origin http://192.168.88.27:3002/jgitta/homelab-configs.git git branch -M main git push -u origin main ``` ### Step 3: Update Nextcloud Docker-Compose (5 minutes) SSH to Nextcloud VM: ```bash ssh jgitta@192.168.88.62 ``` Find the docker-compose.yml file (likely in `/home/jgitta/docker` or similar): ```bash cd /path/to/docker-compose ``` Edit the OpenCode service to pull configs from Gitea. Use the template from: **`nextcloud-docker-compose-update.yml`** Or update your existing docker-compose by adding this to the `opencode` service: ```yaml entrypoint: /bin/sh command: | -c " mkdir -p /tmp/homelab-configs git clone http://192.168.88.27:3002/jgitta/homelab-configs.git /tmp/homelab-configs || true mkdir -p /root/.opencode cp /tmp/homelab-configs/opencode/config.json /root/.opencode/config.json exec opencode " ``` ### Step 4: Restart OpenCode Service (2 minutes) ```bash cd /path/to/docker-compose # Stop and remove docker-compose down # Start with new config docker-compose up -d opencode # Check logs docker-compose logs -f opencode ``` You should see: ``` 🔄 Fetching configuration from Gitea... ✅ Configuration fetched successfully ✅ OpenCode config loaded from Gitea 🚀 Starting OpenCode... ``` --- ## 🔄 Ongoing Management ### To Update OpenCode Config for All VMs ```bash # Clone the repo (or update if you have it) git clone http://192.168.88.27:3002/jgitta/homelab-configs.git cd homelab-configs # Edit the config nano opencode/config.json # Commit and push git add opencode/config.json git commit -m "Switch to gpt-4o-mini for faster responses" git push origin main ``` **Next time OpenCode restarts**, it automatically gets the latest config! ### Adding More Services Same pattern for any other service: 1. Create directory: `mkdir jellyfin` 2. Add config: `cp ~/jellyfin/config.yml jellyfin/` 3. Update that service's docker-compose to fetch from Gitea 4. Commit and push --- ## 📁 Repository Structure ``` homelab-configs/ ├── README.md # Overview and usage guide ├── opencode/ │ └── config.json # OpenCode IDE config │ ├── apiBase: http://192.168.88.27:4000 │ ├── apiKey: litellm-local-key-... │ └── model: gpt-4o ├── litellm/ │ └── README.md # API gateway reference │ ├── Endpoint: 192.168.88.27:4000 │ ├── Models: 16 available │ └── Master Key: litellm-local-... └── jellyfin/ └── (placeholder for future expansion) ``` --- ## ✅ Verification ### Check if Repository Created: ```bash curl http://192.168.88.27:3002/api/v1/repos/jgitta/homelab-configs \ 2>/dev/null | jq '.name' # Should output: homelab-configs ``` ### Check if Configs Are Accessible: ```bash curl http://192.168.88.27:3002/jgitta/homelab-configs/raw/branch/main/opencode/config.json \ 2>/dev/null | jq '.apiBase' # Should output: "http://192.168.88.27:4000" ``` ### Check if OpenCode Pulled Config: ```bash # SSH to Nextcloud ssh jgitta@192.168.88.62 # Check the config file cat ~/.opencode/config.json | jq '.' # Should show the config from Gitea ``` --- ## 🎯 Key Benefits Achieved | Before | After | |--------|-------| | Configs on each VM | Single Gitea repo | | Manual edits per VM | One edit, all VMs update | | No version control | Full git history | | Hard to rollback | `git revert` to any point | | Config drift | Single source of truth | --- ## 🔐 Security Considerations - **API Keys**: Currently in plaintext in `opencode/config.json` - For production: Use `.env` file not committed to git - Or: Use Docker secrets - Or: Fetch from secure vault - **Repository Privacy**: - Set repo to Private if exposing internal IPs concerns you - Current setup is fine for internal network only - **Git Clone Access**: - Currently HTTP (works on internal network) - Can use SSH if configured with deploy keys --- ## 📝 Common Tasks ### Change Model for All VMs ```bash cd homelab-configs nano opencode/config.json # Change: "model": "gpt-4o" → "model": "claude-3.5-sonnet" git add opencode/config.json git commit -m "Switch model to claude-3.5-sonnet" git push origin main # Next OpenCode restart gets new model ``` ### Add New Service Config ```bash mkdir -p myservice cat > myservice/config.json << 'EOF' { "apiEndpoint": "http://192.168.88.27:4000", "key": "litellm-local-key-change-in-production" } EOF git add myservice/ git commit -m "Add myservice configuration" git push origin main ``` ### Check Config History ```bash git log --oneline opencode/config.json # Shows every change made to OpenCode config ``` ### Revert to Previous Config ```bash # Find the commit you want to revert to git log --oneline opencode/config.json # Revert to that commit git revert git push origin main # Next restart: VMs get the old config back ``` --- ## 🚨 Troubleshooting ### "Configuration fetched successfully" but config not applied - Check docker-compose volumes are mounted correctly - Verify `/root/.opencode/config.json` exists in container: ```bash docker exec opencode cat /root/.opencode/config.json | jq '.' ``` ### "Could not fetch configs from Gitea" - Check network access: `curl http://192.168.88.27:3002/` - Verify Gitea repo exists and is public (or accessible) - Check docker-compose logs: `docker-compose logs opencode` ### Changes pushed but not pulled by VM - Restart the container: `docker-compose restart opencode` - Containers only pull config at startup ### "apiBase connection refused" - Verify LiteLLM is running: `curl http://192.168.88.27:4000/models` - Check docker network: containers need network access to docker-server --- ## 📚 Files Provided | File | Purpose | |------|---------| | `gitea-centralized-setup.sh` | Automated setup script | | `nextcloud-docker-compose-update.yml` | Updated docker-compose template | | `gitea-centralized-implementation.md` | This guide | --- ## 🎓 Summary You now have: - ✅ Central Gitea repository for all VM configs - ✅ Nextcloud (next) pulling OpenCode config from Gitea - ✅ OpenCode pointing to LiteLLM gateway at 192.168.88.27:4000 - ✅ Zero per-VM configuration needed - ✅ Full version control of all changes - ✅ Easy rollbacks with git **All VMs automatically pull latest config on startup!**