Docker update monitoring self-hosted is one of the first gaps you hit once your homelab grows past five containers. A new image can sit in the registry for days while you stay completely unaware — until something breaks or a CVE advisory lands in your inbox. Stashboard solves this by continuously comparing the SHA-256 digest of each running container against the latest registry manifest and sending you a single, actionable notification the moment something changes. This guide covers everything you need: how the digest comparison engine works under the hood, how to wire up the Docker socket safely, how to configure your first watch in the UI, which check schedule to pick, what the notification throttle actually does, and the real security risks of the socket mount.
How Stashboard Docker Update Monitoring Self-Hosted Works: Digest Comparison Engine
Every Docker image is identified by a content-addressable SHA-256 digest — a hash of the manifest. Two images tagged myapp:latest can have completely different digests if their layers differ. This is the core mechanism behind docker update monitoring self-hosted: Stashboard exploits this property to detect updates without relying on tags at all, which means it also catches silent upstream rebuilds that tag-only tools miss entirely.
The check runs in three sequential phases against the Docker API:
- Container inspect — Stashboard calls
ContainerInspectby container name to read the image ID currently running on your host. - Image inspect — Using that image ID it calls
ImageInspectto fetch theRepoDigestsarray: the registry-qualified digests the image was pulled with, in the formregistry/repo@sha256:abc123…. - Registry manifest fetch — Stashboard contacts the registry directly, fetches the manifest for the configured tag, and extracts the digest from the response. The comparison is a case-insensitive string equality check. Digests match → Up to date. Digests differ → Update available.
For GitHub Container Registry images, Stashboard goes one step further: if the new digest corresponds to a published GitHub Release, it fetches the release body and URL so the notification email includes a direct changelog link.
If you need a refresher on how Docker images and digests are structured before going further, the Docker for beginners post covers the fundamentals.
Connecting Stashboard Docker Update Monitoring Self-Hosted to the Docker Daemon
Before any watch can run, Stashboard needs access to a Docker daemon. There are three methods.
Local Socket — :ro vs Writable
The most common setup is a socket bind-mount in docker-compose.yml:
volumes: - /var/run/docker.sock:/var/run/docker.sock:ro # digest tracking only # - /var/run/docker.sock:/var/run/docker.sock # adds "Update now" button
With :ro, Stashboard can inspect containers, compare digests, read logs, and send notifications — everything needed for passive monitoring. Removing :ro gives the writable socket and enables the Update now button, which pulls the new image and recreates the container in one click using the Docker API’s StopContainer → RemoveContainer → CreateContainer → StartContainer sequence. Use the writable mount only if you actually need that feature — see the security section below for why this distinction matters.
Remote TCP+TLS and SSH Tunnel
For remote hosts, Stashboard supports TCP with mutual TLS (daemon on port 2376) and SSH tunnelling. The SSH option is the most secure for VPS use: Stashboard opens a fresh SSH connection per check using a key stored encrypted at rest, tunnels the Docker socket over it, and tears the connection down immediately after. No public Docker port is needed, and the SSH user only needs to be in the docker group — not root or sudo.
⚠️ Never enable the unencrypted TCP port :2375. It exposes the entire Docker daemon to anyone who can reach your host. Always use TLS (:2376) or SSH.
Setting Up Your First Watch for Docker Update Monitoring Self-Hosted
Once a Docker service is connected, open it in Stashboard and navigate to the Docker tab. Click Add watch. Three fields are required:
- Image reference — the full path including registry host, repository, and tag. Examples:
ghcr.io/owner/repo:latest,docker.io/library/nginx:stable. Stashboard parses this into host, repository, and tag automatically — the registry host determines where the manifest is fetched from. - Container name — the exact name visible in
docker ps, for examplemystack-app-1. This is how Stashboard resolves the currently running digest on the host. If the name is wrong, the first test check will tell you. - Label — a short display name for the watch card (e.g. app, db, proxy).
For private registries, expand Registry credentials. Stashboard supports HTTP Basic for Nexus, Harbor, and Gitea; AWS ECR via IAM temporary tokens (cached ~12 hours); and automatic Bearer token negotiation for Docker Hub and GHCR. All credentials are stored AES-256-GCM encrypted in the local SQLite database.
Before saving, always click Test connection. This runs three independent checks and reports each one separately:
- Docker host reachable (ping)
- Container found by the name you entered
- Registry manifest reachable with the given credentials
Because each check is independent, if only the registry test fails you immediately know whether it is a credential problem, a network firewall, or a rate-limit — without guessing.
Choosing the Right Check Schedule for Docker Update Monitoring Self-Hosted
For a typical Docker update monitoring self-hosted homelab, Daily is the right starting point for most containers. But Stashboard offers three schedule types, and the best choice depends on how quickly you need to know about a change and how much registry traffic you want to generate — especially relevant for Docker Hub images where unauthenticated pulls are rate-limited.
- Hourly — checks every 1, 2, 4, 6, or 12 hours. Best for security-sensitive containers such as reverse proxies or authentication services where a patch matters within hours, not days. Each check is a single manifest HEAD request to the registry — lightweight per watch but adds up fast across many services.
- Daily — fires once per day at a configured UTC time. The sweet spot for most homelab services. If Stashboard is offline at the scheduled time, the check fires on the next background loop iteration when the server comes back up.
- Weekly — fires once per week on a chosen day and UTC time. Suitable for slow-moving images — databases, media servers, NAS tools — where upstream ships a release every few months. On startup, Stashboard walks back up to seven days to detect whether a scheduled window was missed while the server was offline.
Under the hood, a background service wakes up every 300 seconds (configurable via the STASHBOARD_DockerUpdate__TickIntervalSeconds environment variable), loads all enabled watches, evaluates which are due, and runs them sequentially. “Hourly/1h” doesn’t mean the check lands exactly on the clock hour — it lands within five minutes of the scheduled time at most.
Email Notifications in Docker Update Monitoring Self-Hosted
Stashboard’s notification logic is built around a single invariant for docker update monitoring self-hosted: you should hear about a specific update exactly once, not once per check cycle. Here is how the throttle works.
When a check returns Update available, the notification service compares watch.LatestDigest to watch.LastNotifiedDigest. If they match, the email is skipped — you have already been told about this exact digest. If they differ, the email is sent, and LastNotifiedDigest is stamped with the new digest value only on successful delivery. This makes transient SMTP failures safe: the stamp never happens, so Stashboard retries on the next scheduled check until the email goes through.
If you also use Telegram notifications, that channel has its own independent throttle field (LastTelegramNotifiedDigest). An email failure does not block Telegram and vice versa — the two channels are completely decoupled, so at least one will get through even if the other is having a bad day.
The email itself includes both digests in shortened form, the image reference, the container name, and — for GHCR images paired with a GitHub Release — a direct link to the release notes so you can read the changelog before deciding whether to update.
⚠️ Docker Socket Security in Docker Update Monitoring Self-Hosted
The Docker socket is the most important security consideration in any Docker update monitoring self-hosted deployment. Understanding what access you are granting is not optional.
Any process with access to /var/run/docker.sock can launch a privileged container with a host path bind-mount, giving it full read-write access to the host filesystem. In practice, socket access equals root on the host. This is true even with the :ro suffix — read-only prevents writes to the socket file, but it does not restrict what you can instruct the daemon to do via the API over that socket. Read-only means Stashboard cannot pull or recreate containers, which limits the blast radius significantly, but it does not eliminate the trust you are placing in the Stashboard process.
Practical recommendations:
- Use
:rounless you specifically need the Update now button. Passive monitoring — digest comparison, notifications, logs, stats — works fully read-only. - For remote VPS monitoring, prefer the SSH tunnel over a local socket mount. No Docker port is opened, and the private key lives AES-256-GCM encrypted on disk.
- Never expose the Stashboard web UI directly to the internet. Put it behind a reverse proxy with an authentication layer. CrowdSec with Nginx Proxy Manager is a solid option for adding an adaptive blocking layer in front of it.
- Add a watch for the Stashboard image itself. The monitoring tool needs monitoring too.
For a deeper look at reducing the attack surface of your running containers in general, the post on hardened Docker images for self-hosting is a natural companion to this setup.
Wrapping Up
Stashboard gives you a solid Docker update monitoring self-hosted pipeline without the complexity of a full Watchtower or Renovate configuration. The digest-based comparison catches rebuilds that tag-only tools miss entirely, the three schedule types cover everything from critical security patches to slow-moving databases, and the per-digest notification throttle keeps your inbox clean no matter how frequently checks run. Start with read-only socket access, validate each watch with the Test connection button before saving, and tune check frequency per container based on how quickly that service moves upstream. For a full overview of what Stashboard can monitor beyond Docker images, see the Stashboard overview post.
Stashboard is open source — you can find the full source code on GitHub and pull the ready-to-run image directly from Docker Hub. Issues, PRs, and stars are always welcome. 🙌
