Running the server
brep-plm has four commands. With no command it runs serve.
brep-plm serve [OPTIONS]
brep-plm backup [--data <dir>] [--scripts <dir>] --out <file.tar.gz>
brep-plm restore --from <file.tar.gz> --data <new dir>
brep-plm export [--data <dir>] --out <file> [--format json|parts-csv|structure-csv]
brep-plm --help
An unknown command or option prints the usage text and exits 2.
serve
brep-plm serve --data ./plm-data --bind 127.0.0.1:8088
| Option | Argument | Default | Effect |
|---|---|---|---|
--data | <dir> | ./plm-data | The data directory: the database, the documents and the attachments. Created on first run. |
--bind | <addr> | 127.0.0.1:8088 | The address and port to listen on. 127.0.0.1:0 picks a free port; the line brep-plm: listening on <addr> names the one bound. |
--scripts | <dir> | <data>/scripts | The administrator's script directory (see Scripts). It can be a git checkout. |
--secure-cookies | off, on or auto | off, or on with --tls-cert | Whether the session cookie is marked Secure. auto marks it when the request arrived over TLS. |
--trust-proxy | none | off | Believe X-Forwarded-For (for the sign-in throttle) and X-Forwarded-Proto (for auto cookies and the server's own URL). Use it only behind a reverse proxy that sets them. |
--tls-cert | <pem> | none | Serve HTTPS directly with this certificate chain, and send HSTS. Needs --tls-key. |
--tls-key | <pem> | none | The private key for --tls-cert. The two go together. |
--lock-script-editor | none | off | Keep the in-browser script editor off, whatever the Settings page says. |
--max-attachment-mb | <n> | 100 | The largest attachment or workspace file upload, in megabytes. |
--max-document-mb | <n> | 64 | The largest CAD document (or unsaved-work recovery copy) the server accepts, in megabytes. |
--min-client-version | <v> | the server's built-in floor | Refuse CAD apps older than version v (MAJOR.MINOR.PATCH). It can raise the built-in floor, never lower it. |
--backup-dir | <dir> | none | Where Back up now and scheduled backups are saved. Created if missing. |
--backup-every | <minutes> | off | Take a backup every so many minutes. Needs --backup-dir. The first one is one period after start. |
--backup-keep | <n> | 7 | How many saved backups to keep; older ones are deleted. |
--web-dir | <dir> | none | Serve the web interface's files from this directory, falling back to the built-in files for anything missing. Files are re-read on every request and not cached, for customising or developing the interface. |
--bake-worker-executable | <file> | none | A desktop brep-app the server may start as its own bake worker. |
--bake-worker-token-file | <file> | none | A file holding a worker API token for that worker. The server passes the file, never the token. |
--bake-worker-url | <url> | none | The address the worker uses to reach this server, for example http://127.0.0.1:8088. |
--cad-app | <dir> | <data>/cad-app | Where the hosted CAD app's files are (see Hosting the CAD app). |
--cad-connect-src | <origin> | none | An origin the hosted CAD app may call besides this server, such as https://api.step.parts. Repeatable. A scheme and a host, no path. |
The three --bake-worker-* options go together: give all three or none. With them,
administrators can start and stop a worker from the Bake queue page (see
Families, templates and the bake worker).
The server stops cleanly on Ctrl+C or SIGTERM, stopping its own bake worker first.
The data directory
| Path | Holds |
|---|---|
plm.sqlite | the metadata, settings, accounts and the audit log, in one SQLite file (WAL mode) |
models/<part number>/<revision>.json | each revision's CAD document, exactly as saved |
blobs/ | attachment and workspace file contents, one file per distinct content |
scripts/ | the administrator's scripts, unless --scripts names another directory |
cad-app/ | the hosted CAD app, unless --cad-app names another directory |
plm.lock | held while a server has the directory open |
bake-worker.log | the output of a worker the server started |
One server owns a data directory. A second server started on the same directory is refused and names the process holding it.
Every change is written to disk before the server answers (SQLite synchronous = FULL).
If write latency matters, give the data directory a disk that is not busy with other
work. The whole catalog is held in memory and loaded at start-up.
A file copy of a running server's directory is not a backup: the database could be
copied mid-write. Use brep-plm backup or the built-in backups.
The first run and the first administrator
On first start with an empty data directory the server creates one account, admin,
and prints its password once:
── first run ──────────────────────────────────────────
an administrator account was created:
username admin
password …
this password is shown ONCE and is not recoverable.
No build of the server ships a known password, and only a verifier of it is stored, so it cannot be recovered. Sign in at the server's address, then:
- Follow Administration → Setup wizard: part numbering, the catalog, users and groups, lifecycle status names, and optional KiCad and mechanical starter libraries. See The web workbench.
- Create a second administrator under Users and permissions.
Facing a network
Serve HTTPS directly:
brep-plm serve --data /srv/plm --bind 0.0.0.0:443 \
--tls-cert /etc/plm/fullchain.pem --tls-key /etc/plm/privkey.pem
The certificate is read at start-up; renewing it means a restart.
Or behind a reverse proxy that terminates TLS, listen on loopback and trust its headers:
brep-plm serve --data /srv/plm --bind 127.0.0.1:8088 --trust-proxy --secure-cookies auto
Administrator scripts can run programs on the server (see
Scripts). If the people who hold administrator
accounts should not have that power through the browser, start with
--lock-script-editor.
Backups, restore and export
brep-plm backup --data ./plm-data --out plm-backup.tar.gz # while serve runs, or not
brep-plm restore --from plm-backup.tar.gz --data ./plm-restored
brep-plm export --data ./plm-data --out plm.json --format json
brep-plm serve --data ./plm-data --backup-dir /backups/plm --backup-every 60 --backup-keep 48
backup
| Option | Default | Effect |
|---|---|---|
--data <dir> | ./plm-data | the data directory to back up |
--scripts <dir> | <data>/scripts | the scripts directory to include |
--out <file.tar.gz> | required | the backup to write |
A backup is one .tar.gz holding a consistent snapshot of the database, every
revision's document, every attachment and workspace file version, and the scripts
directory (without .git), with a manifest of every file's size and SHA-256. The
database is snapshotted, not copied, so a backup can run while the server keeps writing.
Run from outside the server, a backup retakes its copy when a draft is saved during it.
After three tries, a draft that keeps changing (an autosave loop) is taken as copied and
named in a note printed by both backup and restore. Backups taken by the server
itself (the Backups page, --backup-dir) never need this.
The hosted CAD app is not in a backup. Keep the CAD release you serve alongside your backups, or reinstall it.
restore
| Option | Effect |
|---|---|
--from <file.tar.gz> | the backup to restore; required |
--data <new dir> | an empty or absent directory to restore into; required |
Every file is checked against the manifest's size and hash, no path may leave the
directory, and the database must pass SQLite's integrity check. If anything is wrong,
what was written is removed again. Then serve it with --data <new dir>.
export
| Option | Default | Effect |
|---|---|---|
--data <dir> | ./plm-data | the data directory to read |
--out <file> | required | the file to write |
--format | json | json, parts-csv or structure-csv |
json: the metadata, for moving it to another system: settings, part types, categories, manufacturers, suppliers, users (no passwords), and every part with its revisions and uses lists. Documents and attachment contents are not included; each revision names its document key and content hash so they can be taken from a backup.parts-csv: one row per part: number, name, type, class, category, tags, description, latest revision and state, current release, revision count, preferred manufacturer part, and attributes.structure-csv: one row per uses-list line: the parent number, revision and state, the child number and revision, quantity, unit, find number, reference and notes.
Backups from the web page
With --backup-dir, the Backups page (administrators) offers Back up now, lists
the saved backups (named brep-plm-<UTC time>.tar.gz) and downloads them. Download a
backup works without --backup-dir: the server builds one and streams it. The page
also downloads each export format. Every backup is recorded in the audit log.
Hosting the CAD app
The server can serve the web build of the BREP CAD app from its own address, so users
open CAD in the browser at https://<server>/cad/app/web/index.html (/cad redirects
there), already signed in with their PLM session.
Put a CAD web build in the --cad-app directory, with its web/ and pkg/ directories
side by side:
<cad-app dir>/
web/index.html web/worker.js …
pkg/brep_app.js pkg/brep_app_bg.wasm …
Upgrading the CAD app is a file drop into that directory; the server needs no restart.
Without a build installed those addresses answer 404 and the rest of the PLM is
unaffected. The server prints at start-up where it looks and whether it found
web/index.html.
The hosted app runs under its own Content Security Policy. It may only call this server
unless you name other origins with --cad-connect-src. These features call other
origins:
| Feature | Origin to allow |
|---|---|
| STEP parts search | https://api.step.parts, and the hosts its results link to |
| Submit Bug | https://next.brep.io |
Opening a model from a link (?loadModel=<url>) | that link's host |
An air-gapped PLM leaves them all out; each feature then says it is unavailable on this server instead of failing.
Installing the desktop app from the server
The same directory can hold the desktop app and two install scripts, so a workstation is set up from the PLM alone:
<cad-app dir>/
native/linux-x86_64/brep-app
native/windows-x86_64/brep-app.exe
install/install.sh install/install.ps1
GET /cad/config (no sign-in needed) lists each file present with its size and SHA-256,
along with the server's version and the oldest CAD app it accepts.
Users find all of this on their My account page, under Install the desktop app:
one card per platform the directory serves (both the app and its script must be there),
with the install command already filled in with the server's address, a Copy command
button, direct downloads of the script and the app, and the app's SHA-256. A server with
no --cad-app directory says it offers no desktop app.
On a workstation:
curl -fsSL https://plm.example.com/cad/app/install/install.sh | sh -s -- https://plm.example.com
& ([scriptblock]::Create((Invoke-WebRequest -UseBasicParsing https://plm.example.com/cad/app/install/install.ps1).Content)) -Url https://plm.example.com
Each script installs for the current user without prompting, refuses a download whose
hash does not match or an app older than the server accepts, registers the file
associations, and configures the app with brep-app --plm-configure. Given a token file
(--token-file FILE / -TokenFile FILE) it also checks the connection with
brep-app --plm-check; otherwise the user signs in on first launch.
install.sh | install.ps1 | Effect |
|---|---|---|
--prefix DIR | -Prefix DIR | install somewhere other than ~/.local/bin / %LOCALAPPDATA%\Programs\BREP |
--token-file FILE | -TokenFile FILE | configure this API token too |
--no-associations | -NoAssociations | do not register .nbrep, .fbrep and .tbrep |
-NoShortcut | no Start-menu shortcut | |
--uninstall [--forget] | -Uninstall [-Forget] | remove the app; --forget also removes its PLM configuration |