{ me, pkgs, ... }: let moonrakerPort = 7125; klipperDir = "/srv/klipper"; serial = "/dev/ttyUSB0"; user = "klipper"; group = "klipper"; klipper-config = pkgs.runCommand "klipper-printer.cfg" {} '' cat \ ${../assets/printer/printer.cfg} \ ${../assets/printer/mainsail.cfg} \ > $out ''; webcamPort = 1984; in { security.polkit.enable = true; users.users.klipper = { isSystemUser = true; description = "Klipper user"; home = "/srv/klipper"; inherit group; extraGroups = [ "dialout" ]; # for serial access }; users.groups.klipper = {}; services = { klipper = { enable = true; inherit user group; firmwares.mcu = { enable = true; enableKlipperFlash = true; inherit serial; configFile = ../assets/printer/firmware.cfg; }; mutableConfig = false; configFile = klipper-config; configDir = "${klipperDir}/config"; }; moonraker = { enable = true; inherit user group; address = me.tailscale.ip; port = moonrakerPort; allowSystemControl = true; stateDir = "${klipperDir}/moonraker"; settings = { authorization = { cors_domains = [ "*://app.fluidd.xyz" "*://my.mainsail.xyz" "*://*.rnrd.fyi" ]; trusted_clients = [ "10.0.0.0/8" "100.0.0.0/8" "127.0.0.0/24" "192.168.178.0/24" ]; }; # ignore warnings about moonraker not being able to # adjust klipper configuration. i don't really mind. file_manager = { check_klipper_config_path = false; }; }; }; mainsail = { enable = true; hostName = "3d.rnrd.fyi"; nginx = { useACMEHost = "rnrd.fyi"; forceSSL = true; listenAddresses = [ me.tailscale.ip ]; locations."/webcam" = { proxyPass = "http://${me.tailscale.ip}:${toString webcamPort}"; proxyWebsockets = true; }; extraConfig = '' access_log /var/log/nginx/3d.access.log json_combined; ''; }; }; # don't reject large gcode files etc. nginx.clientMaxBodySize = "1000M"; }; foundation.tailnetServices = [ "moonraker" ]; }