3.0.0 (2026-07-06)
BookStack File Exporter v3 is a major release. It adds generic S3/object-storage upload, scheduled-daemon operation (cron, graceful shutdown, health endpoint), parallel export, and richer notifications — alongside several breaking configuration and behavior changes. Read the Breaking Changes section before upgrading.
⚠ BREAKING CHANGES
| Change | What to do |
|---|---|
minio: config block removed. Object-storage upload is now a boto3-based object_storage: list with a flat schema (name, endpoint, prefix, ambient_auth, region, …). There is no type field — a target is AWS S3 when no endpoint is set, otherwise a custom S3-compatible store. |
Convert your minio: block to an object_storage: entry. See Migrating from v2. |
http_config.verify_ssl now defaults to true (was false). The exporter verifies the BookStack server's TLS certificate by default. |
Self-signed / internal-CA BookStack: set http_config.verify_ssl: false, or set http_config.ca_bundle / the REQUESTS_CA_BUNDLE env var to your CA. |
The deprecated assets.modify_markdown alias is removed. modify_links has been the canonical key since v2.x (with modify_markdown accepted as a deprecated alias, and markdown+html link rewriting already supported); v3 drops the alias and now hard-rejects a leftover modify_markdown: at config load instead of silently honoring it. |
Rename modify_markdown → modify_links. |
A skipped page/asset now marks the run partial instead of silently succeeding. A failed page/node or asset fetch is still skipped and the run continues (as in v2.x), but the run is now reported PARTIAL — exit code 3, archive named *_partial.tgz, and an on_failure notification — rather than exiting 0 as a clean success. |
None required; note the new exit code 3 and *_partial.tgz marker if you script on run outcome. |
Unknown / misspelled config keys are now rejected at load. v2.x silently ignored any key it did not recognize; v3 fails the whole config with an error naming the offending key (e.g. keeplast → "Extra inputs are not permitted"). This strictness helps prevent deprecated options being used and silently failing, and typos changing expected behavior. |
Fix or remove stray/misspelled keys — the error names the offending key. Optional keys can still be omitted without issue. |
Setting a config value to an explicit null is now rejected. Writing e.g. keep_last: null — or leaving a value blank (keep_last: with nothing after it) — used to be silently treated as the default; v3 errors at load instead, so a value you meant to set can't be quietly nulled out. (Keys that hold a nested section — like assets: or http_config: — still fall back to their defaults when nulled; only individual value keys reject null.) Most configs are unaffected — this only bites if you explicitly put null/blank on a key instead of just omitting it. |
If the config fails to load pointing at a null, delete that line or give the key a real value — omitting a key entirely still falls back to its default. |
Features
Remote / object storage
- S3 and S3-compatible upload via boto3 — AWS S3, MinIO, Ceph, Cloudflare R2, Backblaze B2, Wasabi, DigitalOcean Spaces (
object_storage:list, multi-target). - Ambient/credential-chain auth (
ambient_auth), per-target TLS options (verify_ssl,ca_bundle), parallel uploads.
Scheduling & lifecycle (daemon mode)
- Cron scheduling via
run_schedule(alongside interval-basedrun_interval). - Production-grade graceful shutdown on
SIGINT/SIGTERM(drains in-flight work; second signal force-exits). - CLI exit codes for scripting (
0success,3partial, etc.). - Opt-in
/healthzhealth server for scheduled mode (liveness +last_run.status), with prompt shutdown handling.
Export control & performance
- Opt-in parallel node fetch (
export_workers). - Stream exports directly into the final gzipped archive (no intermediate
.tarstage). An in-progress archive is written as*.tgz.incompleteand swept automatically on the next run, so a crash or kill never leaves a truncated.tgzthat looks like a good backup. - Honor
export_images/export_attachmentsstandalone at book/chapter export levels. - UTC timestamps in archive filenames.
keep_lastretention is scoped perexport_leveland splits complete vs*_partial.tgzarchives into independent windows, so a partial run can never evict a complete backup.
Observability & notifications
- Richer apprise notifications: grouped failure bullets, an opt-in markdown notification body (
body_format: markdown), and success notifications that report the archive path and upload destinations. - Opt-in JSON-structured logging;
LOG_LEVELenv var support.
Fixes
- Secure image storage (issue #145): images under
local_secure/local_secure_restrictedwere silently saved as the login-page HTML. The exporter now fetches an image from its public/uploadsURL first and, if that returns a login/redirect, falls back to the authenticated image API (/api/image-gallery/{id}/data, BookStack v25.11+). Publiclocal/s3storage is unaffected; older instances skip secure images and mark the run partial.
Commits
Breaking
- group retention by export level and completeness; remove prune_on_partial (#164)
- a self-signed or internal-CA BookStack now fails with a TLS verification error on first run. Set http_config.verify_ssl: false, or point the REQUESTS_CA_BUNDLE environment variable at your CA bundle, to opt out.
- reject explicit YAML null for config fields with defaults (#155)
- boto3 object-storage client + flat S3 schema (v3.0.0) (#149)
- the 'minio:' config key is removed; use 'object_storage:'.
Features
- add CLI exit codes and graceful scheduled-mode lifecycle (#133) (a081024)
- add opt-in JSON-structured logging toggle (#135) (d8fe5f2)
- boto3 object-storage client + flat S3 schema (v3.0.0) (#149) (505e03c)
- cron schedule (run_schedule) for daemon mode (#136) (911a34f)
- group retention by export level and completeness; remove prune_on_partial (#164) (ffd8fa8)
- grouped failure bullets + opt-in markdown notification body (#151) (2e3f320)
- honor export_images/export_attachments standalone at book/chapter level (#134) (cd13e48)
- opt-in /healthz health server for scheduled mode (#137) (4b4949f)
- opt-in export_workers for parallel node fetch (#140) (881fb74)
- pre-v3 improvements — cleanup-failure PARTIAL, parallel uploads, is_aws single-sourcing (#150) (5dd9533)
- production-grade graceful shutdown for scheduled mode (#138) (6e12ae3)
- report archive path and destinations in success notification (#121) (ac6db62)
- report partial runs on content loss and hard-fail when no documents were archived (#153) (8ab0703)
- S3 upload support via object_storage list (v3.0.0) (#142) (633ded5)
- silence cancelled runs and report nothing-to-archive runs honestly (#156) (0a46a83)
- stream exports directly into the final gzipped archive (#158) (eddaf59)
- support LOG_LEVEL env var for log level (#147) (80f72f0)
- UTC timestamps, fail-fast archive errors, and per-target TLS options for object storage (#159) (040cf40)
Bug Fixes
- clearer one-shot run summary wording (#167) (89e06ea)
- fetch secure-storage images via authenticated API (issue #145) (#162) (fafc2cc)
- honor shutdown signals promptly in one-shot parallel export (#157) (2b8eae3)
- notification and config crash-class bugs (#152) (c5e9586)
- raise clear error on empty config file (#126) (11c6b00)
- reject explicit YAML null for config fields with defaults (#155) (3f34206)
- resolve apprise urls in one validated env probe (#125) (be1bf23)
- retention ordering, entrypoint exec, and apprise asset propagation (#154) (59ba365)
- v3.0.0 pre-release hardening — correctness, lifecycle, notification sanitizer, and run summary (#160) (1d127ea)
Documentation
- modernize + trim example config for v3 schema (#148) (19b79b7)
- note README tracks main, point to release tags for versioned docs (#141) (8b5623c)
- split README into docs/ topic pages + add CONTRIBUTING (#146) (7544ced)
- sync 2.4.0 feature docs for health endpoint and notifications (#139) (e270768)
- v3 pre-release doc polish + image-fetch terminology (#163) (569eb5b)
- v3 pre-release review — add operations guide, tighten v2→v3 accuracy (#166) (4ba1d7d)