Skip to content

Configuration

Everything is configured through environment variables, normally via the .env file you copied from .env.example. Backend settings use the VAULT_ prefix — that prefix is historical (the project started life as “Vault”) and is kept for compatibility, so don’t read anything into it.

You rarely need to touch most of these. A default install runs on SQLite and local disk with sensible defaults; the one value you must change is the JWT secret.

One non-VAULT_ variable is read by Docker Compose itself: PRINTSTASH_VERSION selects the image tag the default docker-compose.yml pulls (e.g. 0.6.2). Pin it for reproducible deploys and bump it to upgrade; if unset it defaults to the release the compose file shipped with.

VariableDefaultPurpose
VAULT_JWT_SECRETchangeme_jwt_secret_please_changeSigning secret for auth tokens. Change it.
VAULT_ACCESS_TOKEN_EXPIRE_MINUTES60Access-token lifetime, in minutes.
VAULT_CORS_ORIGINS(empty)Comma-separated browser origins allowed to call the API. Only needed if the UI is served from a different origin than the API.
VAULT_MAX_UPLOAD_MB512Maximum size per uploaded file, in MB. Docker Compose also maps this to the frontend nginx proxy body limit.
VAULT_LOG_LEVELINFOBackend log verbosity.
VariableDefaultPurpose
VAULT_STORAGE_BACKENDlocallocal disk or s3 object storage.
VAULT_DATA_DIR/data/filesWhere model/G-code blobs live (local).
VAULT_THUMB_DIR/data/thumbsGenerated thumbnails.
VAULT_STAGING_DIR/data/stagingScratch space for in-flight uploads. Always local, even on the S3 backend.
VAULT_DB_URLsqlite:////data/db/printstash.sqliteSQLite by default; point at a Postgres URL to switch.

Set VAULT_STORAGE_BACKEND=s3 and supply credentials. This works with AWS S3 and any S3-compatible service — Cloudflare R2, MinIO, Backblaze B2, and so on. Uploads above the multipart threshold are chunked, and downloads are served as short-lived presigned URLs so blobs never round-trip through the API process.

VariableDefaultPurpose
VAULT_S3_BUCKET(empty)Bucket name.
VAULT_S3_ENDPOINT_URL(empty)Custom endpoint (R2 / MinIO / B2).
VAULT_S3_REGIONautoRegion.
VAULT_S3_ACCESS_KEY(empty)Access key.
VAULT_S3_SECRET_KEY(empty)Secret key.
VAULT_S3_PRESIGNED_URL_EXPIRE_SECONDS900Lifetime of presigned download URLs.
VAULT_S3_MULTIPART_THRESHOLD_MB50Files larger than this use multipart.
VAULT_S3_LIFECYCLE_EXPIRATION_DAYS0Object expiration (0 = disabled).
VAULT_S3_LIFECYCLE_TRANSITION_DAYS0Days before a storage-class transition.
VAULT_S3_TRANSITION_STORAGE_CLASSSTANDARD_IAStorage class to transition into.

SQLite is the default and the best-tested path for a single-user home install — one file, no extra container, trivial to back up. Reach for Postgres when you’re running multiple users or want concurrent writes to behave better under load:

Terminal window
docker compose --profile postgres up -d
VAULT_DB_URL=postgresql://printstash:printstash@postgres:5432/printstash
POSTGRES_DB=printstash
POSTGRES_USER=printstash
POSTGRES_PASSWORD=printstash

Migrations run automatically on startup against whichever database you point at. There’s a one-time SQLite-to-Postgres migration script if you start on SQLite and outgrow it later.

VariableDefaultPurpose
VAULT_BACKUP_DIR/data/backupsWhere local tar.gz archives are written.
VAULT_BACKUP_RETENTION_DAYS30How long to keep backups (0 = forever).
VAULT_TRASH_RETENTION_DAYS30How long soft-deleted models stay in trash before permanent deletion.

Backups can be mirrored to object storage with the VAULT_BACKUP_S3_* variables (BUCKET, ENDPOINT_URL, REGION, ACCESS_KEY, SECRET_KEY). This is independent of your vault storage backend — a common setup is keeping vault data on local disk while shipping nightly backups off to R2. See Backup & restore.

The default Docker setup serves the frontend and proxies API/WebSocket traffic same-origin, so no frontend environment variables are needed.

VariableDefaultPurpose
VITE_API_URL(empty)Build-time API base for split-origin or local Vite development. Leave empty for Docker.
VITE_WS_URL(empty)Build-time WebSocket base for split-origin or local Vite development. Leave empty for Docker.