Keeping Self-Hosted Apps Updated Automatically
Automate image and dependency updates with watchtower and Renovate so your self-hosted stack stays patched without breaking your careful setup.
Netbay Developer Relations
Netbay Engineering
On this page
Self-hosted apps sit forgotten until something breaks, and by then they are often running months of outdated images with known vulnerabilities. Updating a running container by hand is easy enough to delay, which is exactly why it never happens on a schedule. Automation fixes the discipline gap. Two tools cover the problem from opposite directions: watchtower updates the running container images on a schedule, and Renovate keeps your image and dependency declarations in source control current. Used together they answer "is what is running patched" and "will the next deploy be patched."
Watchtower for the Running Stack
Watchtower runs as its own container and periodically checks running containers for new versions of their images. When it finds one it can pull and restart the container, preserving its configuration. You give it strict rules so it does not update everything blindly; a layered schedule — one immediate for a critical reverse proxy, a quieter window for the rest — keeps surprises out of your workday.
services:
watchtower:
image: containrrr/watchtower:latest
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command: --schedule 0 0 3 * * * --cleanup --include-stoppedThe --schedule flag takes a cron expression; here it runs at 3 a.m. daily, and --cleanup removes old images after replacement so disk does not fill with retired layers. Mounting the Docker socket is required because watchtower must talk to the engine — a privilege worth accepting only for a tool you fully trust.
Renovate for the Manifest
Renovate scans the git repositories that contain your compose files and opens pull requests when base images, package versions, or other pinned dependencies have newer releases. Unlike watchtower, it changes nothing that is running; it proposes the change in code so a human can review it, see the changelog, and merge deliberately. That is the safety valve: renovate gives you automated awareness without automated surprise.
{
"extends": ["config:base"],
"docker-compose": {
"enabled": true
},
"packageRules": [
{
"matchDatasources": ["docker"],
"rangeStrategy": "pin"
}
]
}With docker-compose support enabled and pin strategy set, Renovate will pin floating tags to explicit versions and then bump them via pull requests, which pairs beautifully with reproducible image builds.
Combine Them Without Losing Control
The two tools are complementary, not redundant. The safest pattern is: Renovate proposes and you approve the version bump, your CI or a manual pull deploys it, and watchtower stays enabled but scoped narrowly — for example only patching patch-level changes of trusted upstream images, with a schedule that matches your monitoring hours. Everything else waits for an explicitly reviewed deploy.
services:
watchtower:
image: containrrr/watchtower:latest
command: >
--schedule "0 30 4 * * *"
--label-enable
--cleanupAdding --label-enable makes watchtower update only containers carrying a specific label, giving you fine-grained opt-in control:
services:
notes:
image: some/notes-app:latest
labels:
- com.centurylinklabs.watchtower.enable=trueWith the label in place, a container is auto-updated only when you decorate it explicitly, so the database or anything with state you care about can opt out of unsupervised restarts.
Have a Rollback, Not Just an Update
Automating updates without a rollback plan turns a bad release into a sticky situation: the new image is in, the old one is gone, and the only way back is retagging and redeploying by hand. Make downgrading boring before you need it. Keep the compose file at the previously pinned version reachable, and make sure your health checks actually catch the problem fast — a container that comes up "fine" but serves broken pages is a failed update wearing a healthy costume.
# roll back a container to the last known-good tag immediately
docker compose -f compose.yml up -d --force-recreate --no-deps app=some/app:1.8.2The one-liner forces recreation of just the app service at the pinned older tag, leaving everything else untouched. Combined with watchtower only running in your monitoring window, a bad update becomes a quick pinned restart instead of an all-morning restore. Decide now which of your services genuinely tolerate unattended updates and which deserve a human watching the dashboard — that list is your automation boundary.
Takeaway
Let watchtower keep already-running containers patched on a schedule you choose, and let Renovate keep your manifests current through reviewed pull requests. Together they replace "I will update it next weekend" with a process that actually runs. Deploy that stack on a Netbay Lucknow VPS and automate the upkeep instead of hoping to remember it — provision your host at netbayhosts.in.
Keep reading
Follow along on a real VPS
Deploy Linux in under 60 seconds
These guides are written against Ubuntu, Debian, and RHEL-family images — the same ones on NetBay.
Deploy an instance