Skip to content

Latest commit

 

History

History
80 lines (77 loc) · 17.6 KB

File metadata and controls

80 lines (77 loc) · 17.6 KB

Configuration reference

See .env.dev.example in the workspace root for local development and .env.server.example for the server stack. Those files intentionally list only the vars a typical install sets; every other key has a working default and can simply be added to your workspace-root .env to override. This table is the complete, overridable reference:

Email delivery is not configured here. Point PrintStream at your own SMTP server in the app itself (Settings > Plugins > the SMTP email plugin); email-backed features (password reset, email notifications) need no environment variables.

Variable Default Description
API_PORT 4000 API HTTP port.
NODE_ENV development Runtime mode (development / production / test). The Compose stacks set production.
DATABASE_URL postgresql://postgres:postgres@db:5432/printstream?schema=public Prisma PostgreSQL URL. Devkit replaces this with the checkout's Compose database URL.
DATABASE_CONNECTION_LIMIT (Prisma default: CPUs×2+1) Prisma connection-pool size for this process. Set it to match expected concurrency against the Postgres max_connections budget; the CPU-count default can bottleneck a busy single-process multi-workspace API. Appended to DATABASE_URL as connection_limit.
DATABASE_POOL_TIMEOUT (Prisma default: 10s) Seconds a query waits for a free pooled connection before erroring (P2024). Appended to DATABASE_URL as pool_timeout.
DB_WAIT_TIMEOUT_MS 60000 Max time npm run dev:db waits for Postgres to accept connections before failing.
DB_WAIT_RETRY_MS 1000 Poll interval npm run dev:db uses while waiting for Postgres.
CLIENT_ORIGIN (unset) Comma-separated list of extra browser origins allowed CORS access. Only needed for a split topology where the web app is served from a different origin than the API; same-origin deployments (the stock single-container stack, the native app) never consult it.
BRIDGE_SERVER_URL http://api:4000 PrintStream server URL the bridge registers with. The default expects the bridge to reach the API over the same Docker network by service name; override to http://localhost:4000 when the bridge runs outside Docker. (BRIDGE_CLOUD_URL is accepted as a legacy alias.)
BRIDGE_LIBRARY_DIR ./data/bridge-library Bridge-local directory for library-owned files and dispatch replicas.
BRIDGE_NAME PrintStream Bridge Human-readable name used when the bridge registers and is connected to a workspace.
MANAGED_BRIDGE true in the Docker example and the native app; false otherwise Enables managed-bridge mode for single-host self-hosting: the bundled bridge auto-pairs into the sole workspace and the Bridges settings page is hidden. Set false to keep manual connect-code pairing (cloud, multiple bridges, or a bridge on a separate host).
MANAGED_BRIDGE_TOKEN_FILE /run/provision/managed-bridge-token Path to the managed-bridge provisioning token. In managed mode the API generates this token on first start; the bundled bridge reads it from the same path over a shared mount to authenticate its auto-pairing. Operators never set the token value, only the file location, which must resolve to the same file in both containers.
BRIDGE_STATE_FILE ./data/bridge-state.json Path where the bridge persists its connected identity and runtime token.
BRIDGE_BACKUP_DIR (unset: backups disabled; native bridge builds default to <data dir>/backups) Directory for the bridge's on-disk backups (snapshots of its identity file + library). Point it OUTSIDE the bridge's data dir: its own bind mount in Docker (./backups in the bridge-only example, ./bridge-backups in the combined server example), ideally on another disk, so wiping or recreating the app cannot take the backups with it. See docs/operations.md for the snapshot format and restore steps.
BRIDGE_BACKUP_INTERVAL_HOURS 24 Scheduled bridge-backup cadence in hours. 0 disables the schedule and keeps backups manual-only ("Back up now" in Settings → Bridges). Retention is automatic: everything kept for 7 days, then one per week for 4 weeks, then one per month for 12 months.
BRIDGE_AUTO_UPDATE false in source runs and the combined app image; true in the slim Docker bridge image and standalone builds When true, a bundle-capable slim Docker bridge or standalone executable installs an available compatible app update after registration. Set false in the bridge-only Compose .env to require a manual update. The combined app image's bridge role has no in-place update driver.
BRIDGE_DISABLE_SELF_UPDATE false Pin a bundle-capable slim Docker bridge or standalone executable to its current build, including against server-initiated installs. The bridge-only Compose example passes this setting from .env.
BRIDGE_RELEASES_DIR /data/releases in the slim Docker bridge image; a path under the data directory in standalone builds Directory for staged bridge updates. The slim Docker bridge keeps its signed app bundle and release pointers here on the persistent /data volume; standalone builds stage executable updates here. The combined app image's bridge role does not use it.
BRIDGE_UPDATE_PUBLIC_KEY official PrintStream key Optional Ed25519 public key override for verifying signed standalone binaries and slim Docker app bundles. Normal bridge installs should leave this unset. Compose .env files may use a one-line PEM with \n escapes when overriding.
API BRIDGE_RELEASES_DIR ./data/bridge-releases API-container directory containing signed bridge release JSON fragments, standalone binaries, and slim Docker app bundles served to bridges.
SECRETS_KEY (unset) Master key for encrypting sensitive stored settings at rest (including OAuth client secrets, SMTP passwords, and Bambu Cloud access tokens) via AES-256-GCM. Any non-empty string works (it is hashed to a 32-byte key). When unset, those settings are stored unencrypted and a warning is logged; set this in production. Existing plaintext values keep working and are re-encrypted on next write. Treat it as a secret; rotating it makes previously-encrypted values unreadable (re-enter them).
AUDIT_LOG_RETENTION_DAYS 365 How long durable audit-log rows are retained before scheduled maintenance prunes them. Raise for stricter compliance retention.
CSP_ENFORCE false When true, the Content-Security-Policy is enforced (Content-Security-Policy); when false it is sent report-only (Content-Security-Policy-Report-Only). Either way, browsers POST violations to the built-in /api/csp-report sink, which logs them as [csp-report] lines (visible in the in-app Logs tab). Roll out report-only first, confirm the sink stays quiet, then set true.
CSP_ANALYTICS_ORIGIN (unset) Origin of a first-party analytics tracker (e.g. a self-hosted Umami at https://analytics.example.com), added to the CSP's script-src and connect-src so the tracker script and its event beacons work under enforcement. Leave unset when no cross-origin analytics is embedded.
SELF_HOSTED (derived from the build) Forces the deployment to identify as self-hosted/OSS (true) or cloud (false), overriding the default (derived from whether the private cloud modules are present). Self-hosted registers the email/password provider (auth-password) and hides the cloud platform-admin, marketing, and support-access surfaces; cloud registers passkeys + email codes (auth-local) and OIDC SSO (auth-oauth). Leave unset in real deployments; set true to run the OSS build from the full source tree.
LICENSE_REFRESH_ORIGIN taken from the key Overrides the cloud origin named by a signed license key. Normally leave this unset: the key already knows which deployment issued it. Subscription keys refresh there automatically; Lifetime keys contact it only for an explicit refresh, update download, or use of the optional in-app support and Suggestions connection. Community keys never use that connection. License refresh sends the key and installation id, no printer counts or telemetry, and retries silently because the signed run window decides when access ends. Support and Suggestions relay through the same signed origin only while those surfaces are used. Set an override only when a proxy rewrites the issuer address; a disagreement is logged.
LIBRARY_DIR ./data/library Directory where uploaded model files (.3mf, .gcode, .stl, .step, .obj, .gltf/.glb, .amf, .fbx) are stored.
BACKUPS_DIR (unset: server backups disabled; the native build defaults to <data dir>/backups) Directory for the built-in whole-install server backups (database dump + persistent files). Must point OUTSIDE the app's own storage: the compose example bind-mounts a host ./backups directory, so recreating the app cannot take the backups with it. Unset keeps backups off rather than defaulting to a path inside the container. See docs/operations.md.
BACKUP_INTERVAL_HOURS 24 Scheduled server-backup cadence in hours. 0 disables scheduled creation. Self-hosted retention keeps scheduled backups for 7 days, then one per week for 4 weeks, then one per month for 12 months; manual backups remain until deleted. Cloud backups, including manual/pre-restore snapshots, have a 30-day maximum age; cloud retention continues even when scheduled creation is disabled.
PG_DUMP_PATH / PG_RESTORE_PATH (unset: resolved from the embedded Postgres bin dir, then PATH) Explicit paths to the Postgres client tools the backup system shells out to. Only needed when the tools are installed somewhere unusual; the Docker image ships a matching postgresql-client. The tool major must EQUAL the database server's major: a newer pg_dump's output does not restore into an older server, so a mismatched backup is refused up front.
LIBRARY_MAX_UPLOAD_BYTES 1073741824 Maximum accepted library upload size in bytes (default 1 GiB).
LIBRARY_TRANSIENT_RETENTION_DAYS 7 How long hidden transient library uploads are retained before scheduled cleanup removes them.
LIBRARY_RECYCLE_RETENTION_DAYS 30 How long recycle-bin (soft-deleted) library files stay restorable before scheduled cleanup removes them permanently.
LIBRARY_UNREFERENCED_SLICE_RETENTION_HOURS 24 How long unreferenced sliced outputs and unused unchanged-slice cache entries are kept before cleanup removes them. Cache hits refresh this window.
SLICER_SERVICE_URL (unset) Optional URL for the standalone slicer container. Set to enable server-side slicing orchestration. Accepts a comma-separated list of identical slicer instances; slices are assigned to the least-busy instance and progress follows the instance that owns the job.
SLICER_SERVICE_TOKEN (unset) Bearer token shared between the API and slicer container. Required by the shipped server Compose deployment. Treat this as a secret.
SLICER_REQUIRE_AUTH false (true in server Compose) Refuse slicer startup unless SLICER_SERVICE_TOKEN is set. Leave false only for an explicitly loopback-only standalone runtime.
SLICER_MAX_INPUT_BYTES / SLICER_MAX_INFLATED_BYTES / SLICER_MAX_ARCHIVE_ENTRIES 536870912 / 2147483648 / 4096 Independent hostile-archive limits enforced by the slicer service before invoking its native engine.
SLICER_MAX_OUTPUT_BYTES 1073741824 Maximum native output file size. The API may request a smaller per-job ceiling but cannot widen this limit.
SLICER_ENGINE_UID / SLICER_ENGINE_GID 1001 / 0 Fallback Unix identity for non-job engine probes. Hostile jobs derive private high-numbered uids and gids from their server-issued ids, so concurrent engines cannot traverse files, signal processes, or inspect process state across jobs.
SLICER_MEMORY_LIMIT / SLICER_CPU_LIMIT / SLICER_PIDS_LIMIT 8g / 4.0 / 512 Server Compose resource ceilings for the native slicer container.
SLICER_WORK_LIMIT 4g Hard tmpfs ceiling for all disposable slicer work files in the server Compose deployment. This prevents native code from filling the host disk even by spreading output across many files.
SLICER_BIND_HOST 127.0.0.1 Host interface for the published slicer port in Compose (127.0.0.1 keeps it private to the server).
SLICER_BIND_PORT 4010 Host port mapped to slicer container port 4010 in Compose.
SLICING_MAX_CONCURRENT_JOBS (one per slicer URL) Maximum slicing jobs the API runs at once across all slicer instances. Defaults to the number of configured SLICER_SERVICE_URL entries. Each invocation has its own BambuStudio home, but concurrent native engines still contend for CPU and memory; prefer adding instances instead.
SLICING_MAX_QUEUED_JOBS 25 Maximum number of queued slicing jobs waiting for a concurrency slot.
SLICING_REQUEST_TIMEOUT_MS 1800000 Timeout for API-to-slicer requests.
PUBLIC_SLICING_ENABLED cloud: true Enables anonymous slicing from /3mf-editor on the hosted cloud. The editor and its API routes are absent from self-hosted, native, and OSS deployments regardless of this value.
PUBLIC_SLICING_MAX_CONCURRENT_JOBS 1 (capped below total slicing concurrency in production) Maximum anonymous slices running at once. Production always reserves at least one total slot for workspace work, so public slicing is unavailable there when only one slicing slot exists. Development may lend its single slot to the public editor because no competing users share that process.
PUBLIC_SLICING_MAX_QUEUED_JOBS 20 Global cap covering incomplete uploads and queued anonymous slices.
PUBLIC_SLICING_MAX_QUEUED_JOBS_PER_IP / PUBLIC_SLICING_MAX_ACTIVE_JOBS_PER_IP 2 / 1 Per-address anonymous upload, queue, and execution limits. Set TRUST_PROXY correctly before relying on client addresses behind a proxy.
PUBLIC_SLICING_MAX_INPUT_BYTES / PUBLIC_SLICING_MAX_INFLATED_BYTES / PUBLIC_SLICING_MAX_OUTPUT_BYTES 268435456 / 536870912 / 536870912 Compressed input, inflated archive, and downloaded artifact limits for anonymous jobs.
PUBLIC_SLICING_MAX_RUNTIME_MS 1200000 Maximum execution time for one anonymous slice.
PUBLIC_SLICING_UPLOAD_TTL_MINUTES / PUBLIC_SLICING_JOB_TTL_MINUTES 30 / 60 Retention for abandoned uploads and completed or failed anonymous jobs.
SLICER_DEFAULT_TARGET_ID (first installed target) Override the default slicer version shown in the slice dialog. Must match an id from the built-in target manifest (/opt/printstream-slicers/targets.json).
SLICER_ENABLE_PIPE_PROGRESS true When true, append Bambu/Orca CLI --pipe progress JSON frames into slicing job output so the UI can render determinate progress updates.
SLICER_BAMBUSTUDIO_HOME_DIR under slicer work dir Base home used by non-job probes. Every slice invocation receives a fresh home inside its disposable job directory.
SLICER_BAMBUSTUDIO_DATA_DIR under slicer work dir Persistent --datadir used for slicer presets and first-run state. Subdirectories are created per target id.
SLICER_KEEP_WORK_DIR false Debugging aid: keep each slice job's work directory (the rewritten input 3MF and the materialized profiles the CLI loaded) instead of deleting it when the job ends. The work dirs are large and are never swept, so leave this off outside an investigation.
PRINT_JOB_THUMBNAIL_RETENTION_DAYS 90 How long completed-job thumbnail PNGs and persisted final-frame snapshot JPGs are retained before scheduled cleanup removes them.
PLUGINS_DIR ./data/plugins Directory for installed external plugins.
TRUST_PROXY (unset) Express trust proxy setting. Set only when a reverse proxy actually fronts the API (e.g. 1 for one nginx hop); with no proxy, trusting X-Forwarded-* lets clients spoof their address to the rate limiter.
SERVE_WEB_DIR /app/apps/web/dist (combined image) Directory of the built web SPA the API serves on its own port, alongside /api and /ws: the single-container topology. The Docker image bakes this in. Set to empty to run the API alone behind a separate web tier (the split topology).
DISCOVERY_PORT 2021 UDP port the bridge uses for SSDP printer auto-discovery.
PUBLIC_BASE_URL (unset) Absolute URL used for notification media embeds (e.g. camera snapshots).
MQTT_DEBUG_LOGS false Set to true or 1 to log raw MQTT publish/receive traffic for protocol debugging.
CAMERA_DEBUG_LOGS false Set to true or 1 to re-enable verbose RTSP camera readiness logs such as snapshot ready and first frame.
METRICS_ENABLED false When true, expose a Prometheus /metrics endpoint (OpenTelemetry) on METRICS_PORT for an internal scraper. Off by default: the app runs no telemetry stack unless you opt in. See docs/observability.md.
METRICS_PORT 9464 Port the Prometheus metrics endpoint binds when METRICS_ENABLED is set. Internal only: keep it on a private interface/network; do not proxy it publicly.
NTFY_TOPIC_URL (unset) Fallback ntfy topic for the notifications-ntfy plugin when a workspace has not configured its own. Honored only in single-box managed-bridge self-hosting (MANAGED_BRIDGE); ignored in multi-workspace mode, where one shared topic would leak every un-configured workspace's notifications to a single operator topic.
VITE_API_BASE_URL (unset) Build-time API base URL for the web app. Leave blank in dev (the Vite proxy handles /api) and for the combined Docker image (the web is served same-origin by the API). Only set it when building the web SPA to be hosted separately from the API.