Skip to content

Latest commit

 

History

15 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Sparky

Vue 3 + Vite web interface for an NVIDIA DGX Spark. Runs as a Docker container with nginx, on the box itself.

Six tabs, one responsive codebase — the phone and the desktop render the same components.

Features

  • Chat — streaming chat with local Ollama models, with three things folded in:
    • ⚛ Quantum steering — a flag, not a separate mode: each turn is preceded by a live measurement from an attached QCicada hardware RNG, shown inline
    • Saved conversations — server-side, restored with their model and settings
    • Image input — on the models that report a vision capability
  • Agent — Claude Code on the box, with a persona picker. Can edit this repo.
  • Goose — research agent with web search
  • Image Generation — SDXL (Pony, NoobAI, Illustrious) and Flux via ComfyUI
  • Manage — Docker/systemd control, live system stats, and a torrent client
  • Overview — hardware, live model list, service links
  • Installable to an iOS home screen as a PWA

Prerequisites

Required services

Service Port Needed for
Ollama 11434 Chat, model list
ComfyUI 8188 Image generation
Telemetry API 8006 Live stats
QCicada QRNG 8007 Quantum steering (optional)
Torrent API + aria2 8009, 6800 Torrents (optional)

Networking

Both containers run with network_mode: host and reach every service over the host's own loopback. This is deliberate: Ollama binds 127.0.0.1 only, so a bridged container cannot reach it at all.

Do not set OLLAMA_ORIGINS=*. Ollama and ComfyUI reject non-localhost origins with 403, and nginx strips the Origin header on those two routes instead — which vouches only for requests arriving through this proxy, rather than opening both services to every origin from every client on the box.

Quick Start

1. Clone Repository

git clone https://github.com/vybe/sparky
cd sparky

2. Configure Deployment

Copy the example files:

cp .env.example .env
chmod +x deploy.sh

Edit .env with your server details:

DGX_HOST=your-server-ip          # Your DGX/server IP or hostname
DGX_USER=your-username           # SSH username
DGX_PASS=your-password          # SSH password (or use SSH keys)
REMOTE_DIR=/home/$USER/dgx-web-ui  # Optional: custom deployment path

3. Set the UI password

Required. See Access control below for why this is not optional.

SPARKY_AUTH_USER=your-username
SPARKY_AUTH_PASS=use-a-long-random-value

Service links need no configuration — they are built from window.location.hostname, so the app works over the LAN, over a VPN, or through a tunnel unchanged. Hardware specs live in src/components/Dashboard.vue; the model list is read live from Ollama.

4. Verify Service Ports

Ensure these services are accessible on your server:

Service Default Port How to Check
Ollama 11434 curl http://localhost:11434/api/version
ComfyUI 8188 curl http://localhost:8188/system_stats
Telemetry 8006 curl http://localhost:8006/stats
QCicada QRNG 8007 curl http://localhost:8007/health

Sparky reaches all of these over the host's loopback, so none of them needs to be exposed on Sparky's account.

On the reference deployment several are nonetheless bound to 0.0.0.0 — ComfyUI (8188), the telemetry API (8006) and the QRNG service (8007) — because they are also used directly, and the Overview tab links to them. That is a deliberate choice on a VPN-restricted box, not an accident, but it does mean they are reachable from the LAN without Sparky's Basic auth. Only the QRNG service has authentication of its own. Bind them to 127.0.0.1 if you do not want that.

The backend (3081) is the exception and is loopback-only by design: it exposes container control and shell exec.

If your ports differ, update config.dgx.js and nginx.conf accordingly.

5. Deploy

./deploy.sh deploy

The web UI will be available at:

  • Web UI: http://your-server-ip:3080
  • API: http://your-server-ip:3081/docs

6. Mobile

Nothing to switch on — the layout adapts below 768px. ?tab=<id> deep-links a tab and ?agent=<id> also picks an agent persona.

The UI requires HTTP Basic auth (see Access control), so on a phone either enter the credentials when prompted or bookmark http://user:pass@host:3080/ — both work.

On iOS, use Safari → Share → Add to Home Screen for a standalone app experience.

Configuration Checklist

Before deploying, ensure you've configured:

  • .env has DGX_HOST / DGX_USER and SPARKY_AUTH_USER / SPARKY_AUTH_PASS
  • deploy.sh executable
  • Hardware specs in src/components/Dashboard.vue match your box
  • Service ports reachable on the host's loopback
  • Only port 3080 reachable from the network

Customizing for Your System

📖 See CONFIGURATION.md for the complete configuration guide covering:

  • Network IPs and VPN setup
  • Hardware specifications display
  • Model lists (LLM, image, video, audio)
  • Service ports and links
  • Backend API customization
  • Docker Compose settings

For advanced customization, see SETUP.md

Local Development

For local development with API tunneling:

# Install dependencies
npm install

# Run dev server
npm run dev
# Open http://localhost:3000

The development server expects services to be accessible on localhost ports (typically via SSH tunneling).

Configuration

Runtime config is loaded from window.DGX_CONFIG (defined in public/config.js or config.dgx.js).

Local development (public/config.js):

window.DGX_CONFIG = {
  COMFYUI_URL: '/comfyui',
  OLLAMA_URL: '/ollama',
  QRNG_URL: '/qrng',
  API_URL: '/api',
  TELEMETRY_URL: '/telemetry',
  APP_NAME: 'Sparky',
  VERSION: '2.0.0'
};

Production (config.dgx.js): the same same-origin paths, proxied by nginx.

src/config.js resolves each one to an absolute URL against location.origin. That is deliberate: a relative fetch resolves against the document URL, and Chrome refuses to construct a Request from a URL carrying credentials — so http://user:pass@host/ would otherwise break every request in the app.

Architecture

Frontend

  • Vue 3 with Composition API
  • Vite 7 for build tooling
  • Tailwind CSS 4 for styling
  • PWA support (manifest + service worker)

Backend API

  • FastAPI (Python)
  • Docker container management
  • System monitoring
  • Claude Code integration

Deployment

  • Multi-stage Docker build
  • Nginx for static file serving
  • Docker Compose for orchestration

Deployment Commands

./deploy.sh sync      # Sync files only
./deploy.sh build     # Rebuild Docker image
./deploy.sh start     # Start containers
./deploy.sh stop      # Stop containers
./deploy.sh restart   # Restart containers
./deploy.sh logs      # View container logs
./deploy.sh status    # Check container status
./deploy.sh deploy    # Full deployment (sync + build + start)

Service Ports

Service Default Port Purpose
Web UI 3080 nginx — the only port that should be reachable from the network
API 3081 Backend; binds 127.0.0.1 only (container control + shell exec)
ComfyUI 8188 Image generation
Ollama 11434 LLM inference
QCicada QRNG 8007 Quantum steering
Telemetry 8006 System stats

Documentation

Document Purpose
GETTING_STARTED.md Overview and preparation checklist
CONFIGURATION.md Complete configuration guide
SETUP.md Advanced setup and customization
SECURITY.md Security best practices and policies
CONTRIBUTING.md How to contribute to this project

Troubleshooting

Everything returns 401

Expected without credentials. If it happens with them, check SPARKY_AUTH_USER / SPARKY_AUTH_PASS in .env and redeploy — the credential is hashed at deploy time, so editing .env alone changes nothing.

Chat returns 403

nginx is not stripping the Origin header on /ollama/. Ollama rejects any non-localhost origin; curl succeeds (no Origin) while the browser fails. Fix the proxy — do not set OLLAMA_ORIGINS=*, which opens Ollama to every origin from every client on the box.

UI loads but is completely empty

Opened as http://user:pass@host/ against a build older than 2026-08-02. Relative fetches threw because the document URL carried credentials. Redeploy.

Images not generating

Check ComfyUI is running:

sudo docker ps | grep comfyui
sudo docker logs comfyui --tail 50

Restart if needed:

sudo docker restart comfyui

(removed) Voice Chat

The Voice tab was removed on 2026-08-02 — the ultravox-vllm container has been Exited(137) since early 2026. Chatterbox TTS still runs on :8004 if it is ever revived. Historical note:

sudo docker ps | grep ultravox
sudo docker restart ultravox-vllm

Container Management Not Loading

Backend API must be running:

sudo docker ps | grep dgx-api
sudo docker logs dgx-api --tail 50

Access control

The UI requires HTTP Basic auth, and this is not optional. The Agent tab runs Claude Code as your user with --dangerously-skip-permissions, and nginx binds 0.0.0.0 — without a credential the app is an unauthenticated shell for anyone who can reach the port. A VPN ACL does not cover the LAN.

Set it in .env:

SPARKY_AUTH_USER=your-username
SPARKY_AUTH_PASS=use-a-long-random-value

deploy.sh hashes it into an nginx {SHA} htpasswd line before it leaves your machine, so the plaintext never reaches the server or the repo. With no credential configured the app fails closed and denies everything.

/health is exempt so the container healthcheck still works.

Security notes

  • The backend binds 127.0.0.1:3081. It exposes container control and shell exec, so it must never be published — on host networking 0.0.0.0 would put it on the LAN and the VPN.
  • The backend needs the Docker socket for container management.
  • Claude Code runs with --dangerously-skip-permissions.
  • Never commit credentials or internal IPs. .secret-patterns (gitignored, see .secret-patterns.example) feeds the scanners in .claude/; putting the literal secret in the checklist that searches for it is how it leaked the first time.
  • Plain HTTP is acceptable inside a WireGuard/Tailscale tunnel; it is not on an open network. Basic auth over plain HTTP sends the credential in every request.

Tech Stack

  • Vue 3 + Composition API
  • Vite 7
  • Tailwind CSS 4
  • Docker + nginx (production)
  • PWA (manifest + service worker)
  • FastAPI (backend)

License

MIT

Contributing

Pull requests welcome! Please ensure:

  • Code follows existing style
  • Documentation is updated
  • No hardcoded credentials or environment-specific values

See CONTRIBUTING.md for details.

Acknowledgments

Built with Claude Code

About

Vue 3 web interface for NVIDIA DGX Spark with ComfyUI, Ollama, and system management

Resources

Contributing

Security policy

Stars

16 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages