How to Set Up OctoPrint for a 3D Printer (Control, Monitor and Time-Lapse from the Server)

The 3D printer on a web page: OctoPrint. Upload from the slicer, watch the camera from the sofa, a buzz when it's done, power off after the job.

A 3D printer with an SD card slot means walking to it with a card every print and hoping it's still going. OctoPrint connects to the printer over USB and gives it a web page: upload G-code straight from the slicer, start, pause, watch the temperatures, a webcam view, a time-lapse per print, and a plugin ecosystem that adds everything from failure detection to a power switch. It usually lives on a Pi next to the printer; the server does it just as well if the printer's within USB reach — or a Pi Zero runs it and the server does the rest.

Quick reference

TaskWhat
Folder~/docker/octoprint/compose.yaml
Webhttp://server-ip:5003
Printer/dev/ttyUSB0 or /dev/ttyACM0 passed as a device; group dialout
Cameraa USB webcam at /dev/video0 with the bundled mjpg-streamer, or a phone/IP camera stream
SlicerPrusaSlicer/Cura "send to OctoPrint" with an API key
Powera smart plug via the PSU Control plugin + Home Assistant

1. Find the printer and camera

Plug the printer's USB in (printer switched on):

ls -l /dev/serial/by-id/ # printer, e.g. usb-Prusa_Research… or ttyUSB0 / ttyACM0
ls -l /dev/video* # webcam

2. The compose file

mkdir -p ~/docker/octoprint/data && cd ~/docker/octoprint
nano compose.yaml

services:
octoprint:
image: octoprint/octoprint:latest
container_name: octoprint
ports:
- "5003:80"
environment:
ENABLE_MJPG_STREAMER: "true"
MJPG_STREAMER_INPUT: "-r 1280x720 -f 15"
CAMERA_DEV: /dev/video0
TZ: Europe/London
devices:
- /dev/serial/by-id/usb-Prusa_Research_xxx:/dev/ttyUSB0
- /dev/video0:/dev/video0
volumes:
- ./data:/octoprint
restart: unless-stopped

docker compose up -d
sudo ufw allow from 192.168.1.0/24 to any port 5003

No webcam? Drop the camera lines; add a phone running an IP-camera app or a Frigate (91) restream later as a URL in OctoPrint's webcam settings.

3. First run

http://192.168.1.50:5003: the setup wizard — create a user (keep access control on), skip or enable anonymous usage tracking, the printer profile (bed size, nozzle, max speeds — from the printer's specs). Then Connect: port /dev/ttyUSB0, baud rate AUTO (115200 or 250000 for most). The Temperature tab starts graphing; the Control tab moves the head. That's a connected printer.

4. From the slicer

PrusaSlicer: Printer settings → General → Physical printer → host type OctoPrint, hostname 192.168.1.50:5003, API key from OctoPrint Settings → API. The Send to printer button uploads G-code; tick "print" to start. Cura: the OctoPrint Connection plugin, same key. Files also upload from the web page (drag G-code) or via curl -F file=@part.gcode -H "X-Api-Key: …" http://…/api/files/local.

5. Watch and get told

The webcam shows on the Control tab and in the time-lapse tab (a frame per layer change → an MP4 when the print ends; Octolapse plugin for the polished kind). Plugins (Settings → Plugin Manager): ntfy or Telegram notifications on done/failed/paused ("print finished, 3h12m, 94 % success"); Bed Level Visualizer; PrintTimeGenius for accurate estimates; Obico (formerly Spaghetti Detective) for AI failure detection with a free self-hosted server; OctoEverywhere or just the VPN (33) for remote access — don't expose OctoPrint to the internet.

6. Power control

A smart plug on the printer's mains (Tasmota/ESPHome, 123, or Zigbee, 122): the PSU Control plugin switches it via Home Assistant (41) or MQTT (96) — on when you upload, off ten minutes after a finished print, and never off mid-print. Home Assistant's own OctoPrint integration adds the printer's state, temperatures and progress to the dashboard, with the camera feed, so the kiosk tablet (197) shows the print.

7. Pi or server?

The server is fine if the printer sits near it; USB cable length (under 3 m) is the limit. Otherwise a Pi 3/4 (not Zero for a camera) next to the printer with OctoPi, and the server just runs Home Assistant and the notifications. Either way, don't run Jellyfin transcodes on a Pi that's also feeding G-code — stutters become layer defects; the server has the headroom.

Troubleshooting

Printer not found / "Error: Connection failed". The by-id path or the device name changed; dialout permissions (the container runs as root by default, so usually the path). Try baud 115200 and 250000 explicitly.

Camera black. /dev/video0 is a different index, or the webcam needs MJPG mode: -y in MJPG_STREAMER_INPUT for YUV cameras.

Prints pause/stutter. USB power management (powertop --auto-tune suspended the port — exclude it, 119), or the host too busy.

Upload works, print won't start. Printer in an error state (thermal runaway, SD card); the Terminal tab shows the firmware's complaint.

Wrapping up

One container with the printer and camera passed through, the slicer sending G-code with an API key, ntfy on done or failed, a smart plug that powers off afterwards. The printer joins the rest of the house's automation, and you watch the print from the sofa instead of standing over it.

Call us