Controller98 Controller98 Docs v0.2.0-alpha (Experimental)
CHAPTER 1: GETTING STARTED Controller98 v0.2.0-alpha (Experimental)

Introduction & Philosophy

⚠️
EXPERIMENTAL ALPHA PRE-RELEASE (VERSION < 1.0) β€” HOMELAB & NON-PRODUCTION ONLY

Controller98 is in active experimental pre-release development. It is NOT a stable production release. Built strictly for homelabs, enthusiast experimentation, and self-hosted testing environments. Do NOT deploy in commercial, enterprise, or mission-critical production infrastructure. Interfaces, database schemas, and CLI commands are subject to breaking changes prior to v1.0. Notice: Tested exclusively on Ubuntu 26.04 so far.

Controller98 is an open-source infrastructure and ingress management platform. It combines the aesthetic charm and rapid keyboard-friendly ergonomics of the iconic Windows 98 desktop with high-performance modern server-side Go engineering.

πŸ’‘
Core Design Principles
  • Zero Client-Side JavaScript: The UI renders entirely via server-side Go HTML templates (SSR) styled with pure CSS (98.css). Browsers download zero megabytes of JS bundles.
  • Extreme Resource Efficiency: Consistently idles at approximately 10 to 12 MiB of RAM, guaranteeing operation on low-spec VPS, Raspberry Pis, and dense Kubernetes nodes.
  • Unified Heterogeneous Control: A single pane of glass for local Docker sockets, Compose stacks, Kubernetes clusters, and remote bare-metal servers.
  • Zero-Dependency Ingress: Native ECDSA TLS engine, Cloudflare Tunnels, ngrok, and ACME without requiring NGINX, Traefik, or Caddy.

System Architecture

Controller98 is compiled into a single static binary containing the web server, SQLite database layer, Docker API client, Kubernetes client, tunnel orchestrator, and Model Context Protocol (MCP) server:

Component Implementation Purpose
retro-infra-manager Pure Go (net/http, database/sql) Primary web server, SSR desktop engine, API router, and ingress controller.
retro-mcp Pure Go JSON-RPC 2.0 Model Context Protocol server for AI coding assistants (Claude, Cursor, AGY).
retro-entrypoint Pure Go Sub-process Proxy Lightweight container entrypoint wrapper providing automatic TLS & health probes.
internal/tunnel Go crypto/tls + Sub-process Runners Automated Self-Signed ECDSA TLS, Cloudflare, ngrok, and Let's Encrypt manager.
internal/db modernc.org/sqlite (Pure Go CGO-free) Zero-dependency embedded database for RBAC, sessions, notes, tokens, and audit logs.

Resource Optimization (< 20 MB Target)

Most modern DevOps dashboards (e.g., Portainer, Rancher, Lens) are built as heavy Single-Page Applications (SPAs) requiring hundreds of megabytes of RAM just to idle. Controller98 achieves its strict < 20 MB RAM target through:

  1. Zero-Allocation SSR: HTML is streamed directly to the socket without holding large in-memory DOM representations.
  2. Pure Go SQLite: No external database daemon (PostgreSQL/MySQL) running in the background.
  3. On-Demand Tunnel Monitoring: Child processes (cloudflared/ngrok) are executed concurrently with non-blocking pipe readers and minimal buffer allocations.
  4. GC Optimization: Goroutine pools and low object allocation keep Go runtime garbage collection pauses under 1 millisecond.
CHAPTER 2: INSTALLATION Step-by-Step

Installation & Deployment

Docker CLI Quickstart

The fastest way to deploy Controller98 is with the official Docker Hub image:

TERMINAL (BASH)
docker run -d \
  --name controller98 \
  --restart unless-stopped \
  --network host \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v ~/.kube/config:/root/.kube/config:ro \
  -v c98-data:/app/data \
  rafaeltre/controller98:latest
ℹ️
Host Networking Mode

Using --network host allows Controller98 to bind to port 8080 (Web UI), port 443 (HTTPS Ingress), and port 80 (HTTP-01 ACME challenges) without complex port forwarding rules.

🐧
Tested Operating System

Note: Controller98 has been tested only on Ubuntu 26.04 so far. Although multi-platform container images (linux/amd64 and linux/arm64) are distributed, bare metal operations, socket mappings, and hardware metrics have exclusively been verified against Ubuntu 26.04 LTS environments.

Docker Compose Setup

For persistent production setups, save the following as docker-compose.yml:

DOCKER-COMPOSE.YML
services:
  controller98:
    image: rafaeltre/controller98:latest
    container_name: controller98
    restart: unless-stopped
    network_mode: "host"
    environment:
      - PORT=8080
      - DATA_DIR=/app/data
      - DOCKER_HOST=unix:///var/run/docker.sock
      - KUBECONFIG=/root/.kube/config
    volumes:
      - controller-data:/app/data
      - /var/run/docker.sock:/var/run/docker.sock
      - ~/.kube/config:/root/.kube/config:ro

volumes:
  controller-data:

Launch the stack with:

BASH
docker compose up -d

Kubernetes & Helm Deployment

To deploy Controller98 directly into a Kubernetes cluster, use the following manifest:

KUBERNETES MANIFEST (YAML)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: controller98
  namespace: kube-system
spec:
  replicas: 1
  selector:
    matchLabels:
      app: controller98
  template:
    metadata:
      labels:
        app: controller98
    spec:
      hostNetwork: true
      containers:
        - name: controller98
          image: rafaeltre/controller98:latest
          env:
            - name: PORT
              value: "8080"
            - name: KUBERNETES_SERVICE_HOST
              value: "127.0.0.1"
          volumeMounts:
            - name: docker-sock
              mountPath: /var/run/docker.sock
            - name: data-volume
              mountPath: /app/data
      volumes:
        - name: docker-sock
          hostPath:
            path: /var/run/docker.sock
        - name: data-volume
          persistentVolumeClaim:
            claimName: controller98-pvc

Storage & Data Persistence

Controller98 stores all operational data in /app/data:

  • /app/data/retro.db: SQLite database storing users, password hashes, settings, notes, and audit logs.
  • /app/data/certs/: Cached SSL/TLS certificates (Let's Encrypt ACME and Self-Signed ECDSA pairs).
  • /app/data/stacks/: Docker Compose YAML stack definitions.
CHAPTER 3: DOCKER & COMPOSE Container Management

Docker Engine & Compose Management

Container Lifecycle Control

Controller98 interacts with the Docker Engine through the native Unix domain socket at /var/run/docker.sock without invoking the Docker CLI as a subprocess for API operations:

  • Start: Starts an existing stopped container.
  • Stop: Gracefully stops a running container (SIGTERM followed by SIGKILL).
  • Pause / Unpause: Freezes container cgroups without terminating processes.
  • Restart: Restarts the container with minimal downtime.
  • Delete: Removes stopped containers from the host.
  • Live Logs: Opens real-time terminal output with automatic ANSI escape code filtering.

Image Management & Layer Inspection

The Images tab provides full registry pull capabilities and local image maintenance.

HTTP POST /docker/images/pull
POST /docker/images/pull HTTP/1.1
Content-Type: application/x-www-form-urlencoded

image=busybox:latest&node=local

Images can also be deleted directly from the web table to reclaim host disk space.

Compose Studio & YAML Stacks

Controller98 includes an integrated Compose Studio that combines visual stack management with raw YAML editing:

  • Stack Editor: Write standard Compose specifications with syntax checking.
  • Save & Deploy: Saves stack YAML to SQLite and immediately executes docker compose up -d.
  • Active Projects Auto-Detection: Discovers Compose projects already running on the host via Docker label inspection.
  • Teardown: Shuts down deployed stacks with docker compose down.
CHAPTER 4: KUBERNETES Cluster Orchestration

Kubernetes & Helm Orchestration

Cluster Connection & Mounting

Connect to local or remote Kubernetes clusters by mounting your kubeconfig file (~/.kube/config). Controller98 provides real-time state visualization and workload management:

Pods & Real-Time Streaming Logs

Inspect Pod health states (Running, Pending, CrashLoopBackOff), examine restart counts, and view streaming stdout/stderr logs with zero browser memory overhead.

Deployments & Replica Scaling

Scale replica counts with instant slider controls, trigger zero-downtime rollout restarts, and inspect revision history.

SCALE REPLICAS (HTTP POST)
POST /k8s/deploy/scale HTTP/1.1
Content-Type: application/x-www-form-urlencoded

namespace=default&name=web-api&replicas=3&node=local

Triggering Rollout Restart (POST /k8s/deploy/restart) prompts Kubernetes to update the deployment pod template, cycling pods without downtime.

Services, Nodes & Helm Releases

Inspect cluster networking (ClusterIP, NodePort, LoadBalancer), host node resource allocations, and view active Helm charts installed via Helm v3.

CHAPTER 5: CLUSTERING Network Neighborhood

Network Neighborhood (Heterogeneous Clustering)

Multi-Node Architecture

Controller98 introduces the Network Neighborhood: an ultra-lightweight multi-node clustering protocol designed for heterogeneous hardware (e.g. cloud VPS paired with local Raspberry Pis and bare-metal servers).

Installing Remote Agent Daemons

On any remote machine you wish to manage, run the standalone agent daemon:

RUN AGENT ON REMOTE NODE
docker run -d \
  --name c98-agent \
  --restart unless-stopped \
  --network host \
  -e MODE=agent \
  -e AGENT_PORT=8081 \
  -e AGENT_TOKEN=my-secure-cluster-token \
  -v /var/run/docker.sock:/var/run/docker.sock \
  rafaeltre/controller98:latest

Then, open Controller98 → Network Neighborhood → Add Remote Node, specify the remote IP/FQDN and token, and click Add Node. Controller98 will continuously probe latency and allow you to switch contexts between nodes instantly.

CHAPTER 5: TUNNELS & INGRESS HTTPS & Gateway

Ingress Gateway & HTTPS Tunnels

Gateway Architecture

Controller98 includes a high-performance built-in ingress proxy and tunnel orchestrator. It supports four automated HTTPS modes with zero external reverse proxies:

Pure Go Self-Signed TLS (Port 443)

Generates ECDSA P-256 certificates dynamically in memory on port 443 with Subject Alternative Names (SANs) for localhost and local network IP addresses.

  • Generates an elliptic curve ECDSA P-256 certificate with Subject Alternative Names (SANs) for localhost, the host IP, and your custom domain.
  • Listens on port 443 with HTTP/2 and TLS 1.3 support.
  • Automatically proxies incoming HTTPS traffic to Controller98 and configured sub-routes.

Cloudflare Tunnels (Quick & Token)

The embedded cloudflared runner allows exposing your server to the global internet without opening firewall ports or configuring port forwarding:

  • Quick Tunnel (Zero Key): Leave the token field blank. Controller98 requests an account-less tunnel and automatically captures the assigned https://*.trycloudflare.com URL.
  • Named Tunnel (Token): Enter your Cloudflare Zero Trust tunnel token (eyJh...) to bind to your pre-configured Cloudflare DNS domain.

ngrok Public Tunnels

Enter your ngrok authtoken in the web UI. Controller98 executes ngrok http 8080 --authtoken <token>, establishes an encrypted session with the ngrok cloud gateway, and displays the public https://*.ngrok-free.dev URL directly in your retro desktop status bar.

Automated Let's Encrypt (ACME HTTP-01)

Enter your domain name (e.g., infra.mycompany.com) and email. Controller98 automatically initiates an ACME HTTP-01 challenge on port 80, obtains signed Let's Encrypt certificates, caches them in /app/data/certs/, and handles renewals automatically.

5. Multi-Service Ingress Routing Table

Expose multiple services and containers behind a single secure HTTPS domain or tunnel:

Path Prefix Target Upstream Example Service
/ (Default) http://127.0.0.1:8080 Controller98 Web Desktop
/grafana http://127.0.0.1:3000 Grafana Monitoring Dashboards
/ollama http://127.0.0.1:11434 Ollama Local LLM API
/open-webui http://127.0.0.1:8081 Open-WebUI LLM Interface

6. Retro Entrypoint Assistant

The included retro-entrypoint executable can wrap around any arbitrary container or pod to instantly inject automatic TLS, public tunnels, and Kubernetes readiness/liveness probes.

CHAPTER 7: SECURITY Authentication & RBAC

Security, Authentication & RBAC

Role-Based Access Control (RBAC)

Controller98 enforces defense-in-depth principles: Argon2id password hashing, constant-time token verification, sliding-window IP rate limiting, strict CSRF validation, and granular Personal Access Tokens (PATs).

  • Admin: Full permissions. Can create/delete users, generate API tokens, deploy Compose stacks, scale K8s workloads, and modify tunnel settings.
  • Operator: Operational access. Can start/stop/restart containers, scale deployments, and view logs, but cannot create users or delete security tokens.
  • Viewer: Read-only access. Can inspect dashboards, container lists, and metrics, but all mutating POST actions are blocked.

CLI Password Reset & Disaster Recovery

If you forget your administrator password or lose access, reset credentials directly using the CLI inside the container:

PASSWORD RESET CLI
# Reset admin password
docker exec retro-infra-manager retro-infra-manager reset-password NewPassword123!

# Reset a specific user
docker exec retro-infra-manager retro-infra-manager reset-password operator1 NewPassword123!

# Reset all users to re-trigger the /setup wizard
docker exec retro-infra-manager retro-infra-manager reset-admin

Personal Access Tokens (PATs)

Generate scoped API tokens for automated scripts and MCP AI clients with granular permissions (*, read, docker, k8s, admin).

REST API Reference

Authenticate requests with the Authorization: Bearer <token> header:

REST API STATUS CHECK
curl -H "Authorization: Bearer c98_pat_..." http://localhost:8080/api/v1/status

Common endpoints:

  • GET /api/v1/status: Host CPU, RAM, disk, Docker, and K8s availability.
  • GET /api/v1/docker/containers: List all containers with status and IDs.
  • POST /api/v1/docker/container/action: Trigger start, stop, restart, pause.
  • GET /api/v1/k8s/pods: List active cluster pods.
CHAPTER 6: AI & MCP Model Context Protocol

Model Context Protocol (MCP) AI Integration

MCP Protocol Overview

Controller98 exposes infrastructure automation tools to modern AI assistants (Claude Desktop, Cursor, AGY) through the Model Context Protocol (MCP).

Stdio Mode (retro-mcp)

The standalone retro-mcp binary implements standard JSON-RPC 2.0 over standard input/output:

CLAUDE_DESKTOP_CONFIG.JSON
{
  "mcpServers": {
    "controller98": {
      "command": "docker",
      "args": [
        "exec",
        "-i",
        "retro-infra-manager",
        "retro-mcp"
      ]
    }
  }
}

HTTP Server-Sent Events (/mcp/sse)

Remote agents can connect to http://localhost:8080/mcp/sse using Bearer token authentication.

Supported AI Tools

  • docker_list_containers: Inspect all containers, states, and ports.
  • docker_container_action: Start, stop, restart, or pause containers.
  • k8s_list_pods: List cluster workloads.
  • k8s_scale_deployment: Autoscale replicas dynamically based on AI reasoning.
  • tunnel_get_status: Check public tunnel URLs and ingress routing.
CHAPTER 9: OPERATIONS Diagnostics & FAQ

Operations, Diagnostics & FAQ

Diagnostics & Activity Audit Logs

Controller98 records all administrative actions in the Task Manager → Audit Logs tab. Every container restart, image pull, user login, and deployment change is timestamped and recorded with username and outcome.

FAQ & Troubleshooting

❓
Q: Why does the UI look like Windows 98?

Windows 98 pioneered high-density, no-nonsense desktop ergonomics. By utilizing standard HTML tables, bevels, and native inputs with 98.css, we achieve an ultra-intuitive dashboard that loads in milliseconds with zero JavaScript overhead.

⚠️
Q: Docker socket permission denied?

Ensure /var/run/docker.sock is accessible by the container user (UID 0 root by default). On Linux systems with SELinux, append :z to the volume mount: -v /var/run/docker.sock:/var/run/docker.sock:z.

πŸ’‘
Q: Can I use custom domain SSL certificates?

Yes! Choose Custom TLS or Let's Encrypt in the Tunnels & Ingress configuration tab to use your own domain and certificates.

πŸ” Documentation Search
    Navigate with ↑ ↓ and Enter Press Esc to close