diff --git a/Dockerfile b/Dockerfile
index 4b58cbc..dcf94de 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -6,8 +6,10 @@ COPY wordarr ./wordarr
COPY static ./static
RUN pip install --no-cache-dir .
+ARG WORDARR_BUILD=""
ENV WORDARR_CONFIG_DIR=/config \
- WORDARR_DOWNLOAD_DIR=/mnt/downloads
+ WORDARR_DOWNLOAD_DIR=/mnt/downloads \
+ WORDARR_BUILD=$WORDARR_BUILD
VOLUME /config
EXPOSE 8787
diff --git a/README.md b/README.md
index 2eeb10b..342c338 100644
--- a/README.md
+++ b/README.md
@@ -25,6 +25,13 @@ the same mount, otherwise moving turns into copy + delete.
| `WORDARR_EXTRA_EBOOK_EXTENSIONS` | – | extra ebook formats the scan should offer, e.g. `.kepub,.lit,.rtf` |
| `WORDARR_HARDCOVER_TOKEN` | – | Hardcover API token, the best ebook source; without it Hardcover is skipped |
| `WORDARR_GOOGLE_BOOKS_KEY` | – | optional, only needed when the keyless Google Books quota runs dry |
+| `WORDARR_BUILD` | – | shown next to the version, e.g. the git sha; also a build arg of the image |
+
+The header shows the running version and, behind it, the build stamp (the newest
+source file, or `WORDARR_BUILD` when the image was built with it) - the quickest
+way to see whether a redeploy actually arrived. `GET /api/version` returns the
+same three values. Build with the git sha via
+`WORDARR_BUILD=$(git rev-parse --short HEAD) docker compose up -d --build`.
The UI speaks German and English; the button next to the navigation switches
between them and remembers the choice. Without one, the browser language decides.
diff --git a/docker-compose.yml b/docker-compose.yml
index 4c246cf..8f9425c 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,6 +1,10 @@
services:
wordarr:
- build: .
+ build:
+ context: .
+ args:
+ # e.g. WORDARR_BUILD=$(git rev-parse --short HEAD) docker compose up -d --build
+ WORDARR_BUILD: ${WORDARR_BUILD:-}
container_name: wordarr
ports:
- "8787:8787"
diff --git a/static/app.js b/static/app.js
index 5846d1a..9499c28 100644
--- a/static/app.js
+++ b/static/app.js
@@ -1619,9 +1619,21 @@ function onLangChange() {
if (scanItems.length) renderImportTable();
}
+// ---- version ----
+// the build stamp is the quickest answer to "did the redeploy arrive?"
+async function showVersion() {
+ try {
+ const v = await api("/api/version");
+ // the version alone rarely moves, so the stamp is what tells deploys apart
+ $("#app-version").textContent = `v${v.version} · ${v.build || v.built_at}`;
+ $("#app-version").title = `${v.built_at} UTC${v.build ? " · " + v.build : ""}`;
+ } catch {}
+}
+
// ---- init ----
applyI18n();
updateLangButton();
endLibraryEdit();
loadLibraries();
refreshMissingBadge();
+showVersion();
diff --git a/static/index.html b/static/index.html
index 5e18991..7de74ab 100644
--- a/static/index.html
+++ b/static/index.html
@@ -11,7 +11,7 @@