printspy

printspy

Docker app from ccmpbll's Repository

Overview

Self-hosted dashboard for monitoring multiple 3D printers from a single web interface. Connects to OctoPrint and PrusaLink printers, displaying real-time status, webcam feeds, temperatures, print progress, and more via Server-Sent Events. Features include a full File Manager with thumbnails and one-click reprint, print history with per-print material/filament stats, Pushover notifications, smart plug power control (Tasmota via direct HTTP or MQTT, or PSU Control), print control (pause/resume/cancel), and PrusaSlicer/OrcaSlicer print-host integration. Open the web UI, add your printers, and you're set. No config files needed. Web interface: http://Unraid_IP:8080

PrintSpy

Build Status Docker Image Size Docker Pulls License

A self-hosted dashboard for monitoring multiple 3D printers — OctoPrint and PrusaLink — from a single web interface.

This was built for my own personal use and the way I want to interact with my printers, as well as an ongoing experiment in agentic coding.

Early Development — expect rough edges, breaking changes, and evolving APIs. Feedback and contributions welcome.

What it does

Each printer gets a row in the dashboard: webcam/snapshot, progress/ETA, temps, and smart plug power state/control. Updates push live via SSE. Everything's configured through the settings page — no config files, no restart needed.

Screenshots

Dashboard

File Manager & Print History

File Manager Print History

Supported platforms

  • OctoPrint — fully supported (as far as I know)
  • PrusaLink — more than experimental at this point, but only tested on MK4S and Core One

Plugin architecture — new platforms should be straightforward to add.

Features

Core (both platforms)

  • Real-time dashboard updates via SSE, no manual refresh
  • Print control — pause, resume, cancel
  • File Manager per printer — browse every file on its storage, one-click reprint, download, or delete, thumbnail and material/tool previews for every file (native on OctoPrint, cached from the file's own metadata on PrusaLink)
  • Print history per printer, with configurable retention (days, 0 = keep forever) and real thumbnails per entry
  • Pushover notifications — print started/checkpoints/complete/failed/error, each independently configurable: priority, sound, image source (camera/thumbnail/none), and custom title/message templates
  • Smart plug power control via a directly-configured Tasmota device, independent of any platform plugin, assignable to any printer — HTTP-direct (default) or MQTT (push-based, opt-in per plug)
  • Auto-off after idle timeout and thermal runaway protection (second layer on top of firmware protection) for printers with an assigned smart plug
  • Camera feed via printspy-cam (ESP32-CAM firmware), assignable to any printer — snapshot/live/plate-thumbnail toggle buttons under each card's image, with an optional global setting to hide the whole section for a printer while it's unreachable
  • Multi-user login with per-account passwords, no roles/tiers
  • Config backup/restore as YAML
  • Printer reordering, optional free-text "model" field, dark mode, responsive layout

OctoPrint

  • Auto-detects camera stack (MJPEG or camera-streamer), printer name, and installed plugins
  • Native smart plug power control + energy monitoring, auto-detected via the Tasmota or PSU Control plugin
  • Layer progress display (needs the DisplayLayerProgress plugin)
  • Live webcam streaming, with a snapshot/live toggle

PrusaLink

  • Snapshot only — no live stream from the printer's own camera (assign a printspy-cam for a live feed)
  • No native power control over the API — use a directly-configured smart plug instead
  • Keepalive ping — works around printers whose wifi drops off after sitting idle
  • File upload from the dashboard, with an optional "print immediately"
  • Slicer print-host target — point PrusaSlicer/OrcaSlicer's "Send to printer" (PrusaLink mode) at PrintSpy, pinned to one specific printer; "Upload" relays automatically once the printer's online, "Upload and Print" also powers it on first if it's off — no manual step either way
  • Print history enriched with real per-print metadata — material, filament used/cost, layer height, duration vs. estimate, and per-tool breakdown for multi-material prints — parsed directly from the file's own slicer metadata, since none of this is exposed over PrusaLink's API

Quick start

docker run -d \
  --name printspy \
  -p 8080:8080 \
  -v printspy-data:/data \
  ccmpbll/printspy:latest

Open http://<docker host IP>:8080 — first run prompts you to create a login. Once in, click the settings gear and add your first printer. You'll need the printer's URL and OctoPrint API key or Prusalink user/pass.

Docker Compose

services:
  printspy:
    image: ccmpbll/printspy:latest
    ports:
      - "8080:8080"
    volumes:
      - printspy-data:/data
    restart: unless-stopped

volumes:
  printspy-data:

Configuration

All printer management is done through the web UI — open the settings page to add, edit, reorder, and remove printers. No config files needed.

Login

First run redirects to a setup page to create the first account. Add or remove additional users from Settings → Users. No roles or permission tiers — every account has full access.

Smart plugs

OctoPrint printers with the Tasmota or PSU Control plugin installed get power control automatically — nothing to configure. For everything else (PrusaLink or an OctoPrint printer without the plugin), add a Tasmota device directly under Settings → Smart Plugs and assign it to a printer. Plugs are managed independently of printers, so deleting a printer unassigns its plug instead of deleting it.

Each plug can use either connection mode:

  • Direct HTTP (default) — polled over the network on each printer's own poll interval, no extra setup
  • MQTT — push-based via a broker instead of polling; configure the broker under Settings → MQTT Broker (host:port, optional TLS/username/password), then set the plug's mode to MQTT and enter its Tasmota topic

Both modes can be mixed freely across plugs.

Cameras

Any printer type can get a webcam feed by assigning a printspy-cam device under Settings → Cameras — useful for PrusaLink, which has no webcam support of its own. Assigning a camera overrides whatever webcam a printer's own plugin would otherwise show. Cameras are managed independently of printers, so deleting a printer unassigns its camera instead of deleting it.

Environment variables

Variable Default Description
PRINTSPY_PORT 8080 HTTP server port
PRINTSPY_DATA_DIR /data SQLite database location

Getting your OctoPrint API key

  1. Open your OctoPrint web interface
  2. Go to Settings (wrench icon) → API
  3. Copy the Global API Key, or create a new one under Application Keys

Tech stack

  • Go backend — single binary, low resource usage
  • SQLite — no external database needed
  • Vanilla HTML/CSS/JS frontend — no build step, no framework
  • Docker — amd64 container

Building from source

# Requires Go 1.25+ and CGO (for SQLite)
make build

# Or with Docker
make docker

Contributing

PrintSpy is in early development. If you'd like to contribute:

  • Open an issue to discuss before submitting large changes
  • Bug reports with docker logs output are especially helpful
  • Plugin implementations for Moonraker/Klipper are welcome

License

AGPL-3.0 — see LICENSE for details.

Install Printspy on Unraid in a few clicks.

Find Printspy in Community Apps on your Unraid server, review the template, and click Install. Unraid handles the Docker app or plugin setup from the published template.

Open the Apps tab on your Unraid server Search Community Apps for Printspy Review the template variables and paths Click Install

Download Statistics

2,349
Total Downloads

Related apps

Explore more like this

Explore all

Details

Repository
ccmpbll/printspy:latest
Last Updated2026-07-15
First Seen2026-06-29

Runtime arguments

Web UI
http://[IP]:[PORT:8080]
Network
bridge
Shell
sh
Privileged
false

Template configuration

Web UI PortPorttcp

HTTP web interface port

Target
8080
Default
8080
Value
8080
Config PathPathrw

Path to store PrintSpy database and configuration

Target
/data
Default
/mnt/user/appdata/printspy
Value
/mnt/user/appdata/printspy