- dev: local developer runs with
APP_PROFILE=dev, uses localsettings/. - staging: production-like config, separate database, limited access.
- prod: managed service with systemd, config in
/etc/zm_api, assets in/usr/share/zm_api.
- Base config is
settings/base.tomlplussettings/{APP_PROFILE}.toml. - Environment variables override config values using the
APP_prefix and__separators.- Example:
APP_DB__HOST=10.0.0.5
- Example:
- Use
APP_CONFIG_DIRto point the app at/etc/zm_apiin packaged installs. - Use
APP_STATIC_DIRto point the app at/usr/share/zm_api/staticin packaged installs. - Secrets should live outside the repo. Store keys under
/var/lib/zm_api/keysand update thesecret.*_keypaths in the profile config. - Generate per-install JWT keys with
scripts/generate-jwt-keys.sh /var/lib/zm_api/keys(orJWT_KEY_DIR=/var/lib/zm_api/keys).
zm_api ships passive by default (daemon.enabled = false): it serves only the
REST API and does not create the daemon manager, bind /run/zm/zmdc.sock, or run
kill_orphan_daemons(). This makes it safe to install alongside a running stock
ZoneMinder — the package never fights the existing zmdc.pl/zmc/zmfilter
processes.
When you are ready to let zm_api supervise the ZoneMinder daemons itself:
sudo zm_api-takeover # stops+disables zoneminder.service, flips the flag, restarts zm_api
sudo zm_api-takeover --revert # hand control back to ZoneMinderEquivalent manual steps: systemctl disable --now zoneminder, set
APP_DAEMON__ENABLED=true in /etc/zm_api/zm_api.env, systemctl restart zm_api.
- Install the package (see matrix below). It creates the
zoneminderuser (if absent), provisions/var/lib/zm_api/keyswith generated JWT keys, installs the unit, and starts zm_api in passive mode. - Confirm DB connectivity — zm_api falls back to
/etc/zm/zm.confwhen the[db]placeholders are unchanged; otherwise setAPP_DB__*inzm_api.env. - Configure TLS/ACME if needed (see
docs/tls.md). - Validate health with
/swagger-uiand a smoke test against/api-docs/openapi.json. - When ready, run
sudo zm_api-takeoverto assume daemon supervision.
JWT keys are generated automatically on install by setup-instance.sh. For a
manual/source install, run scripts/generate-jwt-keys.sh /var/lib/zm_api/keys
and point secret.*_key (or APP_SECRET__*) at that directory.
- Binary:
/usr/bin/zm_api; takeover helper:/usr/bin/zm_api-takeover - Config:
/etc/zm_api/base.toml,/etc/zm_api/prod.toml,/etc/zm_api/zm_api.env - State (JWT keys):
/var/lib/zm_api/keys(generated per-install; never packaged) - Setup helper:
/usr/share/zm_api/setup-instance.sh - Systemd unit:
/lib/systemd/system/zm_api.service(Deb) or/usr/lib/systemd/system/zm_api.service(RPM/Arch)
| Family | Definition | Build / publish |
|---|---|---|
Debian/Ubuntu (.deb) |
Cargo.toml [package.metadata.deb] + packaging/debian/{postinst,prerm,postrm} |
cargo deb / ./scripts/package.sh deb |
Fedora/RHEL/Rocky/Alma (.rpm) |
packaging/rpm/zm_api.spec |
rpmbuild / COPR / ./scripts/package.sh rpm |
openSUSE (.rpm) |
same spec (has %if 0%{?suse_version} branches) |
OBS / rpmbuild |
Arch (PKGBUILD) |
packaging/arch/PKGBUILD + zm_api.install |
makepkg / AUR |
- Debian/Ubuntu:
cargo install cargo-debthen./scripts/package.sh deb. - RPM (Fedora/EL/openSUSE): build on the target family (or COPR/OBS) with
./scripts/package.sh rpm, which tarballsHEADand runsrpmbuildon the spec. - Arch:
./scripts/package.sh arch(runsmakepkg) on an Arch host. - Update
Cargo.toml/ spec / PKGBUILD version before a release.
This is the first Rust version; it keeps the v3 major from ZoneMinder's API
lineage and uses SemVer pre-releases while it stabilises:
3.0.0-alpha.N → 3.0.0-beta.N → 3.0.0-rc.N → 3.0.0
- Source of truth:
Cargo.tomlversion(currently3.0.0-alpha.1). - Cutting a release: push a matching tag, e.g.
git tag v3.0.0-alpha.1 && git push origin v3.0.0-alpha.1. TheReleaseworkflow builds every package and, for tags, publishes a GitHub Release — automatically flagged pre-release when the tag contains a hyphen. - Dry run without publishing: trigger the workflow via Actions → Release →
Run workflow (
workflow_dispatch); it builds and uploads artifacts but does not create a Release. - Per-distro pre-release ordering (so the eventual stable upgrades cleanly):
- Debian: cargo-deb maps
-alpha.1→~alpha.1automatically. - RPM (
packaging/rpm/zm_api.spec):Release: 0.1.alpha1%{?dist}(set back to1%{?dist}for stable). - Arch (
packaging/arch/PKGBUILD):pkgver=3.0.0~alpha1, git tag in_pkgtag.
- Debian: cargo-deb maps
- Bumping the version touches four spots, kept in sync by hand:
Cargo.toml, the specVersion/Release+ changelog, and the PKGBUILDpkgver/_pkgtag.
cargo fmt --all -- --checkcargo clippy --all-targets --all-features -- -D warningscargo test --all-features- Integration tests:
APP_PROFILE=test-db cargo test --test '*' -- --include-ignored - Build packages in CI or a clean builder container
- Only edit
prod.tomlor override via environment variables. - Keep
base.tomlin the package as a stable defaults layer.