mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-09-30 03:01:21 +02:00
Reporter @TheFou (on Docker bridge mode with the default userland-proxy:
true) saw ~2000 docker-proxy host processes spawn from the commented
"50000-51000:50000-51000" line, pinning ~3.5 GB of host RAM before they
had even logged in for the first time. The processes are host-level so
they don't appear in `docker stats`, which makes the leak invisible.
Linux's host-mode default in the same compose file sidesteps this
entirely (zero docker-proxy cost) - the issue only fires when a user
forces bridge mode (typically Docker Desktop on macOS / Windows).
The 1001-port FTP passive range is load-bearing on the VP server side
(virtual_printer/ftp_server.py:567-574 documents the widening from 100
ports as multi-VP collision-avoidance headroom against birthday-style
collisions when bind_ip=0.0.0.0). Reverting it would regress multi-VP
installs to solve a problem that only exists for bridge-mode users.
Fix is documentation, not code. Added a warning block above the
commented FTP-passive line pointing bridge-mode users at
{ "userland-proxy": false } in /etc/docker/daemon.json. Reporter
confirmed this clears the issue on their setup - the kernel does NAT
directly via iptables/nftables in that mode, no per-port host process
needed. Only side-effect is that connections originating from
127.0.0.1 on the host itself can't reach the container, which doesn't
matter for nearly every Bambuddy install.
161 lines
7.9 KiB
YAML
161 lines
7.9 KiB
YAML
services:
|
||
bambuddy:
|
||
image: ghcr.io/maziggy/bambuddy:latest
|
||
build: .
|
||
# Usage:
|
||
# docker compose up -d → pulls pre-built image from ghcr.io
|
||
# docker compose up -d --build → builds locally from source
|
||
container_name: bambuddy
|
||
# File ownership inside the data and logs volumes is normalised by the
|
||
# entrypoint at startup (chowns to PUID:PGID and drops privileges via
|
||
# gosu before running the app). Override PUID / PGID below to match
|
||
# your host user if needed — defaults to 1000:1000 to match the
|
||
# historical compose `user:` directive.
|
||
#
|
||
# Allow binding to privileged ports (322, 990) as non-root user — required
|
||
# for FTPS in every VP mode and for the RTSPS camera proxy in proxy mode +
|
||
# non-proxy modes that have a target printer configured. Without this, the
|
||
# FTP and RTSP listeners silently fail.
|
||
cap_add:
|
||
- NET_BIND_SERVICE
|
||
#
|
||
# LINUX: Use host mode for printer discovery and camera streaming
|
||
network_mode: host
|
||
#
|
||
# macOS/WINDOWS: Docker Desktop doesn't support host mode.
|
||
# Comment out "network_mode: host" above and uncomment "ports:" below.
|
||
# Note: Printer discovery won't work - add printers manually by IP.
|
||
#ports:
|
||
# - "${PORT:-8000}:8000"
|
||
# - "3000:3000" # Virtual printer bind/detect
|
||
# - "3002:3002" # Virtual printer bind/detect
|
||
# - "8883:8883" # Virtual printer MQTT
|
||
# - "990:990" # Virtual printer FTP control
|
||
# - "6000:6000" # Virtual printer file transfer tunnel
|
||
# - "322:322" # Virtual printer RTSP camera (X1/H2/P2; proxy mode + non-proxy modes with a target printer)
|
||
# - "2024-2026:2024-2026" # Virtual printer proprietary ports (A1/P1S)
|
||
# - "50000-51000:50000-51000" # Virtual printer FTP passive data (widened from 50000-50100 for multi-VP headroom)
|
||
#
|
||
# ⚠️ Bridge-mode + Docker's default userland proxy: the 1001-port FTP
|
||
# passive range spawns ~2000 docker-proxy host processes (IPv4+IPv6
|
||
# × 1001 ports), each pinning ~3.5 MB of host RAM, for a ~3.5 GB
|
||
# footprint that doesn't show up in `docker stats` because it's
|
||
# host-level, not container-level (#1646). Linux's host-mode default
|
||
# above sidesteps this entirely. If you genuinely need bridge mode
|
||
# (e.g. Docker Desktop on macOS/Windows), set
|
||
# { "userland-proxy": false }
|
||
# in /etc/docker/daemon.json and restart Docker. Confirmed to clear
|
||
# the issue by the reporter; the kernel does NAT directly via
|
||
# iptables/nftables, no per-port host process needed. Only side-
|
||
# effect is that connections originating from 127.0.0.1 on the host
|
||
# itself can't reach the container — fine for nearly every
|
||
# Bambuddy install.
|
||
volumes:
|
||
- bambuddy_data:/app/data
|
||
- bambuddy_logs:/app/logs
|
||
#
|
||
# OPTIONAL — only needed if you ALSO run a native install of Bambuddy
|
||
# on the same host and want both installs to share the same Virtual
|
||
# Printer CA certificate (so the slicer only has to trust one CA).
|
||
# Most Docker-only users should leave this commented out — the
|
||
# entrypoint will keep the VP data inside the named volume above.
|
||
# If uncommented, the entrypoint chowns the host directory to
|
||
# PUID:PGID on first start so the container user can write to it.
|
||
#- ./virtual_printer:/app/data/virtual_printer
|
||
#
|
||
# Mount scheduled backup output to NAS or external storage
|
||
# Backups default to DATA_DIR/backups/ inside the data volume.
|
||
# Uncomment to store them externally (e.g. on a NAS share).
|
||
#- /path/to/nas/bambuddy-backups:/app/data/backups
|
||
#
|
||
# Tailscale integration (optional): mount the host's tailscaled socket
|
||
# so Bambuddy can request Let's Encrypt certs for virtual printers via
|
||
# your tailnet's MagicDNS name. Requires:
|
||
# 1. Tailscale installed + `tailscale up` completed on the host
|
||
# 2. `sudo tailscale set --operator=<container-user>` on the host so
|
||
# the user running the container can call `tailscale cert`
|
||
# Without this mount, the Tailscale toggle in the UI is harmless —
|
||
# Bambuddy falls back to self-signed certs.
|
||
#- /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock
|
||
#
|
||
# Using a self signed certificate for Home Assistant
|
||
# Add your certificate to certs directory and mount it to the container.
|
||
# The certificate will be added to the system trust store on container startup.
|
||
# Enable the system trust store with the USE_SYSTEM_TRUST_STORE env var to
|
||
# have Bambuddy trust the certificate.
|
||
# - /path/to/certs:/usr/local/share/ca-certificates
|
||
#
|
||
# External library folders. Mount the host paths the operator wants
|
||
# users to be able to register as external folders. The in-container
|
||
# paths chosen here MUST appear in BAMBUDDY_EXTERNAL_ROOTS below.
|
||
# Read-only (:ro) is recommended unless you want users uploading
|
||
# files back to the host share.
|
||
#- /mnt/nas/3d-prints:/external/nas:ro
|
||
#- /srv/library:/external/projects:ro
|
||
environment:
|
||
- TZ=${TZ:-Europe/Berlin}
|
||
# User/group the container drops to after the entrypoint normalises
|
||
# ownership on /app/data and /app/logs. Match your host user (run
|
||
# `id -u` / `id -g`) if you want files written by the container to
|
||
# show up as your user on the host. Defaults to 1000:1000.
|
||
- PUID=${PUID:-1000}
|
||
- PGID=${PGID:-1000}
|
||
# Port BamBuddy runs on (default: 8000)
|
||
# Usage: PORT=8080 docker compose up -d
|
||
- PORT=${PORT:-8000}
|
||
# Virtual printer: Set to the Docker host's IP when using bridge mode (ports:).
|
||
# Required for FTP passive mode to work behind NAT.
|
||
# Example: VIRTUAL_PRINTER_PASV_ADDRESS=192.168.1.100
|
||
#- VIRTUAL_PRINTER_PASV_ADDRESS=
|
||
#
|
||
# External PostgreSQL (optional — uses SQLite by default)
|
||
# Example: DATABASE_URL=postgresql+asyncpg://bambuddy:password@db-host:5432/bambuddy
|
||
#- DATABASE_URL=
|
||
#
|
||
# Slicer API sidecar (optional — Settings → "Use Slicer API" toggles this on).
|
||
# Default points at the OrcaSlicer sidecar on the docker host; change if you
|
||
# run the sidecar on a different host/port. The matching docker-compose.yml
|
||
# for the sidecars lives in the orca-slicer-api fork
|
||
# (https://github.com/maziggy/orca-slicer-api).
|
||
#- SLICER_API_URL=http://localhost:3003
|
||
#
|
||
# MFA at-rest encryption key (#1219). Auto-generated to
|
||
# DATA_DIR/.mfa_encryption_key on first startup if unset. Override here
|
||
# to manage the key out-of-band (e.g. via a secret manager).
|
||
#- MFA_ENCRYPTION_KEY=
|
||
#
|
||
# External library folders (GHSA-r2qv follow-up). Empty default
|
||
# disables the "Add external folder" feature; set to one or more
|
||
# colon-separated absolute paths INSIDE THE CONTAINER to opt in.
|
||
# The paths must also be bind-mounted from the host — uncomment
|
||
# the matching volume snippet below.
|
||
# Example for a single NAS mount:
|
||
#- BAMBUDDY_EXTERNAL_ROOTS=/external/nas
|
||
# Example for two roots:
|
||
#- BAMBUDDY_EXTERNAL_ROOTS=/external/nas:/external/projects
|
||
#
|
||
# Enable System Trust Store for certificate validation (e.g. for local Home Assistant)
|
||
# You also need to mount your certificates to the container (see volumes section above).
|
||
# - USE_SYSTEM_TRUST_STORE=true
|
||
restart: unless-stopped
|
||
|
||
# Optional: External PostgreSQL database
|
||
# Uncomment to run Postgres alongside Bambuddy (or use an external Postgres host)
|
||
#postgres:
|
||
# image: postgres:16-alpine
|
||
# container_name: bambuddy-db
|
||
# restart: unless-stopped
|
||
# environment:
|
||
# POSTGRES_USER: bambuddy
|
||
# POSTGRES_PASSWORD: changeme
|
||
# POSTGRES_DB: bambuddy
|
||
# volumes:
|
||
# - bambuddy_pgdata:/var/lib/postgresql/data
|
||
# ports:
|
||
# - "5432:5432"
|
||
|
||
volumes:
|
||
bambuddy_data:
|
||
bambuddy_logs:
|
||
#bambuddy_pgdata:
|