How to Use Watchtower: The Beginner's Guide (First Run, the Docker-Sock Rule, Labels, and the Monitor-Only Lesson)
CodexFuse Team · 2026-11-01T01:34:22.750Z · 18 min read
Learn how to use Watchtower: deploy the automatic Docker container updater, master the docker.sock security rule, labels, schedules, monitor-only mode, and cleanup.
If you self-host a dozen Docker containers, you know the Sunday-night ritual: check each image for updates, pull the new ones, stop the old containers, and restart them one by one. Learning how to use Watchtower ends that ritual. Watchtower is a free, open-source Docker container whose only job is automatic Docker container updates: it watches the images behind your running containers, and whenever a registry pushes a new version, it pulls the image and recreates the container with the same settings — while you do something more interesting. This is the watchtower for beginners walkthrough: your first run, the docker.sock security rule everyone skips, labels for selective updates, schedules, the monitor-only lesson for production, notifications, cleanup, and the Diun comparison that settles which tool you actually want. New to containers entirely? Start with our Docker beginner guide — Watchtower only makes sense once Docker itself feels familiar.
What Does Watchtower Actually Do?
Watchtower is a Docker container image that automates the process of updating your other Docker containers. It monitors your running containers for new image versions and automatically pulls and restarts them when updates are available (containrrr.dev, the official docs, crawled 2026-11-01). Think of it as an update manager that lives inside your Docker host instead of on your to-do list. The mechanism runs the same loop every check:
- Runs as a container. Watchtower itself is just a container — you install it with one
docker runcommand, and it stays alive beside your apps. - Monitors other containers. Through the mounted Docker socket it can see every container on the same host and the image each one was started from.
- Checks the registry. It polls Docker Hub or your private registry for the images your containers use and compares the newest digest against what is running.
- Pulls new images. When a registry holds a newer version, Watchtower pulls the updated image down to the host.
- Recreates containers. It gracefully stops the old container and starts a replacement with the same options that were used when it was deployed initially — ports, volumes, environment variables, and all.
The project behind it is containrrr/watchtower on GitHub: roughly 24,600 stars, created in July 2015, with its latest release (v1.7.1) dating to November 2023 (GitHub API, fetched 2026-11-01). That age is worth knowing before you commit: Watchtower is a mature, slow-moving project whose core job is finished and stable, not a fast-moving tool with monthly releases. What you deploy today is the same shape of tool thousands of homelabs have run for years.
What You Need Before Your First Watchtower Run
Watchtower has short prerequisites, and all of them are worth checking before you deploy the updater itself. First, a working Docker installation on a Linux host — the Docker beginner guide linked above gets you there in under an hour if you have never touched Docker. Second, a server of your own: this is the classic self-hosted stack, so if you are still deciding where your containers live, read what is VPS hosting first — a small VPS is where most people run Watchtower in practice. Third, sudo (or root) access on that host, because you will mount the Docker socket, which is a privileged operation by design. Fourth, at least one running container to watch — even a throwaway nginx container works for the first test. Nothing else is needed: no agent on other machines, no cloud account, no dashboard to sign into.
Your First Watchtower Run: A Watchtower Docker Tutorial in 10 Steps
This watchtower docker tutorial takes you from zero to a working updater in ten steps. Do the whole arc once on a test container before you point Watchtower at anything you care about.
- Confirm Docker is healthy. Run
docker --versionanddocker ps. You need Docker Engine 20.10 or newer and a terminal with sudo access (dev.to, Watchtower + Diun guide, crawled 2026-11-01). - Pull the Watchtower image. Run
docker pull containrrr/watchtower. This is the official image from the containrrr organization — the only image name you should use (fossengineer, updated 2026-10-31). - Start Watchtower with the socket mounted. Run
docker run -d --name watchtower -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower. The-vflag mounts the Docker socket, which is how Watchtower talks to the Docker daemon — without it, Watchtower is blind (official quickstart). - Add a restart policy. Stop that container and rerun it with
--restart unless-stoppedappended. Your updater should survive host reboots the way your apps do. - Verify it is running.
docker psshould showwatchtowerup, anddocker logs watchtowershows its first scan. Healthy logs list the containers it is checking (dev.to). - Understand what it is doing right now. By default Watchtower polls every 300 seconds — five minutes (Docker Hub v2tec/watchtower README; fossengineer, 2026-10-31). Your first full check happens within minutes, not hours.
- Watch an update land. Deploy a test container from an image you can change (a personal image pushed to Docker Hub works), push a new tag, and watch the logs: you will see the new image pulled and the container recreated with identical settings.
- Set a sane interval immediately. Five minutes is aggressive for a home server hammering Docker Hub. Add
--interval 86400(seconds; once a day) to thedocker runcommand or setWATCHTOWER_POLL_INTERVAL=86400— then recreate the Watchtower container. The interval is the first knob every beginner should turn. - Move the config to Compose. One-off
docker runcommands are fine for learning, but a compose file is version-controllable. Our Docker Compose generator builds the YAML for you; the minimal Watchtower service is just the image plus the socket volume. - Confirm the steady state. After one interval passes, check the logs again: you should see regular check cycles and (usually) nothing to update. That quiet log is Watchtower working correctly — updates are the exception, not the noise.
docker run -d \
--name watchtower \
--restart unless-stopped \
-v /var/run/docker.sock:/var/run/docker.sock \
-e WATCHTOWER_POLL_INTERVAL=86400 \
containrrr/watchtower
The Docker-Sock Rule: Watchtower's #1 Security Lesson
Mounting /var/run/docker.sock gives Watchtower significant power over your host — only run Watchtower on systems you trust (fossengineer, 2026-10-31). Here is why that warning is the single most important paragraph in this guide: the Docker socket is the control plane of the host. Anything that can talk to it can start, stop, inspect, and delete every container on the machine, read their environment variables (which often contain passwords), and launch new privileged containers. In practical terms, mounting the socket hands a container root-equivalent power over Docker. That is exactly what an updater needs — and exactly why you never deploy Watchtower casually. The rules are simple: run it only on hosts you fully control, never on a shared or client machine, keep the host itself patched, and remember that any vulnerability in Watchtower's image inherits this power. Treat the updater with the same care you give SSH keys.
Watchtower Schedule: How Often It Checks, and How to Change It
Watchtower's default check interval is 300 seconds — five minutes — and that default surprises almost everyone the first time (Docker Hub README; fossengineer, updated 2026-10-31). Five-minute polls mean five-minute container restarts the moment an upstream maintainer pushes a broken image, and a steady trickle of registry requests all day. For a homelab, a daily or weekly check is calmer and still fresh. You have two controls, and they are mutually exclusive: use --interval (seconds) for a simple cadence, or --schedule with a six-field cron expression when you want updates at a specific hour. Six fields, not the usual five — the first field is seconds, so "0 30 4 * * *" means 04:30:00 every day (fossengineer).
| Option | Flag | Environment variable | Good for |
|---|---|---|---|
| Interval | --interval 86400 | WATCHTOWER_POLL_INTERVAL=86400 | Simple "check every N seconds" setups |
| Cron schedule | --schedule "0 30 4 * * *" | WATCHTOWER_SCHEDULE=0 30 4 * * * | Maintenance windows, e.g. 4:30 AM daily |
| Monitor only | --monitor-only | WATCHTOWER_MONITOR_ONLY=true | Production: alert, don't auto-update |
| Cleanup | --cleanup | WATCHTOWER_CLEANUP=true | Removing replaced images to save disk |
| Run once | --run-once | — | Manual update during a maintenance window |
| Label filter | --label-enable | WATCHTOWER_LABEL_ENABLE=true | Updating only labeled containers |
One caution from the field: do not combine --interval and --schedule — pick one, since either the interval or the schedule expression could be defined, but not both (Docker Hub README). And resist the temptation to set a 60-second interval "just to see it work": it will work, and it will also restart your containers the moment any upstream tag twitches.
Watchtower Labels: Update Only What You Choose
Out of the box, Watchtower updates all running containers on the host. That default is the second thing every beginner should change, because "all" includes your database, your reverse proxy, and anything whose update needs a human. Watchtower labels give you a whitelist: start Watchtower with the --label-enable flag (or WATCHTOWER_LABEL_ENABLE=true), and then only containers carrying the label com.centurylinklabs.watchtower.enable=true are eligible for automatic updates (Docker Hub README; howtogeek). Set the same label to false on a container to explicitly exclude it. Yes, the prefix still says "centurylinklabs" — a legacy of the project's original home; it is the current, correct prefix (verified against the docs and current guides this run).
services:
watchtower:
image: containrrr/watchtower
container_name: watchtower
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- WATCHTOWER_CLEANUP=true
- WATCHTOWER_POLL_INTERVAL=86400
- WATCHTOWER_LABEL_ENABLE=true
app:
image: myapp:latest
labels:
- "com.centurylinklabs.watchtower.enable=true"
database:
image: postgres:15
labels:
- "com.centurylinklabs.watchtower.enable=false"
The database line in that example is not decoration. A fossengineer author learned the hard way that an automatic database update broke their Nextcloud setup — major-version bumps in databases rename config keys, move data directories, and need migration steps that no updater can perform for you (fossengineer, 2026-10-31). The rule: auto-update stateless apps with true, pin databases and anything stateful with false, and review the excluded list whenever you add a container. Alternatively, skip the whitelist entirely and pass container names as arguments — containrrr/watchtower nginx redis watches only those two (Docker Hub README) — which is the simplest selective mode for tiny stacks.
Watchtower Monitor Only Mode and Notifications
In production environments, you might not want containers to update automatically — instead, you might prefer to be notified when updates are available and apply them manually during scheduled maintenance windows (betterstack, Watchtower guide). That is the monitor-only lesson, and it is the correct posture for anything that earns money or serves users. Enable it with the --monitor-only flag or the WATCHTOWER_MONITOR_ONLY=true environment variable: Watchtower keeps polling registries and keeps reporting, but never restarts anything. Pair it with notifications and you get the best of both worlds — awareness without surprise restarts.
Watchtower notifications come in two flavors: email and Shoutrrr-style chat URLs. For email, set WATCHTOWER_NOTIFICATIONS=email plus the SMTP variables (WATCHTOWER_NOTIFICATION_EMAIL_FROM, _TO, _SERVER, _SERVER_PORT, _SERVER_USER, _SERVER_PASSWORD); for Gmail you must use an App Password, not your regular password (betterstack; dev.to). For chat-style alerts, WATCHTOWER_NOTIFICATIONS=shoutrrr with WATCHTOWER_NOTIFICATION_URL=telegram://TOKEN@telegram?channels=CHAT_ID pushes updates to Telegram (dev.to). The resulting email looks like this: subject "Watchtower updates on hostname," then the version, the notification channel, the containers being checked, and a "Found new image" line with the digest (betterstack). Test the pipeline by pushing a trivial change to a test image and confirming the alert arrives within one interval — never assume notifications work until one has fired.
Watchtower Cleanup: The Disk Lesson
Every automatic update leaves the old image sitting on disk. By default Watchtower does not remove those replaced images, so a chatty upstream can quietly fill a small VPS disk with dangling images over a few months (betterstack). The fix is the --cleanup flag or WATCHTOWER_CLEANUP=true: after each successful update, Watchtower deletes the old image it replaced (fossengineer; dev.to). Turn this on in every long-lived deployment — the only reason it is not the default is safety conservatism, and for a beginner the disk-space surprise is worse than the theoretical risk of losing an old image you might want to roll back to. If rollback matters to you, pin image tags by version and keep cleanup on; you can always re-pull the old tag from the registry.
Watchtower Run Once: The Maintenance-Window Pattern
Sometimes you want Watchtower's brain without its daemon: a single deliberate update pass, run by you, at a time you chose. That is --run-once. Run it with --rm so the temporary container cleans itself up, optionally name the target container, and Watchtower performs one check-and-update cycle and exits (fossengineer; betterstack):
docker run --rm \
--name watchtower-once \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower --run-once
This is the maintenance-window pattern: monitor-only mode tells you updates exist all week, and on Sunday at 02:00 you run a single --run-once pass, watch the logs, and verify the apps. For many self-hosters this combination — alerting all week, one deliberate update run — is safer and calmer than any schedule, because you are awake, watching, and holding a snapshot. It also handles the "which containers" question elegantly: append a container name after the image and the run-once pass touches only that container (betterstack).
Watchtower vs Diun: Which One Should You Use?
The most common question after the first setup is not "how to use watchtower" but whether Watchtower is even the right tool. Enter Diun (Docker Image Update Notifier, crazymax/diun): a companion tool that only monitors and notifies — it never pulls, never restarts, never changes anything. It sends notifications when updates are available, and that is its entire job (dev.to, crawled 2026-11-01). The choice is a philosophy, not a feature list:
| Watchtower | Diun | |
|---|---|---|
| Job | Automatic container updates | Notifications only — you update manually |
| Use when | You want full automation; dev and non-critical stacks | You want complete control; production stacks |
| Risk profile | A bad upstream image restarts your container at 3 AM | No automatic changes; worst case is a missed alert |
| Notification channels | Email, Shoutrrr URLs (Telegram, etc.) | Wide: Telegram, Discord, webhooks, and more |
| Selective scope | Labels (enable=true/false), name arguments | Image filters, tag include/exclude patterns |
| Combine? | Yes: Diun watches everything and alerts; Watchtower auto-updates only labeled dev containers (dev.to hybrid pattern) | |
The pragmatic answer for most homelabs: run Watchtower with labels on the low-stakes apps (media servers, dashboards, bots), exclude databases and reverse proxies, and add Diun if you want a second pair of eyes on the containers Watchtower is not allowed to touch. They are not rivals — they are the automation half and the awareness half of the same maintenance story. For the container-management side of your stack (starting, stopping, inspecting — not updating), see our Portainer beginner guide: Portainer manages, Watchtower updates, and the two sit comfortably on the same host.
7 Beginner Mistakes That Break Watchtower Setups
Every one of these has bitten a real self-hoster, most of them in the first week:
| Mistake | What happens | Fix |
|---|---|---|
| Leaving the 5-minute default interval | Containers restart the moment any upstream tag twitches | Set WATCHTOWER_POLL_INTERVAL=86400 or a cron schedule first |
| Letting Watchtower update everything | Databases and proxies get major-version bumps unattended | --label-enable + enable=true only on safe apps |
| Mounting the socket on a shared host | A container with root-equivalent Docker power on a box you do not fully control | Trusted hosts only; treat the socket like an SSH key |
| No restart policy on Watchtower itself | Host reboots silently stop your updater | --restart unless-stopped on the Watchtower container |
| Skipping cleanup | Old images accumulate until the disk fills | WATCHTOWER_CLEANUP=true on every long-lived deploy |
Auto-updating :latest in production | Breaking changes arrive with zero warning | Pin version tags; use monitor-only + --run-once |
| Assuming notifications work | Monitor-only mode silently misses alerts | Push a test image change and confirm the alert fires |
Sources
- containrrr.dev/watchtower — official Watchtower documentation (quickstart command, update mechanism: pull, graceful stop, restart with the same options; crawled 2026-11-01)
- GitHub API, containrrr/watchtower (fetched 2026-11-01) — ~24,596 stars, created 2015-07-13, latest release v1.7.1 (published 2023-11-11)
- fossengineer.com/setup-watchtower-with-docker/ (updated 2026-10-31) — docker-run arc, labels, the 5-minute default interval, the Docker-socket security warning,
--run-once,--schedule+--cleanupexamples, the Nextcloud database caution - betterstack.com/community/guides/scaling-docker/watchtower-docker/ (crawled 2026-11-01) — monitor-only mode with email notifications,
WATCHTOWER_CLEANUP, cron scheduling, private-registry auth, the maintenance-window pattern - dev.to/fedya_serafiev/docker-compose-magic-how-to-automate-all-your-container-updates-with-watchtower-and-diun-1ab6 (crawled 2026-11-01) — the Watchtower-vs-Diun lesson, label enable/disable patterns, notification configuration, lifecycle hooks
- Docker Hub v2tec/watchtower README (crawled 2026-11-01) —
--intervaldefault of 300 seconds,--label-enablewithcom.centurylinklabs.watchtower.enable, container-name arguments, interval-vs-schedule exclusivity - xda-developers.com/i-automated-my-docker-container-updates-safely-with-watchtower/ (2025-11-06) — the compose deployment arc, environment labels, and the "automatic updates can break containers" caution
Frequently Asked Questions
Is Watchtower safe to use on a production server?
It depends on how you configure it. Blind auto-updates on production are risky — upstream images can ship breaking changes, and Watchtower restarts containers without asking. For production, the accepted pattern is monitor-only mode with notifications plus a deliberate --run-once pass during a maintenance window. Fully automatic updates belong on dev and homelab stacks where a surprise restart is an annoyance, not an incident.
How often does Watchtower check for updates by default?
Every 300 seconds — five minutes (Docker Hub README; fossengineer, 2026-10-31). Almost every beginner finds this too aggressive. Set WATCHTOWER_POLL_INTERVAL=86400 for a daily check, or use WATCHTOWER_SCHEDULE with a six-field cron expression (the first field is seconds) to pin checks to a quiet hour like 4:30 AM.
Can Watchtower update itself?
Yes — Watchtower watches all containers by default, including its own, so it can update itself on the next cycle. The container briefly goes down and comes back with the new image. This usually works, but if self-updates make you nervous, exclude it with the com.centurylinklabs.watchtower.enable=false label and update it manually with --run-once.
Why didn't Watchtower update my container?
Check four things in order: the Docker socket is mounted (without it Watchtower cannot see anything), the container is not excluded by a label or name filter, the registry actually holds a newer image digest — Watchtower compares digests, not tag names, so rebuilding and re-pushing the same tag still counts as an update (betterstack demonstrated a same-tag rebuild picked up within one interval), and the interval has elapsed since startup. docker logs watchtower tells you exactly what the last check decided.
Should I let Watchtower update my database?
No. Databases are the classic Watchtower casualty: major versions change config keys, data directories, and migration requirements that no updater can handle for you. Label every database com.centurylinklabs.watchtower.enable=false, update it by hand with backups taken first, and keep auto-updates for stateless apps where a recreate is harmless.