mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-08-11 00:30:12 -04:00
The Virtual Printer binds 990 and 322, below 1024, which a service running
as a normal user may not do without CAP_NET_BIND_SERVICE. Without it the
rest of Bambuddy works and only the VP is dead -- sockets never open, the
slicer never finds the printer, and the sole trace is one journal line.
332a7c6ac added the line to install/install.sh in March under the heading
"Fix install.sh missing AmbientCapabilities". Three other places define the
same unit and none of them got it: the manual template, the combined
Bambuddy + SpoolBuddy installer, and the unit the wiki tells you to paste.
The wiki additionally claimed the capability was always included.
Also diagnose it. The VP diagnostic reported only that nothing was listening
on 990, which reads identically to a port conflict. It now checks CapEff for
the capability and names it as the cause -- but stays quiet when the port is
answering (an iptables REDIRECT is the documented alternative and that host
works) and when the capability is held (the port is down for another reason
and blaming this would misdirect). Skips where there is no procfs rather
than putting a systemd instruction in front of a macOS user.
97 lines
3.7 KiB
Desktop File
97 lines
3.7 KiB
Desktop File
# BamBuddy Systemd Service Template
|
|
#
|
|
# INSTALLATION:
|
|
# 1. Copy this file to /etc/systemd/system/bambuddy.service
|
|
# 2. Replace placeholders:
|
|
# - INSTALL_PATH: Where BamBuddy is installed (e.g., /opt/bambuddy)
|
|
# - SERVICE_USER: User to run as (e.g., bambuddy)
|
|
# - DATA_DIR: Data directory (e.g., /opt/bambuddy/data)
|
|
# - LOG_DIR: Log directory (e.g., /opt/bambuddy/logs)
|
|
# 3. Run: sudo systemctl daemon-reload
|
|
# 4. Run: sudo systemctl enable bambuddy
|
|
# 5. Run: sudo systemctl start bambuddy
|
|
#
|
|
# Or use the install script: ./install/install.sh
|
|
#
|
|
|
|
[Unit]
|
|
Description=BamBuddy - Bambu Lab Print Management
|
|
Documentation=https://github.com/maziggy/bambuddy
|
|
After=network.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=SERVICE_USER
|
|
Group=SERVICE_USER
|
|
WorkingDirectory=INSTALL_PATH
|
|
|
|
# Environment file (optional - created by install script)
|
|
EnvironmentFile=-INSTALL_PATH/.env
|
|
|
|
# Use virtual environment
|
|
Environment="PATH=INSTALL_PATH/venv/bin:/usr/local/bin:/usr/bin:/bin"
|
|
|
|
# Server configuration
|
|
# --loop asyncio is required: uvloop's SSL layer can silently truncate VP FTP
|
|
# uploads on a ragged client close over slow storage (#1896). Do not remove.
|
|
#
|
|
# --timeout-graceful-shutdown is also required. Uvicorn's default is to wait
|
|
# forever for in-flight requests, and an MJPEG camera stream is a response that
|
|
# never completes — one open camera tile would hang the stop until systemd gave
|
|
# up and SIGKILLed, skipping the WAL checkpoint, the MQTT disconnect and the
|
|
# virtual-printer teardown entirely. On timeout uvicorn cancels the request
|
|
# tasks; the camera generators unwind cleanly on CancelledError.
|
|
ExecStart=INSTALL_PATH/venv/bin/uvicorn backend.app.main:app --host 0.0.0.0 --port ${PORT:-8000} --loop asyncio --timeout-graceful-shutdown 5
|
|
|
|
# Restart policy
|
|
Restart=on-failure
|
|
RestartSec=5
|
|
|
|
# Graceful shutdown. Uvicorn now bounds its own wait at 5s and the app's own
|
|
# teardown takes ~1-2s, so this only has to be comfortably longer than that —
|
|
# it is the backstop, not the mechanism. The old 10s could clip a slow teardown
|
|
# on a Pi with several virtual printers.
|
|
TimeoutStopSec=30
|
|
|
|
# Kill zombie ffmpeg processes (timelapse processing)
|
|
ExecStartPre=-/usr/bin/pkill -9 -f "ffmpeg.*bambuddy"
|
|
ExecStopPost=-/usr/bin/pkill -9 -f "ffmpeg.*bambuddy"
|
|
|
|
# Logging
|
|
StandardOutput=journal
|
|
StandardError=journal
|
|
SyslogIdentifier=bambuddy
|
|
|
|
# Allow binding to privileged ports (322 RTSP, 990 FTPS) for Virtual Printer
|
|
# mode. Without this the VP's sockets never open and the slicer simply never
|
|
# sees the printer — with no obvious error, since the bind failure is one line
|
|
# in the journal (#2549). Works alongside NoNewPrivileges=true below: systemd
|
|
# raises the ambient set at exec, which is not the privilege escalation that
|
|
# setting forbids.
|
|
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
|
|
|
# Security hardening
|
|
NoNewPrivileges=true
|
|
PrivateTmp=true
|
|
ProtectSystem=strict
|
|
# ProtectHome=true hides /home/* and breaks ExecStart when INSTALL_PATH is
|
|
# under /home (issue #1685). Default is the safer read-only; flip to true if
|
|
# your INSTALL_PATH is outside /home (e.g. /opt/bambuddy).
|
|
ProtectHome=read-only
|
|
#
|
|
# ProtectSystem=strict mounts EVERYTHING outside these three paths read-only for
|
|
# this service — including a NAS share you have mounted yourself and can write to
|
|
# from your own shell. Writes there fail with EROFS ("Read-only file system"),
|
|
# which looks like a permission problem but is not one (issue #2544).
|
|
#
|
|
# So if you point Scheduled Backups at a directory outside the install, data and
|
|
# log dirs, add it here — or better, in a drop-in that survives a reinstall:
|
|
#
|
|
# sudo systemctl edit bambuddy
|
|
# [Service]
|
|
# ReadWritePaths=/mnt/your-nas-share
|
|
#
|
|
ReadWritePaths=DATA_DIR LOG_DIR INSTALL_PATH
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|