Skip to main content

Template reload modes

When you run PDF Server as the base for your own PDF service, its templates live in a directory you control. Reload mode decides whether — and how — the server notices edits to that directory after it has started. It is set with a single flag:

--templates-reload-mode <none|always|watch> # env TEMPLATES_RELOAD_MODE

The default is none. There are three modes.

At a glance​

ModePicks up edits without restartNew/removed templates in listingsTester UI auto-refreshesPer-request overheadRun it for
none (default)✗✗✗noneProduction — templates baked into your image
always✓✓✗ (re-render to see changes)disk read per renderTemplates that change out of band (a mounted volume)
watch✓✓✓ (over SSE)none between rebuildsInteractive authoring with the tester UI

none — static snapshot (production default)​

Templates are read once at startup into an immutable store and never re-read. Changing a file on disk has no effect until you restart the server.

This is the right mode for a deployed service: your templates are baked into your image (see Build your image), so they never change under a running process, and every render serves from memory with no disk access.

always — re-read on every render​

Each render re-reads its template from disk, and template listings (the tester menu, the OpenAPI spec) re-scan the directory — so files you add, edit, or remove after startup are reflected without a restart. Nothing is pushed to the browser, so an open tester UI does not refresh on its own: re-render (or reload the page) to pick up a change.

Use always when the templates directory changes independently of the process — for example a volume you mount and update, or a filesystem where the watch mode's change notifications don't work (some network and overlay filesystems). The cost is a disk read per render; on local SSDs it is negligible, but it is not free at high throughput, which is why production uses none.

watch — live reload with the tester UI​

The server watches the template and composition directories for filesystem changes, rebuilds the whole store when it sees one, and atomically swaps the new store in. A rebuild that fails (for example a half-written file mid-save) keeps the previous store, so a bad intermediate edit never takes the service down.

On top of that, watch mounts GET /_events and pushes a change event to connected tester UIs over Server-Sent Events. The tester refreshes its template menu and re-renders the current preview automatically — edit a file, and the preview updates with no click. Between rebuilds, renders serve from the built store just like none, so there is no per-render disk cost.

A burst of file events (an editor rewriting several files) is collapsed into one rebuild by a debounce window, --templates-reload-debounce (default 250ms).

Two caveats:

  • A top-level templates or compositions directory that does not exist at startup is not watched if you create it later — restart the server once after creating it. Existing directories and any nesting beneath them are picked up live.
  • If change notifications are unreliable on your filesystem (some network/overlay mounts), use always instead.

The first build is the strict one​

Whatever the mode, the store is built once at startup and a template that cannot be loaded fails that build — the process logs the reason and exits, serving nothing. A rebuild is not strict in the same way: in watch mode a failed rebuild keeps the previous store and logs a warning, so the running service is never taken down by an edit.

The asymmetry is about when, not about the mode, and the case it catches you on is ordinary: create a template directory, and until you have written the body file in it there is no template there. The message names the file it wanted —

no template file in this directory: expected one of template.mustache,
template.handlebars, template.tmpl, template.html

— but docker run --rm -d deletes the container before anyone reads it, so it presents as a container that silently refuses to exist. Run it in the foreground (drop -d), or check the templates directory ahead of time with pdf-server validate, which answers the same question and prints it.

Choosing a mode​

  • Production: none. Templates are fixed in your image; take the fast path.
  • Authoring locally with the tester UI: watch, for hands-off live preview.
  • Templates change under a running server (mounted/synced volume) or watch can't see changes on your filesystem: always.

See also​