apps.header.allAppsCount
ShipLog
apps.detail.types.plugin from Junker der Provinz
apps.detail.sections.overview
Readme
View on GitHub
⚓ ShipLog reads the changelog before you update — right inside Unraid's native Docker tab. Next to each container it shows what actually changes between your running image and the newest: the release notes, a deterministic risk badge (patch / minor / major) and the real version jump (e.g. 1.7 → 1.8).
Read-only — it never pulls, recreates or stops anything. Optional: AI changelog summaries via a local Ollama, and Matrix notifications.
Table of Contents
- What is this?
- Screenshots
- Features
- Install on Unraid
- Configuration
- How it works
- Security
- License
- Support this project
1. What is this?
A single static Go binary on a distroless image (~tens of MB, low idle RAM) that polls the read-only Docker socket, resolves which images have updates, fetches the changelog for the version span, classifies the risk, and serves it on a small status page + JSON API. The headline experience — a changelog bubble next to each container in Unraid's Docker tab — ships as a companion Unraid plugin; this engine is the brain and works on any Docker host via its status page.
2. Screenshots
Click the Changelog chip on any container — the bubble shows the version jump, a risk badge, the release notes, an optional AI summary, and a read-only Update-now button, right in Unraid's Docker tab.
A Changelog chip sits on every container: a coloured dot when an update is waiting, grey when you're up to date.
Settings: poll interval, a live engine-status line, optional GitHub / Docker Hub tokens for more changelogs, Ollama (with autodetect) for AI summaries, and Matrix alerts.
3. Features
Feature list
- What changed, not just "update available" — changelog between your running tag and the newest, newest-first, with a link to the full release notes.
- Deterministic risk badge — digest/patch = low, minor = medium, major = high, non-semver = unknown (with a reason). Colour by default, with a colour ⇄ monochrome toggle.
- Breaking-change escalation — when a release note in the update span flags a breaking change (a required database migration, a removed extension, a dropped API), the badge is bumped to critical and raises an Unraid alert, so a rolling
:latestdigest move that would otherwise read as a harmless "low" no longer slips past. - Honest degradation — when no changelog is machine-findable, ShipLog says so and shows what it does know, never pretends.
- Fix a wrong changelog source — an image's OCI source label often points at the packaging wrapper (LinuxServer's
docker-<app>), is wrong (inherited from a base image), or is missing. Click source on any row of the status page and point it at the correct GitHub repo; the override sticks to the image and survives container recreation. Common LinuxServer apps (Radarr, Sonarr, Lidarr, Prowlarr, Readarr, Whisparr, Bazarr) resolve to their upstream project out of the box. - Read-only by construction — never writes to the Docker socket.
- Registry-friendly by construction — manifest checks are
HEADrequests, which do not count against Docker Hub's pull rate limit. Bearer tokens are cached, duplicate images share one lookup per sweep, and a rate-limiting registry is backed off host-wide instead of hammered. - Knows what has no upstream — digest-pinned containers (
image@sha256:…) and locally built images are labelled as such instead of producing bogus updates or permanent errors. - Update all in one click — a counter button next to the Basic/Advanced toggle triggers Unraid's own bulk update for every container with a pending update (ShipLog itself stays read-only).
- Update controls — optional confirmation before an update, and an optional silent update that skips Unraid's pop-up download-log window (Settings → Updates).
- Scheduled auto-update, gated by SemVer level (Unraid plugin only) — optionally let ShipLog apply updates on a schedule, but only up to a level you choose: patch, minor or major. Unknown / non-versioned tags are never auto-applied, and
:latest/ digest-only moves have their own separate toggle. Runs daily, at boot, or every N hours / days, with a dry-run mode that only reports what would update — to the ShipLog log, and to Matrix if configured. It hands the work to Unraid's own container-update path, so containers come back identical to a manual update — the engine itself still never writes to the Docker socket. - Localised — the settings page and the changelog bubble follow Unraid's configured language across 26 languages.
- Optional, off by default: AI changelog summaries via a local Ollama; enriched Matrix notifications.
- Tiny + multi-arch (amd64 + arm64), pure-Go (no cgo), boot-smoke-gated CI.
4. Install on Unraid
The Community Applications template is published in the unraid-apps feed (search ShipLog in the Apps tab once it lands). The only required mount is the Docker socket, read-only:
-v /var/run/docker.sock:/var/run/docker.sock:ro
-v /mnt/user/appdata/shiplog:/config
-p 8484:8484
Open the WebUI on port 8484.
5. Configuration
On the Unraid plugin the settings page groups these into tabs — General, Updates, Notifications, Sources — so it stays tidy as it grows. The AUTOUPDATE_* keys below are Unraid-plugin only (the generic container image stays a read-only advisor).
| Variable | Default | Notes |
|---|---|---|
PORT |
8484 |
engine API + status page |
DOCKER_SOCKET |
/var/run/docker.sock |
mounted read-only |
DATA_DIR |
/config |
SQLite database + curated-mapping override |
POLL_INTERVAL |
6h |
how often to re-check (e.g. 1h, 12h, 24h) |
IGNORE_UNMANAGED |
false |
skip third-party containers not created from an Unraid template (Docker Compose, Dockhand, plain docker run); only Unraid-managed containers are tracked |
GITHUB_TOKEN |
— | optional; raises the anonymous GitHub API limit for changelog fetching |
OLLAMA_URL / OLLAMA_MODEL |
— | optional AI summaries |
MATRIX_HOMESERVER / MATRIX_TOKEN / MATRIX_ROOM |
— | optional enriched notifications |
UNRAID_NOTIFY |
false |
(plugin only) also send update alerts through Unraid's own notification system (the notification centre + every agent you configured: email, Discord, Telegram, ...) |
CONFIRM_UPDATE |
true |
ask for confirmation before "Update now" triggers Unraid's update |
SILENT_UPDATE |
false |
run the update without Unraid's pop-up download-log window (it still runs in the background) |
AUTOUPDATE_ENABLED |
false |
(plugin only) master switch for scheduled auto-update |
AUTOUPDATE_LEVEL |
off |
highest bump to auto-apply: off / patch / minor / major |
AUTOUPDATE_DIGEST |
false |
also auto-apply :latest / digest-only moves (they carry no SemVer level) |
AUTOUPDATE_DRYRUN |
false |
report what would update (ShipLog log + Matrix if set), apply nothing |
AUTOUPDATE_SCHED_MODE |
off |
off / daily / boot / hours / days |
AUTOUPDATE_SCHED_TIME |
04:00 |
run time for daily |
AUTOUPDATE_SCHED_EVERY |
6 |
interval for hours / days |
AUTOUPDATE_EXCLUDE_WORDS |
(empty) | comma-separated words; block an otherwise-eligible update whose changelog text contains any of them, case-insensitive (e.g. breaking, migration required) — catches a release that names its own danger even at a minor/patch bump |
6. How it works
Every POLL_INTERVAL, for each container:
- Discover via the read-only Docker socket (image ref, digest, OCI labels). Digest-pinned (
image@sha256:…), image-ID-referenced and locally built containers are recognised here and honestly labelled — they have no upstream to check, so no registry call is made for them. - Resolve the newest tag + same-tag digest from the registry (Docker Hub / GHCR / generic OCI v2, anonymous). Manifest checks are
HEAD-only and don't consume Docker Hub's pull rate limit; thetags/listcall is subject only to generic throttling, which ShipLog meets with per-request retries (honouringRetry-After), a per-host request gate, bearer-token caching, one lookup per distinct image per sweep, and a host-wide backoff after a hard 429. - Changelog via a layered provider chain — first hit wins: the image's
org.opencontainers.image.sourcelabel → GitHub releases between the tags; otherwise a version-delta fallback with a compare link. - Risk is a deterministic function of the version delta, then escalated to critical if a release note in the update span flags a breaking change (required migration, removed extension, dropped API).
- Store in SQLite (status + a small per-container version history) and surface on the API + status page.
7. Security
ShipLog mounts the Docker socket read-only and never issues a write call over it — the engine itself cannot start, stop, recreate, or pull anything directly. Update actions (the one-click bulk update, and on the Unraid plugin the opt-in scheduled auto-update) are handed to Unraid's own container-update tooling, which performs the pull + recreate; ShipLog only triggers it, and only for a container it has already classified as having an eligible update. The generic container image has no update path at all and stays a pure read-only advisor. v1 has no authentication and is intended for a trusted LAN; do not expose port 8484 to the internet. It makes outbound HTTPS calls to image registries and (for changelogs) GitHub.
8. License
Copyright (C) 2026 Junker der Provinz.
ShipLog is free software under the GNU Affero General Public License v3.0 (AGPL-3.0); see LICENSE. You may run, study, share and modify it. If you distribute it, or run a modified version as a network service, you must release your source under the same AGPL-3.0 terms and keep the existing copyright and attribution notices intact.
Name and branding are not licensed. The AGPL covers the source code only. "ShipLog", its logo and its branding remain reserved: a fork or derivative must use its own distinct name and branding, and may not present itself as ShipLog. This keeps it unambiguous which project is the original.
9. Support this project
Questions, bugs, ideas? Unraid support thread → (or open a GitHub issue).
apps.marketingCta.appInstallTitle
apps.marketingCta.appInstallDescription
apps.detail.sections.categories
apps.downloadStats.title
apps.downloadStats.monthly.title
apps.detail.sections.related
apps.detail.related.exploreCategories
apps.detail.related.exploreAllapps.detail.sections.links
apps.detail.sections.details
https://raw.githubusercontent.com/junkerderprovinz/shiplog/main/plugin/shiplog.plg