May 2, 20244 minutes
Exploring a typical software stack for a Klipper 3D Printer.
The software stack for a typical Klipper setup encompasses several key components. First is Klipper itself, serving as the 3D printer firmware. Then there’s Moonraker, functioning as the web API layer. Additionally, there’s a client application, such as Mainsail or Fluidd. Finally, there’s typically a camera service that provides the video stream.
Klipper operates locally and exposes its interface using a Unix Domain Socket. To extend this interface over the network, Moonraker connects to it and facilitates communication through a defined HTTP(S)/Websocket protocol. This setup enables any HTTP server to host a WebUI for printer control, including options like nginx, lighttpd, apache, or even python’s built-in HTTP server module. Since camera services usually operate their own servers, their streams are readily accessible over the network. With these combined services, users gain a modern and powerful means to manage their printers locally.
Let’s show this as a sequence diagram:
When Klipper starts, the Klippy service creates a Unix Domain Socket in /tmp/klippy_uds
for communication. Moonraker connects and communicates with Klippy over this socket.
Moonraker also enables various controls over its WebAPI, e.g. managing the host services, reboot, and etc.
If webcam stream is needed, then running ustreamer will expose a stream on port 8080
. With Moonraker, Klipper, and ustreamer running, serving Mainsail asssets with a HTTP server like nginx will complete the asks. Taking this a step futher, the above diagram has nginx acting as a reverse proxy (on top of serving the Mainsail assets). As a reverse proxy, nginx acts as a middleware and relays communcations between Mainsail and the proxied services (Moonraker/ustreamer).
The nginx configuration would look something like this:
Find a full nginx.conf
for such reverse proxy setup in MainsailOS
.
Let’s breakdown and explain some of the sections.
Lines 3-6
, this condition nginx to send a Connection: Upgrade
header when a Upgrade
header is present. This enables Moonraker and its clients to switch from HTTP to Websocket.
Line 9
, reverse proxy server will listen on port 80
.
Line 13
, nginx will look for Mainsail assets in this path and serve them over port 80
.
Lines 27-36
, proxies the request to :80/websocket
from clients. Make sure appropriate HTTP headers are passed, e.g. Connection: Upgrade
to upgrade protocols, X-Real-IP
for Moonraker’s truste_cllients
checks.
Lines 39-47
, proxies other moonraker requests. These are typically HTTP and not Websocket.
Lines 50-57
, proxies :80/webcam/
to :8080/
(ustreamer). The various settings prevents stream delays by disabling buffering.
Lines 61-64
, defines upstream apiserver
(moonraker) for referencing in this config, e.g. line 28, 40
.
Lines 67-70
, defines upstream ustreamer
(ustreamer) for referencing in this config, e.g. line 56
.
You can proxy more webcams by duplicating and renaming the location /webcam/
(line 50-57
) and upstream ustreamer
(lines 67-70
) sections.
Now you should have a high level understanding of how all these services connect and interact with each other. You should also be able to configure a simple reverse proxy using nginx.