bambuddy/docker-compose.yml
maziggy 689f5276e4 Show the compose directory in the Docker update command (#2664)
The printed command only works from the directory holding the compose
file, which is the thing the user came to the page not knowing. Adds a
copy button, a saved Compose directory setting, BAMBUDDY_COMPOSE_DIR,
and best-effort detection from a bind mount's host path.

Compose records the directory on every container it creates, but reading
that label needs the Docker socket mounted in — root-equivalent access
for a convenience string. The mountinfo guess is a prefill only: its root
field is relative to the mounted device, so a compose dir on its own
mount loses that prefix, and nothing in the container can detect it.

The field is restricted to path characters. It is the one setting whose
purpose is to be pasted into a root shell, so "/opt/bambuddy; rm -rf /"
would otherwise render as a plausible update command.
2026-08-03 15:12:02 +02:00

183 lines
9.4 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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-50029:50000-50029" # Virtual printer FTP passive data (3 VPs × 10-port slice)
#
# FTP passive-mode port slicing (#1646): non-proxy VPs (Archive / Review /
# Queue modes) get a 10-port slice each, allocated by VP id — VP 1 →
# 50000-50009, VP 2 → 50010-50019, VP 3 → 50020-50029, etc. The default
# exposure above covers 3 VPs; widen the range to cover more
# (`50000-500N9` where N = vp_count - 1). Proxy-mode VPs forward the
# real printer's full 50000-50100 range — if you use proxy mode, expose
# `50000-50100:50000-50100` instead.
#
# Why narrow this matters on bridge mode: with Docker's default
# userland-proxy (true), every exposed port spawns one docker-proxy host
# process per address family (IPv4 + IPv6). The original 1001-port range
# spawned ~2000 such processes, pinning ~3.5 GB of host RAM that doesn't
# appear in `docker stats` (host-level, not container-level). 30 ports
# → ~60 processes → ~210 MB instead.
#
# Bridge mode is the normal setup for any Linux host that runs
# Bambuddy alongside other services (NAS, multi-tenant Docker VM,
# Synology DSM, Unraid) — `network_mode: host` would conflict with
# ports those other services already bind. Bambuddy uses host mode by
# default because SSDP printer discovery needs L2 multicast, but it's
# a deliberate trade-off, not a security-blind default; setups that
# forgo discovery (add printers by IP) can stay on bridge with the
# narrowed range above.
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}
# Directory this compose file lives in, so Settings → Updates can print
# an update command you can paste from anywhere instead of one that only
# works if you are already in the right directory (#2664). Uncomment to
# have Compose fill it in from the shell you run `docker compose` in; the
# field is also editable in Settings if you would rather set it there or
# if you drive Compose with `-f` from elsewhere.
#- BAMBUDDY_COMPOSE_DIR=${PWD}
# 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
# Docker's default is 10s, after which it SIGKILLs. Bambuddy shuts down in
# well under that (uvicorn caps its wait on in-flight requests at 5s, then
# the app checkpoints the SQLite WAL, disconnects MQTT and stops the virtual
# printers), but a Pi with several virtual printers and a slow SD card can be
# nearer the limit than is comfortable. The headroom costs nothing — the
# container exits as soon as it is done, not when the timer expires.
stop_grace_period: 30s
# 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: