Compare commits
12
Commits
653cd2771e
...
cfb6cea452
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cfb6cea452 | ||
|
|
d0f06918ea | ||
|
|
bc1574b36e | ||
|
|
827dffe164 | ||
|
|
71cd913d05 | ||
|
|
aa54af8a87 | ||
|
|
dd141099e1 | ||
|
|
ec8c3f5925 | ||
|
|
24a70d9527 | ||
|
|
9ac817bb6e | ||
|
|
cd3cdad11c | ||
|
|
27e7d9aff0 |
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"WebSearch",
|
||||
"Bash(docker logs:*)",
|
||||
"Bash(docker ps:*)",
|
||||
"Bash(docker inspect:*)",
|
||||
"Bash(tree:*)",
|
||||
"Bash(nvidia-smi:*)",
|
||||
"Bash(find:*)",
|
||||
"Bash(grep:*)",
|
||||
"Bash(cat:*)"
|
||||
],
|
||||
"deny": [],
|
||||
"ask": []
|
||||
}
|
||||
}
|
||||
@@ -70,6 +70,10 @@ docker-compose.override.yml
|
||||
# Local configuration (machine-specific)
|
||||
local.yml
|
||||
local.config
|
||||
.claude/settings.local.json
|
||||
|
||||
# Jupyter notebook checkpoints
|
||||
.ipynb_checkpoints/
|
||||
|
||||
# Archive files
|
||||
*.zip
|
||||
|
||||
@@ -17,7 +17,7 @@ This is the `tower-of-joy` project - a containerized home server infrastructure
|
||||
|
||||
**Purpose:** Self-hosted services platform with GPU-accelerated ML model serving, media streaming, cloud storage, and secure remote access.
|
||||
|
||||
**System:** Intel i7-6700, RTX 2080 Ti (11GB VRAM), 16GB RAM, Zorin OS 16.3 (Ubuntu 20.04 based)
|
||||
**System:** Intel i7-6700, RTX 2080 Ti (11GB VRAM), 64GB RAM, Zorin OS 16.3 (Ubuntu 20.04 based)
|
||||
|
||||
**Storage Architecture:**
|
||||
- **SSD (489GB):** Container configs, databases, Docker images - `/home/jpmschweitzer/docker-data/`
|
||||
|
||||
+101
-3
@@ -1,7 +1,7 @@
|
||||
# Container Reference - tower-of-joy Infrastructure
|
||||
|
||||
> **Last Updated:** 2026-01-31
|
||||
> **Total Services:** 34 containers across 21 stacks
|
||||
> **Last Updated:** 2026-02-20
|
||||
> **Total Services:** 37 containers across 23 stacks
|
||||
> **System:** Intel i7-6700, RTX 2080 Ti (11GB VRAM), 64GB RAM, Zorin OS 16.3
|
||||
|
||||
---
|
||||
@@ -40,8 +40,11 @@
|
||||
| **Paperless-ngx** | 8091 | https://documents.schweitz.net | Internet | No | 8 | ✅ Running |
|
||||
| **Penpot** | 9001 | https://penpot.schweitz.net | Internet (SSO) | No | 10 | ✅ Running |
|
||||
| **ClamAV** | 3310 | N/A (host service) | No | No | - | ✅ Running |
|
||||
| **Shell In A Box** | 4200 | https://shell.schweitz.net | Internet (host service) | No | - | ✅ Running |
|
||||
| **AdGuard Home** | 53, 3053 | http://dns.schweitz.internal | LAN (DNS) | No | - | ✅ Running |
|
||||
| **Tatlock UI** | 9999 | https://home.schweitz.net | Internet | No | - | ✅ Running |
|
||||
| **Stable Audio** | 11500 | http://192.168.86.149:11500 | LAN | Yes (RTX 2080 Ti) | - | ⏸️ Not Deployed |
|
||||
| **TRELLIS** | 11510 | http://192.168.86.149:11510 | LAN | Yes (RTX 2080 Ti) | - | ✅ Running |
|
||||
|
||||
### External Domains (SSL via Let's Encrypt)
|
||||
- **home.schweitz.net** → Tatlock UI
|
||||
@@ -51,6 +54,7 @@
|
||||
- **auth.schweitz.net** → Authentik SSO
|
||||
- **api.schweitz.net** → Core API
|
||||
- **code.schweitz.net** → Code-Server (host service)
|
||||
- **shell.schweitz.net** → Shell In A Box (host service)
|
||||
- **amp.schweitz.net** → AMP Game Server
|
||||
- **housekeeping.schweitz.net** → Home Assistant
|
||||
- **documents.schweitz.net** → Paperless-ngx
|
||||
@@ -287,6 +291,31 @@ Code-Server provides a browser-based Visual Studio Code IDE running directly on
|
||||
|
||||
---
|
||||
|
||||
### Shell In A Box
|
||||
|
||||
Shell In A Box is a web-based terminal emulator that provides secure shell access to the host system through a browser, enabling command-line administration from any device without requiring an SSH client. It runs as a lightweight systemd service on the host, exposing a terminal interface via HTTP that is secured externally through Nginx Proxy Manager with SSL encryption. The service provides a quick way to access the host shell for system administration, troubleshooting, and maintenance tasks when a full IDE like Code-Server is not needed.
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| **Deployment Type** | Host-based systemd service (NOT containerized) |
|
||||
| **Binary Location** | `/usr/bin/shellinaboxd` |
|
||||
| **Service Name** | `shellinabox.service` |
|
||||
| **Access URL (LAN)** | http://192.168.86.149:4200 |
|
||||
| **Access URL (Public)** | https://shell.schweitz.net |
|
||||
| **External Access** | Yes (via NPM reverse proxy with SSL) |
|
||||
| **Port Binding** | 0.0.0.0:4200 (HTTP) |
|
||||
| **User/Group** | `shellinabox:shellinabox` (daemon), login as any system user |
|
||||
| **Restart Policy** | `on-failure` (systemd) |
|
||||
| **Config Location** | `/etc/default/shellinabox` |
|
||||
| **Resource Limits** | None (native host process) |
|
||||
| **GPU Required** | No |
|
||||
| **Dependencies** | NPM (reverse proxy) |
|
||||
| **Authentication** | System login (PAM), SSL via NPM |
|
||||
| **Typical Memory** | ~5-10MB |
|
||||
| **Features** | Web-based terminal, color themes, multiple sessions, copy/paste support |
|
||||
|
||||
---
|
||||
|
||||
## Networking Layer
|
||||
|
||||
### Headscale
|
||||
@@ -739,6 +768,68 @@ Penpot is an open-source design and prototyping platform, serving as a self-host
|
||||
|
||||
---
|
||||
|
||||
### Stable Audio
|
||||
|
||||
Stable Audio Open is an AI audio generation model from Stability AI that creates music and sound effects from text prompts. It generates up to 47 seconds of audio using diffusion techniques, with a Gradio web interface for easy interaction. The service uses GPU acceleration for inference and runs as a locally-built container image, storing model weights in a HuggingFace cache on the SSD.
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| **Image** | `stable-audio-open:local` (locally built) |
|
||||
| **Container Name** | `stable-audio` |
|
||||
| **Access URL (LAN)** | http://192.168.86.149:11500 |
|
||||
| **External Access** | LAN only |
|
||||
| **Port Mapping** | 11500:8000 (Gradio Web UI) |
|
||||
| **Network Mode** | Bridge (docker-dataplane) |
|
||||
| **Restart Policy** | `unless-stopped` |
|
||||
| **Volume Mounts** | `~/docker-data/stable-audio/hf-cache:/root/.cache/huggingface` (SSD - model cache ~6GB) |
|
||||
| **Environment** | `NVIDIA_VISIBLE_DEVICES=all`, `NVIDIA_DRIVER_CAPABILITIES=compute,utility`, `HF_TOKEN=<required>`, `TZ=Europe/Amsterdam` |
|
||||
| **Resource Limits** | Memory: 16GB limit, 8GB reservation |
|
||||
| **GPU Required** | Yes (RTX 2080 Ti - ~6GB VRAM) |
|
||||
| **Dependencies** | NVIDIA Container Toolkit, HuggingFace token |
|
||||
| **Health Check** | `curl -fSs http://localhost:8000/` (60s interval, 300s start_period) |
|
||||
| **Build Location** | `/home/jpmschweitzer/docker-data/stable-audio-open/` |
|
||||
| **Source** | https://github.com/SaladTechnologies/stable-audio-open |
|
||||
| **Features** | Text-to-audio, up to 47s generation, configurable diffusion steps, CFG scale |
|
||||
|
||||
**Prerequisites:**
|
||||
1. Accept model license: https://huggingface.co/stabilityai/stable-audio-open-1.0
|
||||
2. Create HuggingFace token with read access
|
||||
3. Build image: `docker build -t stable-audio-open:local .`
|
||||
|
||||
---
|
||||
|
||||
### TRELLIS
|
||||
|
||||
TRELLIS is Microsoft's 3D model generation system that creates 3D assets from text or image inputs. This deployment uses the low-VRAM fork (0lento/TRELLIS) optimized for 11GB GPUs, using 6-8GB VRAM instead of the standard 16GB requirement. It outputs GLB meshes with UV mappings, suitable for game asset pipelines. The Gradio web interface allows interactive generation with configurable parameters.
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| **Image** | `trellis:local` (locally built) |
|
||||
| **Container Name** | `trellis` |
|
||||
| **Access URL (LAN)** | http://192.168.86.149:11510 |
|
||||
| **External Access** | LAN only |
|
||||
| **Port Mapping** | 11510:7860 (Gradio Web UI) |
|
||||
| **Network Mode** | Bridge (docker-dataplane) |
|
||||
| **Restart Policy** | `unless-stopped` |
|
||||
| **Volume Mounts** | `~/docker-data/trellis/hf-cache:/root/.cache/huggingface` (SSD - model cache ~5GB), `/mnt/media/trellis/outputs:/app/outputs` (HDD - generated GLB files) |
|
||||
| **Environment** | `NVIDIA_VISIBLE_DEVICES=all`, `NVIDIA_DRIVER_CAPABILITIES=compute,utility`, `ATTN_BACKEND=xformers`, `SPCONV_ALGO=native`, `PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True`, `HF_TOKEN=<optional>`, `TZ=Europe/Amsterdam` |
|
||||
| **Resource Limits** | Memory: 16GB limit, 4GB reservation |
|
||||
| **GPU Required** | Yes (RTX 2080 Ti - 6-8GB VRAM with low-VRAM fork) |
|
||||
| **Dependencies** | NVIDIA Container Toolkit |
|
||||
| **Health Check** | `curl -fSs http://localhost:7860/` (60s interval, 300s start_period) |
|
||||
| **Build Location** | `/home/jpmschweitzer/docker-data/trellis/` |
|
||||
| **Source** | https://github.com/0lento/TRELLIS (low-vram branch) |
|
||||
| **Output Format** | GLB with mesh geometry, UV mappings, and textures |
|
||||
| **Features** | Text-to-3D, image-to-3D, GLB export with UVs, Blender-compatible output |
|
||||
|
||||
**Use Case:** Game asset pipeline - generate 3D meshes with UVs, import into Blender, apply custom textures, render isometric sprites.
|
||||
|
||||
**Prerequisites:**
|
||||
1. Create directories: `mkdir -p ~/docker-data/trellis/{hf-cache,config} /mnt/media/trellis/outputs`
|
||||
2. Build image: `cd ~/docker-data/trellis && docker build -t trellis:local .` (~20-30 min)
|
||||
|
||||
---
|
||||
|
||||
### ClamAV
|
||||
|
||||
ClamAV is an open-source antivirus engine running on the host OS, providing virus scanning capabilities for the entire server and accessible via TCP socket for container-based services like Paperless-ngx. It includes automatic virus definition updates via freshclam and can perform both on-demand and real-time scanning. Running on the host provides better security isolation than containerized scanning and allows scanning of the host filesystem directly.
|
||||
@@ -834,6 +925,7 @@ Gitea is a lightweight, self-hosted Git service providing repository hosting, is
|
||||
| **Redis Shared** | redis-shared:6379 | No (internal) | Shared cache/session store |
|
||||
| **NPM** | http://192.168.86.149:81 | Yes (admin) | Reverse proxy admin |
|
||||
| **Code-Server** | https://code.schweitz.net | Yes | Browser-based IDE |
|
||||
| **Shell In A Box** | https://shell.schweitz.net | Yes | Web-based terminal |
|
||||
| **Ollama** | http://192.168.86.149:11434 | No | ML model API |
|
||||
| **Headscale** | http://192.168.86.149:8085 | No | VPN control server |
|
||||
| **Open WebUI** | https://webui.schweitz.net | Yes (SSO) | LLM chat interface |
|
||||
@@ -862,9 +954,13 @@ Gitea is a lightweight, self-hosted Git service providing repository hosting, is
|
||||
|---------|-----------|-------------------|---------|
|
||||
| **Ollama** | Compute, Utility | 2-10GB (model dependent) | LLM inference |
|
||||
| **Jellyfin** | Video Encode/Decode | ~1-2GB (during transcode) | Media transcoding |
|
||||
| **Stable Audio** | Compute | ~6GB | AI audio generation |
|
||||
| **TRELLIS** | Compute | 6-8GB (low-VRAM fork) | 3D model generation |
|
||||
|
||||
**Total VRAM Available:** 11GB (RTX 2080 Ti)
|
||||
|
||||
**Note:** Stable Audio, TRELLIS, and Ollama share GPU. For best results, stop competing services during heavy generation tasks.
|
||||
|
||||
---
|
||||
|
||||
### Storage Distribution
|
||||
@@ -894,6 +990,8 @@ Gitea is a lightweight, self-hosted Git service providing repository hosting, is
|
||||
| **Webber** | `~/docker-data/webber/logs/`, `~/docker-data/webber/sandbox/` | N/A | Logs: ~10MB, Sandbox: variable |
|
||||
| **Penpot** | `~/docker-data/penpot/assets/` | N/A | Assets: variable (uploads, exports) |
|
||||
| **Tatlock UI** | None (stateless) | N/A | ~0MB (static files in container) |
|
||||
| **Stable Audio** | `~/docker-data/stable-audio/hf-cache/` | N/A | Model cache: ~6GB |
|
||||
| **TRELLIS** | `~/docker-data/trellis/hf-cache/` | `/mnt/media/trellis/outputs/` | Model cache: ~5GB, Outputs: variable |
|
||||
|
||||
**SSD Usage (docker-data):** ~6-11GB (configs, caches, databases)
|
||||
**HDD Usage (/mnt/media):** ~2.1TB / 3.6TB (58% used)
|
||||
@@ -943,4 +1041,4 @@ redis-cli -h redis-shared # Redis connection
|
||||
|
||||
---
|
||||
|
||||
*Last Updated: 2026-01-31*
|
||||
*Last Updated: 2026-02-20*
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
# Handover: Add Swap Limits to Containers
|
||||
|
||||
## Problem
|
||||
|
||||
System swap is at 99% (2043/2047 MB) after 60 days uptime. All containers have `mem_swappiness` and `memswap_limit` unset, meaning when they hit their memory ceiling the kernel pushes pages to swap indefinitely instead of applying back-pressure. Over time this exhausts swap.
|
||||
|
||||
## Root Cause Analysis (2026-02-03)
|
||||
|
||||
Per-process swap audit identified these containers as the top offenders:
|
||||
|
||||
| Container | Swap Used | Mem Limit | File |
|
||||
|-----------|-----------|-----------|------|
|
||||
| authentik-worker | ~865 MB (across 5 worker procs) | 1G | `stacks/authentik.yml` |
|
||||
| neo4j | 384 MB | 4G | `stacks/neo4j.yml` |
|
||||
| penpot-backend | 372 MB | 1G | `stacks/penpot.yml` |
|
||||
| authentik-server | 248 MB (gunicorn master+worker) | 512M | `stacks/authentik.yml` |
|
||||
| open-webui | 129 MB | 1G | `stacks/open-webui.yml` |
|
||||
| library-desk | 130 MB | 768M | `stacks/library-desk.yml` |
|
||||
|
||||
Additionally, host-level `clamd` (ClamAV) uses ~410 MB swap but is not managed by Portainer.
|
||||
|
||||
## Required Changes
|
||||
|
||||
For each container listed above, add `memswap_limit` equal to the `memory` limit and set `mem_swappiness: 0` under the top-level service config (not under `deploy`). This is Docker Compose v2 compatible syntax that works alongside v3 deploy blocks.
|
||||
|
||||
### stacks/authentik.yml
|
||||
|
||||
**authentik-server** — add to the service block (sibling to `deploy`, not nested inside it):
|
||||
|
||||
```yaml
|
||||
server:
|
||||
# ... existing config ...
|
||||
mem_swappiness: 0
|
||||
memswap_limit: 512M
|
||||
```
|
||||
|
||||
**authentik-worker** — same pattern:
|
||||
|
||||
```yaml
|
||||
worker:
|
||||
# ... existing config ...
|
||||
mem_swappiness: 0
|
||||
memswap_limit: 1G
|
||||
```
|
||||
|
||||
### stacks/neo4j.yml
|
||||
|
||||
```yaml
|
||||
neo4j:
|
||||
# ... existing config ...
|
||||
mem_swappiness: 0
|
||||
memswap_limit: 4G
|
||||
```
|
||||
|
||||
### stacks/penpot.yml
|
||||
|
||||
**penpot-backend** only (frontend and exporter are not swap offenders):
|
||||
|
||||
```yaml
|
||||
penpot-backend:
|
||||
# ... existing config ...
|
||||
mem_swappiness: 0
|
||||
memswap_limit: 1G
|
||||
```
|
||||
|
||||
### stacks/open-webui.yml
|
||||
|
||||
```yaml
|
||||
open-webui:
|
||||
# ... existing config ...
|
||||
mem_swappiness: 0
|
||||
memswap_limit: 1G
|
||||
```
|
||||
|
||||
### stacks/library-desk.yml
|
||||
|
||||
```yaml
|
||||
library-desk:
|
||||
# ... existing config ...
|
||||
mem_swappiness: 0
|
||||
memswap_limit: 768M
|
||||
```
|
||||
|
||||
## What These Settings Do
|
||||
|
||||
- `memswap_limit: X` — total memory+swap budget. Setting it equal to the memory limit means zero swap allowed.
|
||||
- `mem_swappiness: 0` — tells the kernel to avoid swapping for this container unless absolutely necessary.
|
||||
|
||||
Together, these ensure containers are constrained to their RAM allocation. If they exceed it, the OOM killer handles it properly rather than silently filling swap.
|
||||
|
||||
## Deployment Notes
|
||||
|
||||
- These are runtime container settings — each stack needs to be redeployed in Portainer (or via `docker compose up -d`) for changes to take effect.
|
||||
- After deploying, clear current swap: `sudo swapoff -a && sudo swapon -a`
|
||||
- Monitor with: `cd /mnt/media/Projects/system-management && ./sysmon check memory`
|
||||
- If any container starts OOM-killing after this change, its memory limit may need bumping. The most likely candidate is `authentik-worker` (was using 865 MB swap on top of its 1G RAM limit — may need 1.5G or 2G).
|
||||
|
||||
## ClamAV (Host Service)
|
||||
|
||||
ClamAV (`clamd`) is the single largest swap consumer at 410 MB. It runs as a host service, not a container. To limit it, edit `/etc/clamav/clamd.conf` or the systemd unit to set a memory ceiling. This is outside the scope of portainer-core but noted for completeness.
|
||||
|
||||
## Verification
|
||||
|
||||
After all stacks are redeployed and swap is cleared:
|
||||
|
||||
```bash
|
||||
# Confirm swap is back to healthy levels
|
||||
free -h
|
||||
|
||||
# Run system check
|
||||
cd /mnt/media/Projects/system-management && ./sysmon check memory
|
||||
|
||||
# Verify no container is using swap
|
||||
for cid in $(docker ps -q); do
|
||||
name=$(docker inspect --format '{{.Name}}' "$cid")
|
||||
swap=$(docker stats --no-stream --format '{{.MemUsage}}' "$cid")
|
||||
echo "$name: $swap"
|
||||
done
|
||||
```
|
||||
@@ -0,0 +1,191 @@
|
||||
# Home Assistant MCP Server Setup Guide
|
||||
|
||||
> **Created:** 2026-02-06
|
||||
> **Status:** Infrastructure Ready - Manual Configuration Required
|
||||
|
||||
This guide documents the setup of the Home Assistant MCP (Model Context Protocol) Server integration for use with Claude.ai and Claude Desktop.
|
||||
|
||||
---
|
||||
|
||||
## Current State
|
||||
|
||||
| Component | Status | Details |
|
||||
|-----------|--------|---------|
|
||||
| Home Assistant | Running | https://housekeeping.schweitz.net |
|
||||
| MCP Endpoint | Active | https://housekeeping.schweitz.net/api/mcp |
|
||||
| NPM Proxy | Configured | WebSocket support enabled, SSL via Let's Encrypt |
|
||||
| Authentik | Not in path | Good - allows Home Assistant's built-in IndieAuth |
|
||||
|
||||
### Verified Configuration
|
||||
|
||||
**MCP Endpoint Test Results:**
|
||||
- `GET /api/mcp` → `401 Unauthorized` (expected - requires OAuth)
|
||||
- `OPTIONS /api/mcp` → CORS preflight working
|
||||
- Allowed methods: GET, OPTIONS, POST
|
||||
|
||||
**NPM Configuration (proxy host ID 15):**
|
||||
- Domain: `housekeeping.schweitz.net`
|
||||
- Forward: `localhost:8123`
|
||||
- WebSocket upgrade: Enabled
|
||||
- SSL: Let's Encrypt (certificate ID 18)
|
||||
- Advanced config includes WebSocket headers
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Home Assistant Configuration
|
||||
|
||||
### 1.1 Verify MCP Server Integration is Enabled
|
||||
|
||||
The MCP endpoint is already responding, which suggests the integration may already be installed. Verify in Home Assistant:
|
||||
|
||||
1. Go to **Settings** → **Devices & Services**
|
||||
2. Look for "Model Context Protocol Server" or "MCP Server"
|
||||
3. If not present, click **Add Integration** and search for "MCP"
|
||||
|
||||
### 1.2 Expose Entities to Voice Assistants (Required)
|
||||
|
||||
The MCP server only exposes entities that are enabled for voice assistants. You must configure which entities Claude can access:
|
||||
|
||||
1. Go to **Settings** → **Voice assistants**
|
||||
2. Click on **Assist** (the default assistant)
|
||||
3. Go to the **Expose** tab
|
||||
4. Enable the entities you want Claude to control:
|
||||
- **Lights** - for lighting control
|
||||
- **Switches** - for on/off devices
|
||||
- **Climate** - for thermostats and HVAC
|
||||
- **Covers** - for blinds, garage doors, etc.
|
||||
- **Scenes** - for activating predefined scenes
|
||||
- **Scripts** - for running custom automations
|
||||
- **Media players** - for controlling media devices
|
||||
- **Sensors** - for reading sensor values (read-only)
|
||||
|
||||
**Recommendation:** Start with a few entities to test, then expand once connectivity is verified.
|
||||
|
||||
### 1.3 (Optional) Generate Long-Lived Access Token
|
||||
|
||||
Only needed if using clients that don't support OAuth:
|
||||
|
||||
1. Click your user profile (your name in the sidebar)
|
||||
2. Scroll down to **Long-lived access tokens**
|
||||
3. Click **Create Token**
|
||||
4. Name it (e.g., "Claude MCP Token")
|
||||
5. Copy and save the token securely - it won't be shown again
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Claude.ai Configuration
|
||||
|
||||
### For Claude.ai (Web Interface)
|
||||
|
||||
1. Go to [claude.ai](https://claude.ai) and sign in
|
||||
2. Navigate to **Settings** → **Integrations** or **MCP Servers**
|
||||
3. Click **Add Remote MCP Server**
|
||||
4. Enter the following configuration:
|
||||
- **Server URL:** `https://housekeeping.schweitz.net/api/mcp`
|
||||
- **Name:** Home Assistant (or your preferred name)
|
||||
5. Click **Connect** or **Add**
|
||||
6. You'll be redirected to Home Assistant for OAuth authentication
|
||||
7. Log in to Home Assistant and authorize Claude
|
||||
8. Return to Claude.ai - the connection should now be active
|
||||
|
||||
### For Claude Desktop
|
||||
|
||||
1. Open Claude Desktop application
|
||||
2. Go to **Settings** or **Preferences**
|
||||
3. Navigate to **MCP Servers** or **Integrations**
|
||||
4. Click **Add Remote Server**
|
||||
5. Enter:
|
||||
- **URL:** `https://housekeeping.schweitz.net/api/mcp`
|
||||
6. Click **Connect**
|
||||
7. A browser window will open for Home Assistant authentication
|
||||
8. Log in and authorize the connection
|
||||
9. Return to Claude Desktop - the server should appear as connected
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Verification
|
||||
|
||||
### Test MCP Endpoint Accessibility
|
||||
|
||||
From command line:
|
||||
```bash
|
||||
# Should return 401 Unauthorized (expected without auth)
|
||||
curl -I https://housekeeping.schweitz.net/api/mcp
|
||||
|
||||
# More detailed test
|
||||
curl -v https://housekeeping.schweitz.net/api/mcp
|
||||
```
|
||||
|
||||
### Test Claude Integration
|
||||
|
||||
After connecting Claude to Home Assistant, try these commands:
|
||||
|
||||
1. **List devices:** "What Home Assistant devices are available?"
|
||||
2. **Check state:** "What's the current state of the living room lights?"
|
||||
3. **Control device:** "Turn on the living room lights"
|
||||
4. **Get sensor value:** "What's the current temperature inside?"
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
| Issue | Possible Cause | Solution |
|
||||
|-------|---------------|----------|
|
||||
| Connection timeout | Network/proxy issue | Check NPM logs, verify WebSocket support |
|
||||
| 401 Unauthorized | OAuth not completed | Re-authenticate through Claude settings |
|
||||
| No devices visible | Entities not exposed | Enable entities in Voice assistants → Assist → Expose |
|
||||
| Commands fail | Entity not exposed for control | Check entity exposure settings in Home Assistant |
|
||||
|
||||
---
|
||||
|
||||
## Technical Details
|
||||
|
||||
### How MCP Authentication Works
|
||||
|
||||
Home Assistant uses IndieAuth (an OAuth 2.0-based protocol) for MCP authentication:
|
||||
|
||||
1. Claude identifies as client ID `https://claude.ai`
|
||||
2. Home Assistant validates the request and presents login
|
||||
3. User authenticates and authorizes Claude
|
||||
4. Home Assistant issues an access token
|
||||
5. Claude uses the token for subsequent API calls
|
||||
|
||||
### Protocol
|
||||
|
||||
The MCP Server uses "Streamable HTTP" protocol:
|
||||
- Requests: POST with JSON-RPC 2.0 payload
|
||||
- Responses: Server-Sent Events (SSE) or direct JSON
|
||||
|
||||
### NPM Configuration Details
|
||||
|
||||
Current advanced config for `housekeeping.schweitz.net`:
|
||||
```nginx
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
```
|
||||
|
||||
If you experience SSE streaming issues, add:
|
||||
```nginx
|
||||
proxy_buffering off;
|
||||
proxy_cache off;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Security Notes
|
||||
|
||||
1. **Authentik is NOT in front of Home Assistant** - This is intentional and required for IndieAuth OAuth to work directly with Claude
|
||||
2. **Entity exposure is granular** - Only expose entities you want Claude to access
|
||||
3. **OAuth tokens are temporary** - Re-authentication may be required periodically
|
||||
4. **All traffic is encrypted** - SSL/TLS via Let's Encrypt
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- [Home Assistant MCP Documentation](https://www.home-assistant.io/integrations/mcp_server/)
|
||||
- [Model Context Protocol Specification](https://spec.modelcontextprotocol.io/)
|
||||
- [Claude MCP Integration](https://docs.anthropic.com/claude/docs/mcp)
|
||||
|
||||
---
|
||||
|
||||
*Last Updated: 2026-02-06*
|
||||
@@ -0,0 +1,102 @@
|
||||
# Tatlock Claudification Handover - portainer-core
|
||||
|
||||
## Context
|
||||
|
||||
Tatlock (the butler) is being upgraded to use Claude as its primary LLM backend instead of Ollama. This requires infrastructure changes to support the new configuration.
|
||||
|
||||
**Parent Issue:** See `/mnt/media/Projects/tatlock/PROJECT_CLAUDIFICATION.md`
|
||||
|
||||
## Impact on portainer-core
|
||||
|
||||
Portainer-core manages Docker Swarm stacks. The Tatlock stack needs updated configuration.
|
||||
|
||||
## Required Changes
|
||||
|
||||
### Priority: High (Required for Claude backend)
|
||||
|
||||
- [ ] **Update `stacks/agents.yml`** (or wherever Tatlock is defined)
|
||||
|
||||
Add new environment variables:
|
||||
```yaml
|
||||
services:
|
||||
tatlock:
|
||||
environment:
|
||||
# Anthropic Configuration (Claude - preferred backend)
|
||||
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
|
||||
- ANTHROPIC_MODEL=claude-sonnet-4-20250514
|
||||
- PREFER_CLOUD_BACKEND=true
|
||||
# Existing Ollama config remains as fallback
|
||||
- OLLAMA_HOST=http://ollama:11434
|
||||
- OLLAMA_DEFAULT_MODEL=mistral-nemo:latest
|
||||
```
|
||||
|
||||
- [ ] **Configure secrets management**
|
||||
|
||||
Options:
|
||||
1. **Docker secrets** (recommended for Swarm):
|
||||
```yaml
|
||||
secrets:
|
||||
anthropic_api_key:
|
||||
external: true
|
||||
services:
|
||||
tatlock:
|
||||
secrets:
|
||||
- anthropic_api_key
|
||||
environment:
|
||||
- ANTHROPIC_API_KEY_FILE=/run/secrets/anthropic_api_key
|
||||
```
|
||||
|
||||
2. **Environment file** (simpler but less secure):
|
||||
```yaml
|
||||
services:
|
||||
tatlock:
|
||||
env_file:
|
||||
- ./secrets/tatlock.env
|
||||
```
|
||||
|
||||
- [ ] **Update `CONTAINERS.md`**
|
||||
- Document new environment variables
|
||||
- Note Claude as preferred backend with Ollama fallback
|
||||
- Update any API documentation
|
||||
|
||||
### Priority: Medium (Phase 2 - MCP Server)
|
||||
|
||||
- [ ] **Add `tatlock-mcp` service definition** (when Phase 2 is ready)
|
||||
```yaml
|
||||
tatlock-mcp:
|
||||
image: git.schweitz.net/jpmschweitzer/tatlock:latest
|
||||
command: ["python", "-m", "src.mcp.server"]
|
||||
ports:
|
||||
- "8778:8778"
|
||||
environment:
|
||||
- MCP_AUTH_TOKEN=${MCP_AUTH_TOKEN}
|
||||
# ... other config
|
||||
```
|
||||
|
||||
### Priority: Low (Optimization)
|
||||
|
||||
- [ ] **Review resource limits**
|
||||
- Claude backend may have different resource profile than Ollama
|
||||
- Monitor memory/CPU after deployment
|
||||
- Adjust limits if needed
|
||||
|
||||
## Testing
|
||||
|
||||
After stack update:
|
||||
|
||||
```bash
|
||||
# Check Tatlock logs for backend selection
|
||||
docker service logs tatlock_tatlock 2>&1 | grep -E "claude|backend"
|
||||
|
||||
# Should see:
|
||||
# model_backend_configured backend=claude model=claude-sonnet-4-20250514
|
||||
# OR (if no API key):
|
||||
# claude_health_check_skipped reason=no_api_key
|
||||
# model_backend_configured backend=ollama
|
||||
```
|
||||
|
||||
## Timeline
|
||||
|
||||
- **Blocking:** Yes - required for production Claude deployment
|
||||
- **When to implement:** When ANTHROPIC_API_KEY is available
|
||||
- **Effort:** ~1 hour for stack updates, ~30 min for secrets setup
|
||||
@@ -38,6 +38,8 @@ review the http://core-api/docs openapi documentation for infrastructure managem
|
||||
| **Gitea** | `gitea.yml` | 3002, 2222 | No | Git repository hosting (includes PostgreSQL) |
|
||||
| **Samba** | `samba.yml` | 139, 445 | No | Network file sharing |
|
||||
| **Home Assistant** | `home-assistant.yml` | 8123 | No | Smart home automation platform |
|
||||
| **Stable Audio** | `stable-audio.yml` | 11500 | **Yes** | AI audio generation (local build) |
|
||||
| **TRELLIS** | `trellis.yml` | 11510 | **Yes** | 3D model generation (local build) |
|
||||
|
||||
## Port Allocation
|
||||
|
||||
@@ -61,6 +63,8 @@ review the http://core-api/docs openapi documentation for infrastructure managem
|
||||
|
||||
### ML/API Services (11000+)
|
||||
- 11434: Ollama
|
||||
- 11500: Stable Audio Open
|
||||
- 11510: TRELLIS (3D model generation)
|
||||
|
||||
### Network Services
|
||||
- 80: HTTP (NPM reverse proxy)
|
||||
@@ -87,6 +91,8 @@ All stacks follow the dual-disk strategy:
|
||||
Stacks requiring GPU access (marked with **Yes** above):
|
||||
- `ollama.yml` - ML model inference
|
||||
- `jellyfin.yml` - Hardware transcoding
|
||||
- `stable-audio.yml` - AI audio generation (~6GB VRAM)
|
||||
- `trellis.yml` - 3D model generation (~6-8GB VRAM)
|
||||
|
||||
**Prerequisites:**
|
||||
- NVIDIA Container Toolkit installed
|
||||
|
||||
@@ -25,6 +25,10 @@ services:
|
||||
- API_HOST=0.0.0.0
|
||||
- API_PORT=8000
|
||||
# Ollama (shared service)
|
||||
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
|
||||
- ANTHROPIC_MODEL=claude-sonnet-4-20250514
|
||||
- PREFER_CLOUD_BACKEND=truec
|
||||
# Ollama (shared service)
|
||||
- OLLAMA_HOST=http://ollama:11434
|
||||
- OLLAMA_DEFAULT_MODEL=mistral-nemo:latest
|
||||
- OLLAMA_TIMEOUT=120
|
||||
@@ -97,6 +101,10 @@ services:
|
||||
- CORS_ORIGINS=["*"]
|
||||
- CORS_METHODS=["*"]
|
||||
- CORS_HEADERS=["*"]
|
||||
# Ollama (shared service)
|
||||
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
|
||||
- ANTHROPIC_MODEL=claude-sonnet-4-20250514
|
||||
- PREFER_CLOUD_BACKEND=truec
|
||||
# Ollama (shared service) - LLM Models hot in VRAM
|
||||
- OLLAMA_URL=http://ollama:11434
|
||||
- OLLAMA_AGENT_MODEL=mistral-nemo:latest
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@ services:
|
||||
- AUTHENTIK_CORE_API_TOKEN=${AUTHENTIK_CORE_API_TOKEN}
|
||||
|
||||
# HOME ASSITANT VARIABLES
|
||||
- HOMEASSISTANT_URL=http://home-assistant:8123
|
||||
- HOMEASSISTANT_URL=http://192.168.86.149:8123
|
||||
- HOMEASSISTANT_TOKEN=${HOMEASSISTANT_TOKEN}
|
||||
|
||||
# AI SYSTEM VARIABLES
|
||||
|
||||
+45
-10
@@ -1,7 +1,7 @@
|
||||
version: '3.8'
|
||||
|
||||
# Home Assistant - Smart Home Automation Platform
|
||||
# Port: 8123 (Home Assistant default)
|
||||
# Ports: 8123 (Home Assistant), 5580 (Matter Server WebSocket)
|
||||
# GPU: No
|
||||
# Storage: SSD (config and database)
|
||||
|
||||
@@ -10,8 +10,7 @@ services:
|
||||
image: ghcr.io/home-assistant/home-assistant:stable
|
||||
container_name: home-assistant
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8123:8123"
|
||||
network_mode: host
|
||||
volumes:
|
||||
# Config on SSD (includes database, automations, scripts)
|
||||
- /home/jpmschweitzer/docker-data/home-assistant/config:/config
|
||||
@@ -19,8 +18,6 @@ services:
|
||||
- TZ=Europe/Amsterdam
|
||||
# Privileged mode for USB device access (Z-Wave, Zigbee dongles)
|
||||
privileged: true
|
||||
networks:
|
||||
- docker-dataplane
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "curl -fSs http://localhost:8123/manifest.json || exit 1"]
|
||||
interval: 30s
|
||||
@@ -32,10 +29,34 @@ services:
|
||||
limits:
|
||||
memory: 1G
|
||||
|
||||
networks:
|
||||
docker-dataplane:
|
||||
external: true
|
||||
name: docker-dataplane
|
||||
matter-server:
|
||||
image: ghcr.io/matter-js/python-matter-server:stable
|
||||
container_name: matter-server
|
||||
restart: unless-stopped
|
||||
network_mode: host
|
||||
security_opt:
|
||||
- apparmor:unconfined
|
||||
volumes:
|
||||
# Matter fabric data on SSD (BACK UP before upgrades - contains device credentials)
|
||||
- /home/jpmschweitzer/docker-data/matter-server/data:/data
|
||||
# D-Bus socket for Bluetooth commissioning
|
||||
- /run/dbus:/run/dbus:ro
|
||||
environment:
|
||||
- TZ=Europe/Amsterdam
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "curl -fSs http://localhost:5580 || exit 1"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 60s
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 512M
|
||||
|
||||
# Note: Both services use network_mode: host for LAN device discovery (mDNS, SSDP, Matter)
|
||||
# Home Assistant reaches Matter Server at ws://localhost:5580/ws
|
||||
# Other containers should reach HA via http://192.168.86.149:8123
|
||||
|
||||
# Setup Instructions:
|
||||
# 1. Create config directory:
|
||||
@@ -64,7 +85,7 @@ networks:
|
||||
# NPM Configuration:
|
||||
# Domain: housekeeping.schweitz.net
|
||||
# Scheme: http
|
||||
# Forward Hostname/IP: home-assistant
|
||||
# Forward Hostname/IP: 192.168.86.149
|
||||
# Forward Port: 8123
|
||||
# Websockets Support: ENABLED (required for HA)
|
||||
# SSL: Let's Encrypt
|
||||
@@ -77,3 +98,17 @@ networks:
|
||||
# - 172.16.0.0/12
|
||||
# - 192.168.0.0/16
|
||||
# - 10.0.0.0/8
|
||||
#
|
||||
# Matter Server Setup:
|
||||
# 1. Create data directory:
|
||||
# mkdir -p /home/jpmschweitzer/docker-data/matter-server/data
|
||||
#
|
||||
# 2. After deploying, connect from Home Assistant:
|
||||
# Settings > Devices & Services > Add Integration > Matter
|
||||
# Deselect "Install the official Matter Server app"
|
||||
# Enter URL: ws://localhost:5580/ws
|
||||
#
|
||||
# 3. Commission devices via the HA Companion app (uses phone Bluetooth)
|
||||
# or add --bluetooth-adapter 0 to the matter-server command for local BT
|
||||
#
|
||||
# Source: https://github.com/matter-js/python-matter-server
|
||||
|
||||
+4
-4
@@ -24,10 +24,10 @@ services:
|
||||
- NVIDIA_DRIVER_CAPABILITIES=all
|
||||
# Process requests sequentially to avoid batch overflow panics
|
||||
- OLLAMA_NUM_PARALLEL=1
|
||||
# Keep models loaded in VRAM (don't unload after idle)
|
||||
- OLLAMA_KEEP_ALIVE=-1
|
||||
# Load multiple models concurrently (mistral-nemo + nomic-embed-text)
|
||||
- OLLAMA_MAX_LOADED_MODELS=2
|
||||
# Unload LLMs after 5 minutes idle (keeps VRAM free for other services)
|
||||
- OLLAMA_KEEP_ALIVE=5m
|
||||
# Only keep one model loaded at a time (embedding model stays, LLMs swap)
|
||||
- OLLAMA_MAX_LOADED_MODELS=1
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "curl -fSs http://localhost:11434/api/tags || exit 1"]
|
||||
interval: 30s
|
||||
|
||||
+3
-3
@@ -78,9 +78,9 @@ services:
|
||||
# Redis (shared, DB 10)
|
||||
PENPOT_REDIS_URI: redis://redis-shared:6379/10
|
||||
|
||||
# Assets storage
|
||||
PENPOT_ASSETS_STORAGE_BACKEND: assets-fs
|
||||
PENPOT_STORAGE_ASSETS_FS_DIRECTORY: /opt/data/assets
|
||||
# Assets storage (updated for Penpot 2.11+)
|
||||
PENPOT_OBJECTS_STORAGE_BACKEND: fs
|
||||
PENPOT_OBJECTS_STORAGE_FS_DIRECTORY: /opt/data/assets
|
||||
|
||||
# Secret key (512-bit base64)
|
||||
PENPOT_SECRET_KEY: +g+fSbAzBWVA2gE8ZnJUcpgq9L1BCqtuB+h9w73iF9qcgxhjMF1QU23XUjQ5ZdxpPmwoyuuQEm/frtKUV2M6pA==
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
version: '3.8'
|
||||
|
||||
# Stable Audio Open - AI Audio Generation
|
||||
# Phase: ML Infrastructure
|
||||
# Ports: 8000 (Gradio Web UI)
|
||||
# GPU: YES - Requires NVIDIA Container Toolkit (8GB+ VRAM)
|
||||
# Storage: SSD recommended for model cache
|
||||
# Image: Built locally from https://github.com/SaladTechnologies/stable-audio-open
|
||||
|
||||
services:
|
||||
stable-audio:
|
||||
image: stable-audio-open:local
|
||||
container_name: stable-audio
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "11500:8000" # Gradio Web UI (internal only)
|
||||
volumes:
|
||||
# HuggingFace cache for model weights (~6GB)
|
||||
- /home/jpmschweitzer/docker-data/stable-audio/hf-cache:/root/.cache/huggingface
|
||||
environment:
|
||||
- TZ=Europe/Amsterdam
|
||||
- NVIDIA_VISIBLE_DEVICES=all
|
||||
- NVIDIA_DRIVER_CAPABILITIES=compute,utility
|
||||
- HF_TOKEN=${HF_TOKEN}
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "curl -fSs http://localhost:8000/ || exit 1"]
|
||||
interval: 60s
|
||||
timeout: 30s
|
||||
retries: 3
|
||||
start_period: 300s # Model download + load takes time
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 16G
|
||||
reservations:
|
||||
memory: 8G
|
||||
devices:
|
||||
- driver: nvidia
|
||||
count: 1
|
||||
capabilities: [gpu]
|
||||
networks:
|
||||
- docker-dataplane
|
||||
|
||||
networks:
|
||||
docker-dataplane:
|
||||
external: true
|
||||
name: docker-dataplane
|
||||
|
||||
# GPU Requirements:
|
||||
# - RTX 2080 Ti (11GB VRAM) - minimum viable, may struggle with long generations
|
||||
# - Recommended: 16GB+ VRAM for reliable 47s audio generation
|
||||
# - NVIDIA Container Toolkit must be installed
|
||||
#
|
||||
# IMPORTANT: GPU Contention
|
||||
# - This service shares GPU with Ollama and Jellyfin
|
||||
# - Consider stopping Ollama when generating audio for better VRAM availability
|
||||
# - Monitor with: watch -n 1 nvidia-smi
|
||||
#
|
||||
# Prerequisites:
|
||||
# 1. Build image: cd /home/jpmschweitzer/docker-data/stable-audio-open && docker build -t stable-audio-open:local .
|
||||
# 2. Create HuggingFace token: https://huggingface.co/settings/tokens (read access)
|
||||
# 3. Accept model license: https://huggingface.co/stabilityai/stable-audio-open-1.0
|
||||
# 4. Create data directories:
|
||||
# mkdir -p /home/jpmschweitzer/docker-data/stable-audio/{hf-cache,output}
|
||||
#
|
||||
# After Deployment:
|
||||
# 1. Set HF_TOKEN in Portainer environment variables
|
||||
# 2. Deploy stack via Portainer
|
||||
# 3. First run downloads model weights (~6GB) - be patient
|
||||
# 4. Verify GPU access: docker exec stable-audio nvidia-smi
|
||||
# 5. Access Web UI: http://tower-of-joy:11500 or http://audio.schweitz.internal (via NPM)
|
||||
#
|
||||
# NPM Configuration (audio.schweitz.internal):
|
||||
# - Domain: audio.schweitz.internal
|
||||
# - Scheme: http
|
||||
# - Forward Hostname: stable-audio (or tower-of-joy)
|
||||
# - Forward Port: 11500
|
||||
# - Block Common Exploits: Yes
|
||||
# - Websockets Support: Yes (required for Gradio)
|
||||
#
|
||||
# API Usage (Gradio API):
|
||||
# curl -X POST http://audio.schweitz.internal/api/predict \
|
||||
# -H "Content-Type: application/json" \
|
||||
# -d '{"data": ["epic orchestral music, cinematic", 30, 100, 7]}'
|
||||
# Parameters: [prompt, duration_seconds, diffusion_steps, cfg_scale]
|
||||
#
|
||||
# Rebuilding Image:
|
||||
# cd /home/jpmschweitzer/docker-data/stable-audio-open
|
||||
# git pull
|
||||
# docker build -t stable-audio-open:local .
|
||||
@@ -0,0 +1,116 @@
|
||||
version: '3.8'
|
||||
|
||||
# TRELLIS 1 - 3D Model Generation (Low-VRAM Fork)
|
||||
# Purpose: Generate 3D meshes with UV mappings for game asset pipeline
|
||||
# Ports: 11510 (Gradio Web UI)
|
||||
# GPU: YES - Optimized for 11GB VRAM (RTX 2080 Ti)
|
||||
# Storage: SSD for model cache, HDD for GLB outputs
|
||||
# Image: Built locally from /home/jpmschweitzer/docker-data/trellis/
|
||||
|
||||
services:
|
||||
trellis:
|
||||
image: trellis:local
|
||||
container_name: trellis
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "11510:7860" # Gradio Web UI
|
||||
volumes:
|
||||
# SSD: HuggingFace model cache (~5GB)
|
||||
- /home/jpmschweitzer/docker-data/trellis/hf-cache:/root/.cache/huggingface
|
||||
# HDD: Generated GLB files
|
||||
- /mnt/media/trellis/outputs:/app/outputs
|
||||
# Entrypoint script (patches Gradio bugs without rebuilding image)
|
||||
- /home/jpmschweitzer/docker-data/trellis/entrypoint.sh:/app/entrypoint.sh:ro
|
||||
command: ["bash", "/app/entrypoint.sh"]
|
||||
environment:
|
||||
- TZ=Europe/Amsterdam
|
||||
- NVIDIA_VISIBLE_DEVICES=all
|
||||
- NVIDIA_DRIVER_CAPABILITIES=compute,utility
|
||||
# VRAM Optimization (for 11GB card)
|
||||
- ATTN_BACKEND=xformers
|
||||
- SPCONV_ALGO=native
|
||||
- PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True
|
||||
# Gradio must bind to 0.0.0.0 inside Docker
|
||||
- GRADIO_SERVER_NAME=0.0.0.0
|
||||
# HuggingFace token for model downloads (set in Portainer)
|
||||
- HF_TOKEN=${HF_TOKEN:-}
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "curl -fSs http://localhost:7860/ || exit 1"]
|
||||
interval: 60s
|
||||
timeout: 30s
|
||||
retries: 3
|
||||
start_period: 300s # Model download + load time
|
||||
memswap_limit: 20G
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 20G
|
||||
reservations:
|
||||
memory: 4G
|
||||
devices:
|
||||
- driver: nvidia
|
||||
count: 1
|
||||
capabilities: [gpu]
|
||||
labels:
|
||||
- "com.centurylinklabs.watchtower.enable=false" # Manual updates for local builds
|
||||
networks:
|
||||
- docker-dataplane
|
||||
|
||||
networks:
|
||||
docker-dataplane:
|
||||
external: true
|
||||
name: docker-dataplane
|
||||
|
||||
# =============================================================================
|
||||
# PREREQUISITES
|
||||
# =============================================================================
|
||||
#
|
||||
# 1. Build the Docker image first:
|
||||
# cd /home/jpmschweitzer/docker-data/trellis
|
||||
# docker build -t trellis:local .
|
||||
# (Takes ~20-30 minutes for CUDA compilation)
|
||||
#
|
||||
# 2. Directories are already created:
|
||||
# /home/jpmschweitzer/docker-data/trellis/hf-cache (SSD - model cache)
|
||||
# /mnt/media/trellis/outputs (HDD - generated GLB files)
|
||||
#
|
||||
# =============================================================================
|
||||
# AFTER DEPLOYMENT
|
||||
# =============================================================================
|
||||
#
|
||||
# 1. Verify GPU access:
|
||||
# docker exec trellis nvidia-smi
|
||||
#
|
||||
# 2. Check logs:
|
||||
# docker logs trellis
|
||||
#
|
||||
# 3. Access Web UI:
|
||||
# http://tower-of-joy:11510
|
||||
# http://192.168.86.149:11510
|
||||
#
|
||||
# 4. Monitor VRAM during generation:
|
||||
# watch -n 1 nvidia-smi
|
||||
#
|
||||
# =============================================================================
|
||||
# USAGE - GAME ASSET PIPELINE
|
||||
# =============================================================================
|
||||
#
|
||||
# 1. Open Gradio UI at http://tower-of-joy:11510
|
||||
# 2. Upload reference image or enter text prompt
|
||||
# 3. Generate 3D model (uses 6-8GB VRAM)
|
||||
# 4. Download GLB file from outputs
|
||||
# 5. Import GLB into Blender (File > Import > glTF)
|
||||
# 6. Apply custom textures, set up isometric camera
|
||||
# 7. Render at 1024x1024, downsample to 64x64 tile sprites
|
||||
#
|
||||
# =============================================================================
|
||||
# GPU CONTENTION NOTE
|
||||
# =============================================================================
|
||||
#
|
||||
# TRELLIS shares the RTX 2080 Ti with Ollama and Jellyfin.
|
||||
# For best results during complex generations:
|
||||
# docker stop ollama
|
||||
# # Run TRELLIS generation
|
||||
# docker start ollama
|
||||
#
|
||||
# =============================================================================
|
||||
Reference in New Issue
Block a user